Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Advent of Code 2015 Day 13 Part 2

2015_day13_part2.livemd

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(&amp;["Me" | &amp;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()