Compare commits
2 Commits
cf508c9396
...
c6c501af2a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6c501af2a | ||
|
|
70cf651767 |
@@ -1,4 +1,15 @@
|
|||||||
defmodule Aoc2023.Common do
|
defmodule Aoc2023.Common do
|
||||||
def stringify(s) when is_binary(s) do s end
|
def stringify(s) when is_binary(s) do s end
|
||||||
def stringify(n) when is_integer(n) do inspect(n) end
|
def stringify(n) when is_integer(n) do inspect(n) end
|
||||||
|
def stringify(nil), do: "nil"
|
||||||
|
|
||||||
|
def map_nth(tup, n, fun) do
|
||||||
|
put_elem(tup, n, fun.(elem(tup, n)))
|
||||||
|
end
|
||||||
|
|
||||||
|
defmacro pipe(expr) do
|
||||||
|
quote do
|
||||||
|
fn (val) -> val |> unquote(expr) end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
52
lib/day2.ex
Normal file
52
lib/day2.ex
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
defmodule Aoc2023.Day2 do
|
||||||
|
use Aoc2023
|
||||||
|
|
||||||
|
def parse(input) do
|
||||||
|
input
|
||||||
|
|> String.split("\n")
|
||||||
|
|> Enum.map(pipe(
|
||||||
|
String.split(": ")
|
||||||
|
|> then(fn ["Game " <> id, rounds] ->
|
||||||
|
{String.to_integer(id),
|
||||||
|
rounds
|
||||||
|
|> String.split("; ")
|
||||||
|
|> Enum.map(pipe(
|
||||||
|
String.split(", ")
|
||||||
|
|> Enum.map(pipe(
|
||||||
|
String.split(" ")
|
||||||
|
|> then(fn [n, color] ->
|
||||||
|
{String.to_existing_atom(color), String.to_integer(n)}
|
||||||
|
end)
|
||||||
|
))
|
||||||
|
))}
|
||||||
|
end)
|
||||||
|
))
|
||||||
|
|> Enum.into(%{})
|
||||||
|
end
|
||||||
|
|
||||||
|
@part1_available [
|
||||||
|
red: 12, green: 13, blue: 14
|
||||||
|
]
|
||||||
|
def part1(input) do
|
||||||
|
input
|
||||||
|
|> Enum.filter(pipe(
|
||||||
|
elem(1)
|
||||||
|
|> Enum.all?(pipe(
|
||||||
|
Enum.all?(fn {color, num} -> Keyword.get(@part1_available, color, 0) >= num end)
|
||||||
|
))
|
||||||
|
))
|
||||||
|
|> Enum.map(pipe(elem(0)))
|
||||||
|
|> Enum.sum
|
||||||
|
end
|
||||||
|
|
||||||
|
def part2(input) do
|
||||||
|
input
|
||||||
|
|> Enum.map(pipe(
|
||||||
|
elem(1)
|
||||||
|
|> Enum.reduce(&(Keyword.merge(&1, &2, fn _, m1, m2 -> max(m1, m2) end)))
|
||||||
|
|> Enum.map(pipe(elem(1)))
|
||||||
|
|> Enum.product
|
||||||
|
))
|
||||||
|
|> Enum.sum
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -3,14 +3,18 @@ defmodule Mix.Tasks.Aoc do
|
|||||||
import Aoc2023.Common
|
import Aoc2023.Common
|
||||||
|
|
||||||
defp module(1), do: Aoc2023.Day1
|
defp module(1), do: Aoc2023.Day1
|
||||||
|
defp module(2), do: Aoc2023.Day2
|
||||||
# [MODULE INSERTION POINT]
|
# [MODULE INSERTION POINT]
|
||||||
|
|
||||||
defp base_dir(), do: System.get_env("AOC_BASE")
|
defp base_dir(), do: System.get_env("AOC_BASE")
|
||||||
|
|
||||||
defp tests(day) do
|
defp tests(day) do
|
||||||
case File.ls(tests_dir(day)) do
|
case File.ls(tests_dir(day)) do
|
||||||
{:ok, paths} -> paths |> Enum.filter(&(not String.contains?(&1, ".")))
|
{:ok, paths} ->
|
||||||
{:error, e} -> dbg(e)
|
paths |> Enum.filter(&(not String.contains?(&1, ".")))
|
||||||
|
|
||||||
|
{:error, e} ->
|
||||||
|
dbg(e)
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -59,17 +63,17 @@ defmodule Mix.Tasks.Aoc do
|
|||||||
defp run(day, ["new"]) do
|
defp run(day, ["new"]) do
|
||||||
create_file("#{base_dir()}/lib/day#{day}.ex", """
|
create_file("#{base_dir()}/lib/day#{day}.ex", """
|
||||||
defmodule Aoc2023.Day#{day} do
|
defmodule Aoc2023.Day#{day} do
|
||||||
use Aoc2023
|
use Aoc2023
|
||||||
|
|
||||||
def parse(input) do
|
def parse(input) do
|
||||||
input
|
input
|
||||||
end
|
end
|
||||||
|
|
||||||
def part1(input) do
|
def part1(_input) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def part2(input) do
|
def part2(_input) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
""")
|
""")
|
||||||
|
|
||||||
@@ -110,6 +114,8 @@ defmodule Mix.Tasks.Aoc do
|
|||||||
if stringify(p1) != p1e do
|
if stringify(p1) != p1e do
|
||||||
IO.puts("Failed at #{test}.1: expected #{p1e}, got:")
|
IO.puts("Failed at #{test}.1: expected #{p1e}, got:")
|
||||||
dbg(p1)
|
dbg(p1)
|
||||||
|
else
|
||||||
|
IO.puts("Test #{test}.1 succeeded")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
IO.puts("Test #{test}.1")
|
IO.puts("Test #{test}.1")
|
||||||
@@ -122,6 +128,8 @@ defmodule Mix.Tasks.Aoc do
|
|||||||
if stringify(p2) != p2e do
|
if stringify(p2) != p2e do
|
||||||
IO.puts("Failed at #{test}.2: expected #{p2e}, got:")
|
IO.puts("Failed at #{test}.2: expected #{p2e}, got:")
|
||||||
dbg(p2)
|
dbg(p2)
|
||||||
|
else
|
||||||
|
IO.puts("Test #{test}.2 succeeded")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
IO.puts("Test #{test}.2")
|
IO.puts("Test #{test}.2")
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
elixir,
|
elixir,
|
||||||
elixir-ls,
|
elixir-ls,
|
||||||
inotify-tools,
|
inotify-tools,
|
||||||
|
entr,
|
||||||
}:
|
}:
|
||||||
mkShell {
|
mkShell {
|
||||||
packages =
|
packages =
|
||||||
[elixir elixir-ls]
|
[elixir elixir-ls entr]
|
||||||
++ lib.lists.optional (pkgs.system == "x86_64-linux") inotify-tools
|
++ lib.lists.optional (pkgs.system == "x86_64-linux") inotify-tools
|
||||||
++ lib.lists.optionals (pkgs.system == "aarch64-darwin") (with pkgs.darwin.apple_sdk.frameworks; [
|
++ lib.lists.optionals (pkgs.system == "aarch64-darwin") (with pkgs.darwin.apple_sdk.frameworks; [
|
||||||
CoreFoundation
|
CoreFoundation
|
||||||
|
|||||||
5
tests/day2/1
Normal file
5
tests/day2/1
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
|
||||||
|
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
|
||||||
|
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
|
||||||
|
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
|
||||||
|
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green
|
||||||
1
tests/day2/1.1
Normal file
1
tests/day2/1.1
Normal file
@@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
1
tests/day2/1.2
Normal file
1
tests/day2/1.2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2286
|
||||||
Reference in New Issue
Block a user