Source: Timing is Everything
Part 1: Given a series of openings one second apart, each with
n
positions that advance one position per second, what is the first time you can start the simulation so that you pass each in position0
.
Not much to say about this one. Load the disks and then check each disk. The most interesting part is using modular arithmetic so that you don’t have to actually determine the current position–just check if it’s 0.
discs = []
for line in fileinput.input(args.files):
if not line.strip() or line.startswith('#'):
continue
m = re.match(r'Disc #(\d+) has (\d+) positions; at time=0, it is at position (\d+).', line)
index, count, current = m.groups()
discs.append((int(index), int(count), int(current)))
def solve():
for button_press in naturals():
success = True
for (index, count, current) in discs:
if (button_press + index + current) % count != 0:
success = False
break
if success:
return button_press
print('Press the button at t = {}'.format(solve()))
Part 2: Add a new opening at the end with
11
positions.
This doesn’t actually change the problem. It just makes it slower. But it still finishes well within a minute, so not much point in optimizing it.