Advent of Code 2024-Day 14: Restroom Redoubt
from advent import parse, ints, iterate, count_from
robots = parse(14, ints)
width, height = 101, 103
tick = lambda r: [ ((x + vx) % width, (y + vy) % height, vx, vy) for x, y, vx, vy in r ]
def part1(n=100):
bots = iterate(tick, robots, 100)
ul, ur, ll, lr = 0, 0, 0, 0
xmid, ymid = width // 2, height // 2
for x, y, _, _ in bots:
if x < xmid:
if y < ymid:
ul += 1
elif y > ymid:
ll += 1
elif x > xmid:
if y < ymid:
ur += 1
elif y > ymid:
lr += 1
return ul * ur * ll * lr
def mostly_symmetric(s, xmid):
good, bad = 0, 0
for x, y in s:
if x < xmid:
if (xmid + xmid - x, y) in s:
good += 1
else:
bad += 1
return good > bad
def part2():
r = robots
for seconds in count_from(1):
r = tick(r)
s = { (x,y) for x, y, _, _ in r }
for xmid in range(30, width-30):
if mostly_symmetric(s, xmid):
return seconds
# ---------------------------------------------------------------------------------------------
assert part1() == 224969976
assert part2() == 7892
Parsing
We're given input of the form:
We just want a tuple of numbers, so:
robots = parse(14, ints)
----------------------------------------------------------------------------------------------------
day14.txt ➜ 8330 chars, 500 lines; first 3 lines:
----------------------------------------------------------------------------------------------------
p=1,65 v=-5,-84
p=14,63 v=-85,6
p=49,81 v=71,14
----------------------------------------------------------------------------------------------------
parse(14) ➜ 500 entries:
----------------------------------------------------------------------------------------------------
((1, 65, -5, -84), (14, 63, -85, 6), (49, 81, 71, 14), (61, 77, 85, 67 ... 9, 53), (31, 39, 16, 34))
----------------------------------------------------------------------------------------------------
Part 1
For part 1, we perform 100 iterations of robot movement, and then return the product of the count of robots in each of four quadrants. First, we'll create a function to perform a single iteration of robot movement:
Then, in part1(), we'll iterate() that tick() function 100 times.
def part1(n=100):
bots = iterate(tick, robots, 100)
ul, ur, ll, lr = 0, 0, 0, 0
xmid, ymid = width // 2, height // 2
for x, y, _, _ in bots:
if x < xmid:
if y < ymid:
ul += 1
elif y > ymid:
ll += 1
elif x > xmid:
if y < ymid:
ur += 1
elif y > ymid:
lr += 1
return ul * ur * ll * lr
Part 2
Part 2 gave me a lot of trouble initially, because I wrongly assumed the tree would be symmetrical about the midpoint of the grid. A second attempt was to assume there would be a picture frame (turns out to be correct), but I assumed it would be around the border of the grid. After a few false starts, I decided to look for symmetry around an (almost) arbitrary midpoint, and that solved the puzzle.
My solution is very inefficient, but after burning too much time on the puzzle, I wasn't motivated to tune the performance. I may come back to that after seeing other solutions, to see how Python compares on the same algorithm.
Here is the function to indicate whether the grid has enough symmetry:
def mostly_symmetric(s, xmid):
good, bad = 0, 0
for x, y in s:
if x < xmid:
if (xmid + xmid - x, y) in s:
good += 1
else:
bad += 1
return good > bad
What remains is to iterate robot movement, and then scan across the mid-point values to see if there is sufficient symmetry:
def part2():
r = robots
for seconds in count_from(1):
r = tick(r)
s = { (x,y) for x, y, _, _ in r }
for xmid in range(30, width-30):
if mostly_symmetric(s, xmid):
return seconds
Eventually, I was able to find the following grid. In hindsight, it may have been simpler to look for a picture frame :)
........................xx............................................................x.............x
.......................xx............................................................................
...................................x.......................x......x............x.....................
......................................................................................x..............
.....................................................................................................
..x.............................................................x....................................
...............................x.....................................................................
...x..........................................x......................................................
x.........x..........................................x.........................................x.....
.....x......................................x.........x..............................................
.....x..............................................x................................................
.x...............................x...................................................................
.....................................................................................................
...................................................................x.................................
..............x................x.....................................................................
............x............................x..................................................x........
......x.............................x.......................................x........................
.............................................................x.............x.........................
...............................................................x.....................................
............................................x........................................................
....x.....................................................x.........................x................
....................................................................................x................
...........x...................................x.....................................................
..............................................x.............x........................................
...............................................................x.....................................
................................................................................................x....
.....................x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...............................................
.......................x.............................x.....................................x.........
.......................x.............................x.....................x...........x.............
.......................x.............................x...............................................
.......................x.............................x...............................................
x......................x..............x..............x...............................................
.......................x.............xxx.............x............x..................................
.......................x............xxxxx............x...............................................
.......................x...........xxxxxxx...........x..x.........................................x..
............x..........x..........xxxxxxxxx..........x..................................x............
.......................x............xxxxx............x...........x................x...x..............
.....x.................x...........xxxxxxx...........x...............................................
....x..................x..........xxxxxxxxx..........x...............................................
...............x.......x.........xxxxxxxxxxx.........x..................x............................
.......................x........xxxxxxxxxxxxx........x...........................x.............x.....
..............x........x..........xxxxxxxxx..........x.....x............x............................
.......................x.........xxxxxxxxxxx.........x..............................x................
.......................x........xxxxxxxxxxxxx........x...............................................
....x.......x..........x.......xxxxxxxxxxxxxxx.......x...............................................
.......................x......xxxxxxxxxxxxxxxxx......x.......x.......................................
......x................x........xxxxxxxxxxxxx........x...............................................
.......................x.......xxxxxxxxxxxxxxx.......x.....x.........................................
.......................x......xxxxxxxxxxxxxxxxx......x....................................x..........
.......................x.....xxxxxxxxxxxxxxxxxxx.....x.........................................x.....
.......................x....xxxxxxxxxxxxxxxxxxxxx....x........................x...............x......
.......................x.............xxx.............x...............................................
.......................x.............xxx.............x...............................................
.......................x.............xxx.............x..........................x.......x............
.......................x.............................x.....................x......x..................
.......................x.............................x...............................................
..............x...x....x.............................x...............................................
.......................x.............................x......x....................x...................
.......................xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...............................................
.....................................................................................................
............................................................................................x........
..x....................x.............................................................................
..x....................x..............x..............................................................
.....................................................................................................
.....................................................................................................
.............................x.......................................................................
...................x.............................................................x...................
.........................................................x...........................................
..................x.....................x.......................................x....................
...............................................................................................x.....
....................................................................................x................
..........................................x..........................................................
..........x.......................x....................................................x.............
............................x................................................x.......................
............x........................................................................................
.......................................................................x..........................x..
.....................................................................................................
...................................................................................................x.
....x................................................................................................
...............................x......x...............x..............................................
.........................x...........................................................................
.............................................................................x.......................
.....................................................................................................
.....................................................................................................
.................................x.........x.........................................................
................................................................................................x....
............................x......x.................................................................
.....................................................................................................
.....................x............................................x..................................
...................x...........x.....................................................................
....................................................x................................................
...x.................................................................................................
........x...................x...............x........................................................
..............................................................................x......................
..x.......................................................................................x..........
...............x................................x.........................................x..........
.............................................x........x..............................................
.....................................................................................................
.....................................................................................................
..................................................................x..................................
......................................................................x...x..........................
........................................................................................x............
.....................................................................................................
New Python Concepts
itertools.count# renamed tocount_fromin my library
Conclusion
As I mentioned, this puzzle gave me more difficulty than it should have, but it was gratifying to solve it without help. If I felt it had more real world applicability, I'd probably be motivated to make it fast, but as it stands, I think I'll move on.