Advent of Code 2024 - Day 23
Mix.install([{:kino, github: "livebook-dev/kino"}])
kino_input = Kino.Input.textarea("Please paste your input file: ")
Part 1
input = Kino.Input.read(kino_input)
input
|> String.split("\n", trim: true)
|> Enum.reduce(%{}, fn connection, connections ->
[computer1, computer2] = String.split(connection, "-")
connections
|> Map.update(computer1, [computer2], fn conns -> [computer2 | conns] end)
|> Map.update(computer2, [computer1], fn conns -> [computer1 | conns] end)
end)
|> then(fn network_map ->
network_map
|> Map.keys()
|> Enum.flat_map(fn computer1 ->
connections = Map.get(network_map, computer1, [])
for computer2 <- connections,
computer3 <- connections,
computer2 != computer3,
computer3 in Map.get(network_map, computer2, []),
do: Enum.sort([computer1, computer2, computer3])
end)
|> Enum.uniq()
|> Enum.filter(fn [a, b, c] ->
Enum.any?([a, b, c], fn name -> String.starts_with?(name, "t") end)
end)
|> Enum.count()
end)
Part 2
input = Kino.Input.read(kino_input)
input
|> String.split("\n", trim: true)
|> Enum.reduce(%{}, fn connection, connections ->
[computer1, computer2] = String.split(connection, "-")
connections
|> Map.update(computer1, MapSet.new([computer2]), &MapSet.put(&1, computer2))
|> Map.update(computer2, MapSet.new([computer1]), &MapSet.put(&1, computer1))
end)
|> then(fn network_map ->
network_map
|> Enum.map(fn {computer1, connections1} ->
connections1
|> Enum.map(fn computer2 ->
network_map
|> Map.get(computer2)
|> MapSet.intersection(connections1)
end)
|> Enum.concat()
|> Enum.frequencies()
|> Enum.sort_by(&elem(&1, 1), :desc)
|> Enum.reduce(MapSet.new([computer1]), fn {computer, _}, group ->
if MapSet.subset?(group, Map.get(network_map, computer)) do
MapSet.put(group, computer)
else
group
end
end)
end)
end)
|> Enum.max_by(&MapSet.size/1)
|> Enum.sort()
|> Enum.join(",")