First, we’ll test our language with our sample circuit. All we do is add a #lang wires designation to the top:
1 2 3 4 5 6 7 8 9 | #lang wires x AND y -> d x OR y -> e x LSHIFT 2 -> f y RSHIFT 2 -> g NOT x -> h NOT y -> i 123 -> x 456 -> y |
When we run this in DrRacket, we get the result:
1 2 3 4 5 6 7 8 | d: 72 e: 507 f: 492 g: 114 h: 65412 i: 65079 x: 123 y: 456 |
Exactly right. Because we’ve modeled our wires as Racket functions, we can fiddle with them on the REPL just like any other functions:
1 2 3 4 5 6 7 8 | > x #<procedure:x> > (x) 123 > (y) 456 > (d) 72 |
Because our wires expander exports the 16-bit operations, we can use those on the REPL too:
1 2 3 4 | > (AND (x) (y)) ; same as definition of `d` 72 > (LSHIFT (x) 2) ; same as definition of `f` 492 |
Now we can try the main puzzle file, which is a 339-wire circuit. As before, we just add #lang wires to the top (excerpt below, but the whole thing is available in the source listing):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #lang wires bn RSHIFT 2 -> bo lf RSHIFT 1 -> ly fo RSHIFT 3 -> fq cj OR cp -> cq fo OR fz -> ga t OR s -> u lx -> a NOT ax -> ay he RSHIFT 2 -> hf lf OR lq -> lr lr AND lt -> lu dy OR ej -> ek 1 AND cx -> cy hb LSHIFT 1 -> hv 1 AND bh -> bi ih AND ij -> ik ··· |
This will print a list of all the wire values:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | bo: 10292 ly: 4045 fq: 6560 cq: 15518 ga: 60815 u: 1 a: 46065 ay: 65531 hf: 15568 lr: 8187 lu: 7027 ek: 15935 cy: 0 hv: 1438 bi: 1 ik: 9873 ··· |
Since we might not notice the value of wire a as it goes whizzing by, we have two choices. We can update our define/display macro in the expander to only print the value of the a wire. (An exercise left to the reader.) Or we can just evaluate a on the REPL:
1 2 | > (a) 46065 |
Puzzle solved. (If you sign up at Advent of Code, you can get your own puzzle file and feed it to #lang wires.)