|
@@ -0,0 +1,30 @@
|
|
1
|
+#!/usr/bin/python3
|
|
2
|
+
|
|
3
|
+import itertools
|
|
4
|
+import re
|
|
5
|
+
|
|
6
|
+input_matcher = re.compile(r'^Disc #(.*?) has (.*?) positions; at time=0, it is at position (.*?)\.$')
|
|
7
|
+
|
|
8
|
+# Returns a generator for positions that this disc will be at when the capsule arrives. e.g. if disc 3 starts at
|
|
9
|
+# position 0 at time 0, the first returned position will be 3 (because the disc will have ticked around three times
|
|
10
|
+# before a capsule released at t=0 arrives).
|
|
11
|
+positions = lambda disc: ((disc[0] + disc[2] + i) % disc[1] for i in itertools.count())
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+def run(lines):
|
|
15
|
+ # Pull the information out from the text line, making sure we treat numbers as ints.
|
|
16
|
+ discs = map(lambda line: tuple(map(int, input_matcher.match(line).groups())), map(str.strip, lines))
|
|
17
|
+
|
|
18
|
+ # Zip together the positions of each disc. That means the first element in combos will show the positions each
|
|
19
|
+ # disc will be at when the capsule arrives if it's released at t=0; the second element will be the positions for
|
|
20
|
+ # a capsule released at t=1, etc.
|
|
21
|
+ combos = zip(*map(positions, discs))
|
|
22
|
+
|
|
23
|
+ # Find a time when all discs will be at position 0 for the arrival of the capsule.
|
|
24
|
+ times = (i for i, c in enumerate(combos) if all(p == 0 for p in c))
|
|
25
|
+ return next(times)
|
|
26
|
+
|
|
27
|
+with open('15.txt', 'r') as file:
|
|
28
|
+ lines = file.readlines()
|
|
29
|
+ print("Step 1: %s" % run(lines))
|
|
30
|
+ print("Step 2: %s" % run(lines + ['Disc #7 has 11 positions; at time=0, it is at position 0.']))
|