Powered by AppSignal & Oban Pro

Day 13: Knights of the Dinner Table

day_13_knights_of_the_dinner_table.livemd

Day 13: Knights of the Dinner Table

Section

defmodule P1 do
  def parse(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.reduce(%{}, fn line, acc ->
      [person, _, action, units_str, _, _, _, _, _, _, next_to] = String.split(line)
      units = String.to_integer(units_str) * if action == "gain", do: 1, else: -1
      next_to_person = String.trim_trailing(next_to, ".")
      Map.update(acc, person, %{next_to_person => units}, &Map.put(&1, next_to_person, units))
    end)
  end

  def calc(arrangement, map) do
    arrangement
    |> Enum.concat([List.first(arrangement)])
    |> Enum.chunk_every(2, 1, :discard)
    |> Enum.map(fn [a, b] -> map[a][b] + map[b][a] end)
    |> Enum.sum()
  end

  def permutations(list), do: permutations(list, [])
  def permutations([], acc), do: [acc]

  def permutations(list, acc) do
    Enum.flat_map(0..(length(list) - 1), fn index ->
      {elem, remaining} = List.pop_at(list, index)
      permutations(remaining, [elem | acc])
    end)
  end
end

map =
  "/Users/eli/Desktop/input.txt"
  |> File.read!()
  |> P1.parse()

Map.keys(map)
|> P1.permutations()
|> Enum.map(&P1.calc(&1, map))
|> Enum.max()
664
people = Map.keys(map)
me_map = Enum.into(people, %{}, fn person -> {person, 0} end)
new_map = Map.put(map, "Me", me_map)

new_map =
  Enum.reduce(people, new_map, fn person, acc ->
    Map.update!(acc, person, fn map -> Map.put(map, "Me", 0) end)
  end)

Map.keys(new_map)
|> P1.permutations()
|> Enum.map(&P1.calc(&1, new_map))
|> Enum.max()
640