Skip to content

Instantly share code, notes, and snippets.

@bossek
Created December 25, 2020 19:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bossek/c78d095ad9eab8192c508b3ee6d3afde to your computer and use it in GitHub Desktop.
Save bossek/c78d095ad9eab8192c508b3ee6d3afde to your computer and use it in GitHub Desktop.
AoC 2020 Day 23 Part 2 (atomics)
defmodule Day23 do
def p2 do
i = "389547612"
cups = String.split(i, "", trim: true) |> Enum.map(&String.to_integer/1)
start = hd(cups)
max = 1_000_000
steps = 10_000_000
mem = :atomics.new(max, [])
Enum.each(Enum.zip(cups, tl(cups) ++ [10]), fn {i, next} -> :atomics.put(mem, i, next) end)
Enum.each(10..max, &:atomics.put(mem, &1, &1 + 1))
:atomics.put(mem, max, hd(cups))
836_763_710 = play(start, mem, steps, max)
end
def play(i, cups, steps, max) when steps > 0 do
a = :atomics.get(cups, i)
b = :atomics.get(cups, a)
c = :atomics.get(cups, b)
dest = dest(i - 1, [a, b, c], max)
dest_next = :atomics.exchange(cups, dest, a)
next = :atomics.exchange(cups, c, dest_next)
:atomics.put(cups, i, next)
play(next, cups, steps - 1, max)
end
def play(_i, cups, 0, _max) do
a = :atomics.get(cups, 1)
b = :atomics.get(cups, a)
a * b
end
def dest(0, picked, max) do
dest(max, picked, max)
end
def dest(x, picked, max) do
if x in picked, do: dest(x - 1, picked, max), else: x
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment