Day 12
This commit is contained in:
@@ -47,4 +47,14 @@ defmodule Aoc2023.Common do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def transpose(l), do: l |> Enum.zip |> Enum.map(&Tuple.to_list/1)
|
def transpose(l), do: l |> Enum.zip |> Enum.map(&Tuple.to_list/1)
|
||||||
|
|
||||||
|
def collapse(enum, v) do
|
||||||
|
enum
|
||||||
|
|> Stream.zip(enum |> Stream.drop(1) |> Stream.concat([nil]))
|
||||||
|
|> Stream.filter(fn {a, b} -> a != v || b != v end)
|
||||||
|
|> Stream.map(pipe(elem(0)))
|
||||||
|
end
|
||||||
|
|
||||||
|
def repeat(lst, 0), do: []
|
||||||
|
def repeat(lst, n), do: Enum.concat(lst, repeat(lst, n - 1))
|
||||||
end
|
end
|
||||||
|
|||||||
93
lib/day12.ex
Normal file
93
lib/day12.ex
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
defmodule Aoc2023.Day12 do
|
||||||
|
use Aoc2023
|
||||||
|
|
||||||
|
defmodule Cache do
|
||||||
|
use GenServer
|
||||||
|
|
||||||
|
def start do
|
||||||
|
{:ok, pid} = GenServer.start_link(Cache, nil)
|
||||||
|
pid
|
||||||
|
end
|
||||||
|
|
||||||
|
def memoize(cache, key, fun) do
|
||||||
|
got = GenServer.call(cache, {:get, key})
|
||||||
|
if got == nil do
|
||||||
|
val = fun.(key)
|
||||||
|
GenServer.call(cache, {:set, key, val})
|
||||||
|
val
|
||||||
|
else
|
||||||
|
got
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def init(_) do
|
||||||
|
{:ok, %{}}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_call({:get, key}, _, state) do
|
||||||
|
case state do
|
||||||
|
%{^key => value} ->
|
||||||
|
{:reply, value, state}
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
{:reply, nil, state}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_call({:set, key, value}, _, state) do
|
||||||
|
{:reply, nil, Map.put_new(state, key, value)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(input) do
|
||||||
|
input
|
||||||
|
|> lines
|
||||||
|
|> Enum.map(
|
||||||
|
pipe(
|
||||||
|
String.split()
|
||||||
|
|> then(fn [rec, blocks] ->
|
||||||
|
{rec |> String.to_charlist(),
|
||||||
|
blocks |> String.split(",") |> Enum.map(&String.to_integer/1)}
|
||||||
|
end)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp possibilities({rec, blocks}) do
|
||||||
|
loop = fn recur, arg ->
|
||||||
|
case arg do
|
||||||
|
{rec, []} -> if Enum.all?(rec, &(&1 in [??, ?.])) do 1 else 0 end
|
||||||
|
{rec, [block | blocks]} ->
|
||||||
|
# Expect rec to start with any number of ./?s up to the max allowing all remaining groups
|
||||||
|
# i.e. their lengths + an undamaged seperator
|
||||||
|
0..(length(rec) - Enum.sum(blocks) - length(blocks) - block)
|
||||||
|
|> Enum.map(fn i -> repeat('.', i) ++ repeat('#', block) ++ '.' end)
|
||||||
|
|> Enum.filter(pipe(Enum.zip_with(rec, &(&1 == &2 || &2 == ??)) |> Enum.all?))
|
||||||
|
|> Enum.map(&(recur.(recur, {Enum.drop(rec, length(&1)), blocks})))
|
||||||
|
|> Enum.sum
|
||||||
|
end
|
||||||
|
end
|
||||||
|
cache = Cache.start()
|
||||||
|
memoized = fn recur, arg -> Cache.memoize(cache, arg, fn arg -> loop.(recur, arg) end) end
|
||||||
|
memoized.(memoized, {rec, blocks})
|
||||||
|
end
|
||||||
|
|
||||||
|
def part1(input) do
|
||||||
|
input
|
||||||
|
|> Enum.map(pipe(possibilities()))
|
||||||
|
|> Enum.sum()
|
||||||
|
end
|
||||||
|
|
||||||
|
def part2(input) do
|
||||||
|
input
|
||||||
|
|> Enum.map(fn {rec, blocks} -> {
|
||||||
|
[rec] |> repeat(5) |> Enum.intersperse('?') |> Enum.flat_map(&id/1),
|
||||||
|
repeat(blocks, 5)
|
||||||
|
} end)
|
||||||
|
|> Enum.map(&possibilities/1)
|
||||||
|
|> Enum.sum()
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -13,6 +13,7 @@ defmodule Mix.Tasks.Aoc do
|
|||||||
defp module(9), do: Aoc2023.Day9
|
defp module(9), do: Aoc2023.Day9
|
||||||
defp module(10), do: Aoc2023.Day10
|
defp module(10), do: Aoc2023.Day10
|
||||||
defp module(11), do: Aoc2023.Day11
|
defp module(11), do: Aoc2023.Day11
|
||||||
|
defp module(12), do: Aoc2023.Day12
|
||||||
# [MODULE INSERTION POINT]
|
# [MODULE INSERTION POINT]
|
||||||
|
|
||||||
defp base_dir(), do: System.get_env("AOC_BASE")
|
defp base_dir(), do: System.get_env("AOC_BASE")
|
||||||
|
|||||||
6
tests/day12/1
Normal file
6
tests/day12/1
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
???.### 1,1,3
|
||||||
|
.??..??...?##. 1,1,3
|
||||||
|
?#?#?#?#?#?#?#? 1,3,1,6
|
||||||
|
????.#...#... 4,1,1
|
||||||
|
????.######..#####. 1,6,5
|
||||||
|
?###???????? 3,2,1
|
||||||
1
tests/day12/1.1
Normal file
1
tests/day12/1.1
Normal file
@@ -0,0 +1 @@
|
|||||||
|
21
|
||||||
1
tests/day12/1.2
Normal file
1
tests/day12/1.2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
525152
|
||||||
Reference in New Issue
Block a user