-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday15.py
More file actions
118 lines (105 loc) · 4.69 KB
/
Copy pathday15.py
File metadata and controls
118 lines (105 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import io
import re
# --- Day 15: Timing is Everything ---
#
# The halls open into an interior plaza containing a large kinetic
# sculpture. The sculpture is in a sealed enclosure and seems to involve
# a set of identical spherical capsules that are carried to the top and
# allowed to bounce through the maze of spinning pieces.
#
# Part of the sculpture is even interactive! When a button is pressed, a
# capsule is dropped and tries to fall through slots in a set of
# rotating discs to finally go through a little hole at the bottom and
# come out of the sculpture. If any of the slots aren't aligned with the
# capsule as it passes, the capsule bounces off the disc and soars
# away. You feel compelled to get one of those capsules.
#
# The discs pause their motion each second and come in different sizes;
# they seem to each have a fixed number of positions at which they
# stop. You decide to call the position with the slot 0, and count up
# for each position it reaches next.
#
# Furthermore, the discs are spaced out so that after you push the
# button, one second elapses before the first disc is reached, and one
# second elapses as the capsule passes from one disk to the one below
# it. So, if you push the button at time=100, then the capsule reaches
# the top disc at time=101, the second disc at time=102, the third disc
# at time=103, and so on.
#
# The button will only drop a capsule at an integer time - no fractional
# seconds allowed.
#
# For example, at time=0, suppose you see the following arrangement:
#
# Disc #1 has 5 positions; at time=0, it is at position 4.
# Disc #2 has 2 positions; at time=0, it is at position 1.
#
# If you press the button exactly at time=0, the capsule would start to
# fall; it would reach the first disc at time=1. Since the first disc
# was at position 4 at time=0, by time=1 it has ticked one position
# forward. As a five-position disc, the next position is 0, and the
# capsule falls through the slot.
#
# Then, at time=2, the capsule reaches the second disc. The second disc
# has ticked forward two positions at this point: it started at position
# 1, then continued to position 0, and finally ended up at position 1
# again. Because there's only a slot at position 0, the capsule bounces
# away.
#
# If, however, you wait until time=5 to push the button, then when the
# capsule reaches each disc, the first disc will have ticked forward 5+1
# = 6 times (to position 0), and the second disc will have ticked
# forward 5+2 = 7 times (also to position 0). In this case, the capsule
# would fall through the discs and come out of the machine.
#
# However, your situation has more than two discs; you've noted their
# positions in your puzzle input. What is the first time you can press
# the button to get a capsule?
#
pattern_disc = re.compile('Disc #([0-9]+) has ([0-9]+) positions; at time=0, it is at position ([0-9]+).')
def line2disc(line):
"""
Turn a string description of a disc into a pair description (nb position, current position)
"""
match = pattern_disc.match(line)
nb_positions = int(match.group(2))
current_position = int(match.group(3))
return (nb_positions, current_position)
def resolves(discs):
start_time = 0
i = 0
while i < len(discs):
(nb_positions, current_position) = discs[i]
# Moving forward the disc
shift = start_time + 1 + i
current_position = (current_position + shift) % nb_positions
if current_position == 0:
# Continue investigating this time
i += 1
else:
# A disc is not aligned, pass to the next time
i = 0
start_time += 1
return start_time
with io.open('inputs/day15.txt') as f:
discs = [line2disc(line.strip()) for line in f]
print('The first time you can press the button to get a capsule with {} discs: {}'.format(len(discs), resolves(discs)))
# --- Part Two ---
#
# After getting the first capsule (it contained a star! what great
# fortune!), the machine detects your success and begins to rearrange
# itself.
#
# When it's done, the discs are back in their original configuration as
# if it were time=0 again, but a new disc with 11 positions and starting
# at position 0 has appeared exactly one second below the
# previously-bottom disc.
#
# With this new disc, and counting again starting from time=0 with the
# configuration in your puzzle input, what is the first time you can
# press the button to get another capsule?
with io.open('inputs/day15.txt') as f:
discs = [line2disc(line.strip()) for line in f]
# Adding the special capsule
discs.append((11, 0))
print('The first time you can press the button to get another capsule with {} discs: {}'.format(len(discs), resolves(discs)))