67 lines
1.5 KiB
Elixir
67 lines
1.5 KiB
Elixir
|
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
|