61 lines
1.3 KiB
Elixir
61 lines
1.3 KiB
Elixir
defmodule AOC.Day7 do
|
|
def parse_input(lines), do: parse_input(lines, %{})
|
|
def parse_input([], acc), do: acc
|
|
|
|
def parse_input([str | tl], acc) do
|
|
[container, str] = String.split(str, " bags contain ")
|
|
|
|
inner =
|
|
str
|
|
|> String.split(", ")
|
|
|> Enum.map(fn
|
|
"no other bags." ->
|
|
[]
|
|
|
|
bags ->
|
|
[num, adj1, adj2, _] = String.split(bags)
|
|
{String.to_integer(num), "#{adj1} #{adj2}"}
|
|
end)
|
|
|> List.flatten()
|
|
|
|
parse_input(tl, Map.put(acc, container, inner))
|
|
end
|
|
|
|
def find_golden_containers(map) do
|
|
map
|
|
|> Map.keys()
|
|
|> Enum.filter(fn
|
|
"shiny gold" -> false
|
|
bag -> find_golden_containers(map, bag)
|
|
end)
|
|
end
|
|
|
|
def find_golden_containers(_, "shiny gold"), do: true
|
|
|
|
def find_golden_containers(map, bag) do
|
|
map[bag]
|
|
|> Enum.map(fn {_, x} -> find_golden_containers(map, x) end)
|
|
|> Enum.any?()
|
|
end
|
|
|
|
def part1 do
|
|
AOC.Util.input_lines(7, 1)
|
|
|> parse_input()
|
|
|> find_golden_containers()
|
|
|> Enum.count()
|
|
end
|
|
|
|
def count_bags(map), do: count_bags(map, "shiny gold")
|
|
|
|
def count_bags(map, bag) do
|
|
map[bag]
|
|
|> Enum.map(fn {n, x} -> n * (count_bags(map, x) + 1) end)
|
|
|> Enum.sum()
|
|
end
|
|
|
|
def part2 do
|
|
AOC.Util.input_lines(7, 1)
|
|
|> parse_input()
|
|
|> count_bags()
|
|
end
|
|
end
|