Skip to content

Commit adabd5b

Browse files
committed
day12
1 parent 7ea6da5 commit adabd5b

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

12/sol.exs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
defmodule Day12 do
2+
def read_input(file_path) do
3+
case File.read(file_path) do
4+
{:ok, content} ->
5+
content
6+
|> String.split("\n", trim: true)
7+
|> Enum.map(&parse_line/1)
8+
9+
{:error, reason} ->
10+
raise "Oh no! #{reason}"
11+
end
12+
end
13+
14+
def parse_line(line) do
15+
[conditions, groups] = String.split(line, " ")
16+
conditions = String.graphemes(conditions)
17+
groups = String.split(groups, ",") |> Enum.map(&String.to_integer/1)
18+
{conditions, groups}
19+
end
20+
21+
def partA(file_path) do
22+
read_input(file_path)
23+
|> Enum.map(&solve(&1, %{}, 0, {0, 0, 0}))
24+
|> Enum.map(&elem(&1, 1))
25+
|> Enum.sum()
26+
end
27+
28+
def partB(file_path) do
29+
read_input(file_path)
30+
|> Enum.map(fn {conditions, groups} ->
31+
{conditions |> List.duplicate(5) |> Enum.intersperse("?") |> List.flatten(),
32+
groups |> List.duplicate(5) |> List.flatten()}
33+
end)
34+
|> Enum.map(&solve(&1, %{}, 0, {0, 0, 0}))
35+
|> Enum.map(&elem(&1, 1))
36+
|> Enum.sum()
37+
end
38+
39+
def solve(_, memo, _, key) when is_map_key(memo, key), do: {memo, memo[key]}
40+
41+
def solve({conditions, groups}, memo, acc, {id_conditions, id_groups, current_length})
42+
when length(conditions) == id_conditions do
43+
{memo,
44+
case {current_length, length(groups), length(groups) - 1, Enum.at(groups, id_groups)} do
45+
{0, ^id_groups, _, _} -> acc + 1
46+
{_, _, ^id_groups, ^current_length} -> acc + 1
47+
{_, _, _, _} -> acc
48+
end}
49+
end
50+
51+
def solve({conditions, groups}, memo, acc, key) do
52+
{memo, acc}
53+
|> solveH(".", conditions, groups, key)
54+
|> solveH("#", conditions, groups, key)
55+
|> (fn {memop, res} -> {Map.put(memop, key, res), res} end).()
56+
end
57+
58+
def solveH({memo, acc}, c, conditions, groups, {id_conditions, id_groups, current_length}) do
59+
cond do
60+
(Enum.at(conditions, id_conditions) == c or Enum.at(conditions, id_conditions) == "?") and
61+
c == "." and
62+
current_length == 0 ->
63+
solve({conditions, groups}, memo, 0, {id_conditions + 1, id_groups, 0})
64+
65+
(Enum.at(conditions, id_conditions) == c or Enum.at(conditions, id_conditions) == "?") and
66+
c == "." and
67+
current_length > 0 and length(groups) > id_groups and
68+
Enum.at(groups, id_groups) == current_length ->
69+
solve({conditions, groups}, memo, 0, {id_conditions + 1, id_groups + 1, 0})
70+
71+
(Enum.at(conditions, id_conditions) == c or Enum.at(conditions, id_conditions) == "?") and
72+
c == "#" ->
73+
solve({conditions, groups}, memo, 0, {id_conditions + 1, id_groups, current_length + 1})
74+
75+
true ->
76+
{memo, 0}
77+
end
78+
|> (fn {memo, res} -> {memo, res + acc} end).()
79+
end
80+
end

0 commit comments

Comments
 (0)