pairings = File.stream!("inputs/day13.txt") |> Enum.reduce(%{}, fn line, acc -> [_, from, dir, amount, to] = Regex.run( ~r/^(\w+) would (gain|lose) (\d+) happiness units by sitting next to (\w+)./, line ) {amount, ""} = Integer.parse(amount) amount = if dir == "lose" do -amount else +amount end {_, newAcc} = Map.get_and_update(acc, from, fn nil -> {nil, %{to => amount}} existing -> {existing, Map.put(existing, to, amount)} end) newAcc end) defmodule A do def permutations([lastElement]) do [[lastElement]] end def permutations(list) do Enum.flat_map(list, fn start -> rest = List.delete(list, start) Enum.map(permutations(rest), fn perm -> [start | perm] end) end) end def maxHappiness(pairings, people) do A.permutations(people) |> Enum.map(fn tableSorting -> offsetSorting = Stream.cycle(tableSorting) |> Stream.drop(1) Enum.zip(tableSorting, offsetSorting) |> Enum.map(fn {p1, p2} -> oneToTwo = Map.get(pairings, p1, %{}) |> Map.get(p2, 0) twoToOne = Map.get(pairings, p2, %{}) |> Map.get(p1, 0) oneToTwo + twoToOne end) |> Enum.sum() end) |> Enum.max() end end maxHappinessWithoutMe = A.maxHappiness(pairings, Map.keys(pairings)) IO.puts("Maximum happiness without me: #{maxHappinessWithoutMe}") maxHappinessWithMe = A.maxHappiness(pairings, ["Me" | Map.keys(pairings)]) IO.puts("Maximum happiness with me: #{maxHappinessWithMe}")