Advent of Code 2015 Day 13 Part 2
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Get Inputs
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2015", "13", System.fetch_env!("LB_SESSION"))
My answer
happiness_map =
puzzle_input
|> String.split("\n")
|> Enum.into(%{}, fn row ->
Regex.named_captures(
~r/(?[a-zA-Z]+) would (?(gain|lose)) (?[0-9]+) happiness units by sitting next to (?[a-zA-Z]+)/,
row
)
|> then(fn %{"from" => from, "to" => to, "num" => num, "sign" => sign} ->
num =
case sign do
"gain" -> String.to_integer(num)
_ -> -1 * String.to_integer(num)
end
{{from, to}, num}
end)
end)
defmodule Permutations do
def get_guests(happiness_map) do
happiness_map
|> Map.keys()
|> Enum.map(&Tuple.to_list(&1))
|> Enum.concat()
|> Enum.uniq()
end
def all([]), do: [[]]
def all(list) do
for elem <- list,
rest <- all(list--[elem]) do
[elem | rest]
end
end
end
guests = Permutations.get_guests(happiness_map)
permutations =
guests
|> Permutations.all()
|> Enum.map(&["Me" | &1])
permutations
|> Enum.map(fn permutation ->
next_permutation = tl(permutation) ++ [hd(permutation)]
Enum.zip(permutation, next_permutation)
|> Enum.map(fn {from, to} ->
Map.get(happiness_map, {from, to}, 0) + Map.get(happiness_map, {to, from}, 0)
end)
|> Enum.sum()
end)
|> Enum.max()