day 15
rambunctious recitation
approach
the game is played with a dictionary from each number to the last turn it was spoken. the starting numbers seed the dictionary; after that, each turn looks up the previous number: if it was spoken before, the next number is the gap since then, otherwise it's 0. the previous number's turn is recorded only after the lookup, so the dictionary always holds the turn before the current one.
part 1 plays to turn 2020 and part 2 to turn 30,000,000 with the same function; there's no shortcut, just the same loop run for longer.
the trick
store only the last turn each number was spoken, and update it one step late.
python
def play(l, k):
d = {n:i for i, n in enumerate(l, 1)}
p = l[-1]
for i in range(len(l), k):
if p in d:
np = i - d[p]
else:
np = 0
d[p], p = i, np
return p