Skip to content

Instantly share code, notes, and snippets.

@bossek
Created December 16, 2020 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bossek/978d81ef9111629bfa3838e111e88ad8 to your computer and use it in GitHub Desktop.
Save bossek/978d81ef9111629bfa3838e111e88ad8 to your computer and use it in GitHub Desktop.
AoC 2020 Day 15 Part 2
defmodule Day15Part2 do
def go do
261_214 = solve([1, 2, 3]) |> elem(0)
end
defp solve(already_spoken) do
start = Enum.count(already_spoken) + 1
stop = 30_000_000
# Assumes last spoken was spoken for the first time.
last = {Enum.at(already_spoken, -1), start - 1}
spoken = :atomics.new(stop, [])
# Fill already spoken, n is stored with index n + 1 (atomics mem starts at 1).
Enum.each(Enum.with_index(already_spoken, 1), fn {n, turn} ->
:atomics.put(spoken, n + 1, turn)
end)
Enum.reduce(start..stop, last, fn turn, {_last, before} ->
if before == turn - 1 do
before = :atomics.exchange(spoken, 0 + 1, turn)
{0, (before == 0 && turn) || before}
else
n = turn - 1 - before
before = :atomics.exchange(spoken, n + 1, turn)
{n, (before == 0 && turn) || before}
end
end)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment