summaryrefslogtreecommitdiff
path: root/2015/day13.exs
blob: e23dc34e51da168d7885c3af54afd73987686fa6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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}")