AoC19/lib/day6/day6.ex

67 lines
1.5 KiB
Elixir
Raw Normal View History

2019-12-06 14:57:36 +00:00
defmodule Day6 do
def part1 do
File.read!("lib/day6/input.txt")
|> parse_orbits()
|> total_orbits()
end
def part2 do
# orbits = parse_orbits("COM)B\nB)C\nC)D\nD)E\nE)F\nB)G\nG)H\nD)I\nE)J\nJ)K\nK)L\nK)YOU\nI)SAN")
orbits =
File.read!("lib/day6/input.txt")
|> parse_orbits()
you_path = path_to_root(orbits, "YOU") |> Enum.reverse()
san_path = path_to_root(orbits, "SAN") |> Enum.reverse()
{rem1, rem2} = remaining_after_lowest_common_element(you_path, san_path)
length(rem1) - 1 + (length(rem2) - 1)
end
def parse_orbits(str) do
str
|> String.split("\n")
|> Enum.map(fn line -> String.split(line, ")") end)
|> Enum.reduce(%{}, fn [orbitted, object], orbits ->
Map.put(orbits, object, orbitted)
end)
end
def total_orbits(orbits) do
orbits
|> Map.keys()
|> Enum.reduce(0, fn object, acc ->
acc + orbit_count(orbits, object)
end)
end
def orbit_count(orbits, object) do
case Map.get(orbits, object) do
nil ->
0
orbitted ->
1 + orbit_count(orbits, orbitted)
end
end
def path_to_root(graph, start) do
case Map.get(graph, start) do
nil ->
[]
parent ->
[parent | path_to_root(graph, parent)]
end
end
def remaining_after_lowest_common_element([_, one | _] = list1, [_, two | _] = list2)
when one != two do
{list1, list2}
end
def remaining_after_lowest_common_element([_ | rest1], [_ | rest2]) do
remaining_after_lowest_common_element(rest1, rest2)
end
end