Advent of Code 2024 - Day 17Chronospatial Computer
| Problem statement | Source code | Tags: VMManual inspectionBitwise operationsPuzzle
This problem pays tribute to 2018 day 6 (unimplemented).
Part 1
Not much to say. After IntCode, this is just another assembly language to parse and execute.
Part 2
This problem reminds me of 2021 day 24, where we also have to stare at assembly and figure out some pattern, so here it is.
I'm redacting X and Y because they are personalized. Anyway, this code is just the following in C (because OCaml is terrible at describing bitwise operations):
Even simpler:
Let's assume x = 1, y = 2 (they aren't for my input). Denote the bits of a from lowest to highest (at this particular iteration) as [a0], [a1], etc. The output is then:
ao | (a >> (ao ^ x)) ^ ao ^ x ^ y |
|---|---|
000 | [a3]11 |
001 | 011 |
010 | [a5][a4][~a3] |
011 | [a4][a3]0 |
100 | [~a7][~a6][~a5] |
101 | [~a6][~a5][a4] |
110 | [~a9][a8][~a7] |
111 | [~a8][a7][a6] |
The expected output is:
Since I want to find the smallest a, I should start with the most significant bits and work our way down. The last output is 0, and I can pick all rows in the table that don't contain any 1 bits. Since higher bits than the MSB are necessarily 0, the only solution is ao = 011. That's the highest octet of a. Now I can pick the next octet equipped with this knowledge, and so on. Sometimes I may have multiple choices, and I use a DFS to figure out the first valid solution.
In my code, I literally built up this table by precomputing (a >> (ao ^ x)) ^ ao ^ x ^ y for every value of ao, using a bit_info data structure:
Then, for each output number, I find all possibilities of ao that's compatible with the current a value, and try each one. The tentative_a is the bits of a that we have already determined (starting from the least significant determined bit, up to the most significant determined bit which is also the MSB of the whole a).
The last step is just to go through hoops to convert this bit array into an integer.