-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathday_09.ex
63 lines (54 loc) · 1.49 KB
/
day_09.ex
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
defmodule AdventOfCode.Y2018.Day09 do
@moduledoc """
--- Day 9: Marble Mania ---
Problem Link: https://adventofcode.com/2018/day/9
Difficulty: s
Tags: not-fast-enough circular-linked-list
"""
alias AdventOfCode.Algorithms.BiCircularList
@players 473
@last_marble 70_904
def run do
task_1 = Task.async(fn -> run_1() end)
task_2 = Task.async(fn -> run_2() end)
{Task.await(task_1), Task.await(task_2)}
end
def run_1 do
%BiCircularList{current: 0}
|> play(1, 1, @last_marble, %{})
|> Enum.max_by(fn {_, v} -> v end)
|> elem(1)
end
defp run_2 do
%BiCircularList{current: 0}
|> play(1, 1, @last_marble * 100, %{})
|> Enum.max_by(fn {_, v} -> v end)
|> elem(1)
end
def play(_, _, marble, marble, scores), do: scores
def play(state, player, marble, last_marble, scores) when rem(marble, 23) == 0 do
state
|> counter_clockwise(7)
|> BiCircularList.pop()
|> then(fn {score, state} ->
play(
state,
player + 1,
marble + 1,
last_marble,
Map.update(scores, rem(player, @players), score + marble, &(&1 + score + marble))
)
end)
end
def play(state, player, marble, last_marble, scores) do
state
|> BiCircularList.next()
|> BiCircularList.insert(marble)
|> play(player + 1, marble + 1, last_marble, scores)
end
defp counter_clockwise(%BiCircularList{} = bcl, n) do
Enum.reduce(1..n, bcl, fn _, acc ->
BiCircularList.previous(acc)
end)
end
end