7
votes
Day 11: Space Police
Today's problem description: https://adventofcode.com/2019/day/11
Join the Tildes private leaderboard! You can do that on this page, by entering join code 730956-de85ce0c
.
Please post your solutions in your own top-level comment. Here's a template you can copy-paste into your comment to format it nicely, with the code collapsed by default inside an expandable section with syntax highlighting (you can replace python
with any of the "short names" listed in this page of supported languages):
<details>
<summary>Part 1</summary>
```python
Your code here.
```
</details>
I was lucky enough to have a decently robust Intcode computer which didn't need to be touched at all, so this question was a nice break from messing with Intcode and whatever was going on yesterday.
Part 1 Strategy
There's a 99% chance that the robot won't go crazy coordinate-wise (100%, now that I know how it behaves), but just to make sure, we store the coordinates in a hash set instead of a grid.Our Intcode computer implementation plays nicely with I/O (input and output are queues, both of which can be messed with whenever the computer interrupts), so we just need to feed in the appropriate color number when it halts for input and keep track of its position/direction.
We can do this by updating the position whenever the computer halts for input, since by then it will have output its paint color & turning direction.
Then, in order:
Letting the code chug along until it halts (and hoping that there isn't a hidden bug in the computer), output the number of distinct elements in the "painted once" set.
Side note: If you try to view the final output, the result resembles the output of a cellular automaton, likely a Turmite but one which I can't immediately recognize.
Part 2 Strategy
Since the code will happily buzz around with whatever configuration we give it, we just add the initial coordinate to the set of white tiles and run it again.We don't actually know where the tiles are, so that takes a little messing around to find (hard code) the proper coordinates.
Once we have a decent enough window to view our tiles, just read off the letters (and maybe flip it if it turns out to be upside down).
Part 1/2 Code
Part 1 Discussion
Did yours actually halt on its own? Mine seemed to get stuck in an infinite loop so I had to add code to terminate it after a certain number of iterations
Part 1
In my case, I put it in the middle of a 100x100 grid and it does halt after 100,010 instructions executed.
I actually struggled more with finding how big of an input area I needed and formatting the Part 2 output than with the puzzle portion. I had to do a very minor modification to int-puter, but it was something I knew was missing but hadn't bother to implement yet
Part 1 & 2 Summary and Code - Python
Basically I just made the robot feed back into itself and created a few new functions to manage interactions with the grid. I was afraid that Part 2 would require multiple robots or something silly, so I wanted to try to compartmentalize it a bit. The additional functionality I mentioned needing to add was the 'get_output_history' method. The earlier version of intputer could only look at the most recent output, but this required being able to look 1 further back.
Minor Tips - Not Really Spoilery
I had to make Part 1 like 500x500 before I stopped getting index out of bounds. But for Part 2 I was able to shrink it down substantially, I used 100x100, but if I hadn't started in the middle it could be much smallerOf course, none of that matters if you're doing it in a way that automatically grows
Minor Tips - A Bit Spoilery
During Part 1 it seems that the robot gets into an infinite loop. I had it stop operating after 10000 iterations, but it probably starts repeating well before thatEdit: This is apparently do to a bug in my code, not part of the base problem. Oops.
Part 1 Spoilery Stuff
That behavior is pretty weird, since for me, the robot did halt at some point.You know your code better than I do, but the infinite loop might be a bug resulting from not assigning
result
during the computer's running loop.When I use the line
result = puter.run_puter()
instead of rawputer.run_puter()
, the loop does terminate and output the correct result.Edit: Turns out we were wondering the same thing at the same time!
My input took 9791 loops to halt, so 10000 is just enough to be right anyway.
Part 1 - Spoilers Continued
Fuck, I think you're right, I completely missed that part. I even have it commented out a few lines down. Thanks!
Whoops! I accidentally did part 1 slightly wrong in such a way that I revealed the correct answer for part 2, which lead me down a long rabbit hole and had me questioning my sanity.
During that rabbit hole I ended up replacing my VM buffer-based input with one based on setting up a pair of I/O lambdas, and during the re-implementation I managed to fix part 1 so ¯\_(ツ)_/¯
Part 1 & 2, Crystal
Well I took this challenge as a chance to refactor my Intputer into an object, which I really should have done for the amplifier challenge but oh well. Once I had that done, I didn't think this was too difficult, though I did benefit a little bit from @PapaNachos nonspoiler tips, and from doing a super overkill way of visualizing the output from Part 2.
Python code below is split up by file that I used, not by part, parts 1 and 2 are mixed in.
Intputer
PaintBot
Main - SpacePolice