Advent of Code 2024 - Day 14: Restroom Redoubt
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 |
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:
p=1,65 v=-5,-84
p=14,63 v=-85,6
p=49,81 v=71,14
p=61,77 v=85,67
p=58,37 v=42,47
...
We just want a tuple of numbers, so:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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:
1 |
tick = lambda r: [ ((x + vx) % width, (y + vy) % height, vx, vy) for x, y, vx, vy in r ] |
Then, in part1()
, we’ll iterate()
that tick()
function 100 times.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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:
1 2 3 4 5 6 7 8 9 10 11 |
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:
1 2 3 4 5 6 7 8 9 10 |
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_from
in 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.