Day 4; run watches in a seperate process to allow continuation after crashes

This commit is contained in:
bluepython508
2023-12-04 18:04:49 +00:00
parent ee17acccae
commit ce5e83baa4
6 changed files with 56 additions and 6 deletions

View File

@@ -32,4 +32,6 @@ defmodule Aoc2023.Common do
end
def id(x), do: x
def const(_, x), do: x
def lines(x), do: String.split(x, "\n")
end

39
lib/day4.ex Normal file
View File

@@ -0,0 +1,39 @@
defmodule Aoc2023.Day4 do
use Aoc2023
defp numbers(values) do
values |> String.split() |> Enum.map(&String.to_integer/1) |> MapSet.new()
end
def parse(input) do
input
|> lines
|> Enum.map(
&Regex.run(~r/Card\s+(?<id>\d+): (?<winning>(\s*\d+)+) \| (?<values>(\s*\d+)+)/, &1,
capture: ["id", "winning", "values"]
)
)
|> Enum.map(fn [id, winning, values] ->
{String.to_integer(id),
MapSet.intersection(numbers(winning), numbers(values)) |> MapSet.size()}
end)
end
def part1(input) do
for {_, count} <- input,
count > 0 do
2 ** (count - 1)
end
|> Enum.sum()
end
def part2(input) do
for {id, count} <- input,
id_ <- (id + 1)..(id + count)//1,
reduce: input |> Enum.map(elem(0) &&& const(1)) |> Enum.into(%{}) do
acc -> Map.update!(acc, id_, &(&1 + Map.get(acc, id)))
end
|> Enum.map(pipe(elem(1)))
|> Enum.sum()
end
end

View File

@@ -5,6 +5,7 @@ defmodule Mix.Tasks.Aoc do
defp module(1), do: Aoc2023.Day1
defp module(2), do: Aoc2023.Day2
defp module(3), do: Aoc2023.Day3
defp module(4), do: Aoc2023.Day4
# [MODULE INSERTION POINT]
defp base_dir(), do: System.get_env("AOC_BASE")
@@ -102,7 +103,7 @@ defmodule Mix.Tasks.Aoc do
end
defp run(day, ["test", "watch"]) do
{:ok, pid} = Mix.Tasks.Aoc.Watcher.start_link({[dirs: ["lib/", "test/day#{day}/"]], self()})
{:ok, pid} = Mix.Tasks.Aoc.Watcher.start_link({[dirs: ["lib/", "tests/day#{day}/"]], self()})
Process.monitor(pid)
loop = fn (loop) ->
IO.puts(IO.ANSI.clear() <> IO.ANSI.cursor(0, 0))
@@ -112,7 +113,9 @@ defmodule Mix.Tasks.Aoc do
:code.purge(Aoc2023.Common)
:code.load_file(module(day))
:code.load_file(Aoc2023.Common)
run(day, ["test"])
spawn fn ->
run(day, ["test"])
end
receive do
:update -> loop.(loop)
{:DOWN, _, :process, ^pid, _} -> nil
@@ -129,8 +132,6 @@ defmodule Mix.Tasks.Aoc do
|> Enum.map(&test(day, &1))
|> Enum.map(fn {test, input, p1e, p2e} ->
parsed = mod.parse(input)
p1 = mod.part1(parsed)
p2 = mod.part2(parsed)
result = fn (part, got, expected) ->
cond do
@@ -142,8 +143,8 @@ defmodule Mix.Tasks.Aoc do
end
end
result.(1, p1, p1e)
result.(2, p2, p2e)
result.(1, mod.part1(parsed), p1e)
result.(2, mod.part2(parsed), p2e)
end)
end

6
tests/day4/1 Normal file
View File

@@ -0,0 +1,6 @@
Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19
Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1
Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83
Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11

1
tests/day4/1.1 Normal file
View File

@@ -0,0 +1 @@
13

1
tests/day4/1.2 Normal file
View File

@@ -0,0 +1 @@
30