Definitely the smallest diff between Part 1 and Part 2 — I just deleted a line in my part 1 solution that hard-coded where the light entered the grid
**enter 0 0 (pair 1 0).**
…and instead added that programmaticaly in JavaScript. This wasn’t a fast or awesome Part 2 solution, and relied on JavaScript logic a fair amount, but the Part 1 solution was very clean in pretty much all Dusa.
I think lots of people got tripped up on the fact that this problem used \\
characters, which are generally an escape character. Dusa doesn’t even support escape characters! So I had to read in the backslashes as &
. This was the first time my JavaScript parsing logic used much of anything more than maps, split(), or slice(). (Day 15 also needed charCodeAt(), I suppose.)
Here’s the part 1 solution Dusa%20%3A-%0A%20%20%20%20cell%20X%20Y%20is%20%22%2F%22%2C%0A%20%20%20%20enter%20X%20Y%20(pair%20DX%20DY).%0A%0Aleave%20X%20Y%20(pair%20DY%20DX)%20%3A-%0A%20%20%20%20cell%20X%20Y%20is%20%22%26%22%2C%0A%20%20%20%20enter%20X%20Y%20(pair%20DX%20DY).%0A%0Aenter%20(plus%20X%20DX)%20(plus%20Y%20DY)%20(pair%20DX%20DY)%20%3A-%0A%20%20%20%20leave%20X%20Y%20(pair%20DX%20DY)%2C%0A%20%20%20%20cell%20(plus%20X%20DX)%20(plus%20Y%20DY)%20is%20_.%0A%0Acharged%20X%20Y%20%3A-%20enter%20X%20Y%20_.%0A%0Aenter%200%200%20(pair%201%200).%0A%0Afield%20ref12%200%20is%20%22.%22.%0Afield%20ref12%201%20is%20%22.%22.%0Afield%20ref12%202%20is%20%22%2F%22.%0Afield%20ref12%203%20is%20%22%2F%22.%0Afield%20ref12%204%20is%20%22.%22.%0Afield%20ref12%205%20is%20%22%7C%22.%0Afield%20ref12%206%20is%20%22.%22.%0Afield%20ref12%207%20is%20%22.%22.%0Afield%20ref12%208%20is%20%22.%22.%0Afield%20ref12%209%20is%20%22.%22.%0Afield%20ref11%200%20is%20%22.%22.%0Afield%20ref11%201%20is%20%22%7C%22.%0Afield%20ref11%202%20is%20%22.%22.%0Afield%20ref11%203%20is%20%22.%22.%0Afield%20ref11%204%20is%20%22.%22.%0Afield%20ref11%205%20is%20%22.%22.%0Afield%20ref11%206%20is%20%22-%22.%0Afield%20ref11%207%20is%20%22%7C%22.%0Afield%20ref11%208%20is%20%22.%22.%0Afield%20ref11%209%20is%20%22%26%22.%0Afield%20ref10%200%20is%20%22.%22.%0Afield%20ref10%201%20is%20%22-%22.%0Afield%20ref10%202%20is%20%22.%22.%0Afield%20ref10%203%20is%20%22-%22.%0Afield%20ref10%204%20is%20%22%2F%22.%0Afield%20ref10%205%20is%20%22.%22.%0Afield%20ref10%206%20is%20%22.%22.%0Afield%20ref10%207%20is%20%22%7C%22.%0Afield%20ref10%208%20is%20%22.%22.%0Afield%20ref10%209%20is%20%22.%22.%0Afield%20ref9%200%20is%20%22.%22.%0Afield%20ref9%201%20is%20%22.%22.%0Afield%20ref9%202%20is%20%22.%22.%0Afield%20ref9%203%20is%20%22.%22.%0Afield%20ref9%204%20is%20%22%2F%22.%0Afield%20ref9%205%20is%20%22.%22.%0Afield%20ref9%206%20is%20%22%26%22.%0Afield%20ref9%207%20is%20%22%26%22.%0Afield%20ref9%208%20is%20%22.%22.%0Afield%20ref9%209%20is%20%22.%22.%0Afield%20ref8%200%20is%20%22.%22.%0Afield%20ref8%201%20is%20%22.%22.%0Afield%20ref8%202%20is%20%22.%22.%0Afield%20ref8%203%20is%20%22.%22.%0Afield%20ref8%204%20is%20%22.%22.%0Afield%20ref8%205%20is%20%22.%22.%0Afield%20ref8%206%20is%20%22.%22.%0Afield%20ref8%207%20is%20%22.%22.%0Afield%20ref8%208%20is%20%22.%22.%0Afield%20ref8%209%20is%20%22%26%22.%0Afield%20ref7%200%20is%20%22.%22.%0Afield%20ref7%201%20is%20%22.%22.%0Afield%20ref7%202%20is%20%22.%22.%0Afield%20ref7%203%20is%20%22.%22.%0Afield%20ref7%204%20is%20%22.%22.%0Afield%20ref7%205%20is%20%22.%22.%0Afield%20ref7%206%20is%20%22.%22.%0Afield%20ref7%207%20is%20%22.%22.%0Afield%20ref7%208%20is%20%22.%22.%0Afield%20ref7%209%20is%20%22.%22.%0Afield%20ref6%200%20is%20%22.%22.%0Afield%20ref6%201%20is%20%22.%22.%0Afield%20ref6%202%20is%20%22.%22.%0Afield%20ref6%203%20is%20%22.%22.%0Afield%20ref6%204%20is%20%22.%22.%0Afield%20ref6%205%20is%20%22.%22.%0Afield%20ref6%206%20is%20%22.%22.%0Afield%20ref6%207%20is%20%22.%22.%0Afield%20ref6%208%20is%20%22%7C%22.%0Afield%20ref6%209%20is%20%22.%22.%0Afield%20ref5%200%20is%20%22.%22.%0Afield%20ref5%201%20is%20%22.%22.%0Afield%20ref5%202%20is%20%22.%22.%0Afield%20ref5%203%20is%20%22.%22.%0Afield%20ref5%204%20is%20%22.%22.%0Afield%20ref5%205%20is%20%22%7C%22.%0Afield%20ref5%206%20is%20%22-%22.%0Afield%20ref5%207%20is%20%22.%22.%0Afield%20ref5%208%20is%20%22.%22.%0Afield%20ref5%209%20is%20%22.%22.%0Afield%20ref4%200%20is%20%22%7C%22.%0Afield%20ref4%201%20is%20%22.%22.%0Afield%20ref4%202%20is%20%22-%22.%0Afield%20ref4%203%20is%20%22.%22.%0Afield%20ref4%204%20is%20%22%26%22.%0Afield%20ref4%205%20is%20%22.%22.%0Afield%20ref4%206%20is%20%22.%22.%0Afield%20ref4%207%20is%20%22.%22.%0Afield%20ref4%208%20is%20%22.%22.%0Afield%20ref4%209%20is%20%22.%22.%0Afield%20ref3%200%20is%20%22.%22.%0Afield%20ref3%201%20is%20%22%7C%22.%0Afield%20ref3%202%20is%20%22.%22.%0Afield%20ref3%203%20is%20%22.%22.%0Afield%20ref3%204%20is%20%22.%22.%0Afield%20ref3%205%20is%20%22%26%22.%0Afield%20ref3%206%20is%20%22.%22.%0Afield%20ref3%207%20is%20%22.%22.%0Afield%20ref3%208%20is%20%22.%22.%0Afield%20ref3%209%20is%20%22.%22.%0Afield%20ref2%200%20is%20ref3.%0Afield%20ref2%201%20is%20ref4.%0Afield%20ref2%202%20is%20ref5.%0Afield%20ref2%203%20is%20ref6.%0Afield%20ref2%204%20is%20ref7.%0Afield%20ref2%205%20is%20ref8.%0Afield%20ref2%206%20is%20ref9.%0Afield%20ref2%207%20is%20ref10.%0Afield%20ref2%208%20is%20ref11.%0Afield%20ref2%209%20is%20ref12.%0Afield%20ref1%20%22data%22%20is%20ref2.%0A) — the answer came from counting the charged
facts, where a cell is charged if light enters it.
**charged X Y :- enter X Y _.**
The key logic to this solution was this: the direction of a light beam was described by a tuple pair DX DY
, and if a beam is leaving a cell in a particular direction, and there’s a cell (regardless of contents) in that direction, then the beam is entering that adjacent cell in the direction of travel, in the same direction.
**enter (plus X DX) (plus Y DY) (pair DX DY) :-
leave X Y (pair DX DY),
cell (plus X DX) (plus Y DY) is _.**
All the rest of the solution is deriving leave
facts from enter
facts.
“Dots just let light pass through” is represented like this:
**leave X Y Dir :-
cell X Y is ".",
enter X Y Dir.**
I once again really wanted multiple-conclusion rules, because without them, second rule below requires some cut-paste of premises. Conceptually: light passes through a -
cell if it has no vertical component, and if it has a vertical component then there will be beams exiting to both the left and the right.
**leave X Y Dir :-
cell X Y is "-",
enter X Y Dir,
Dir == pair _ 0.
leave X Y (pair -1 0),
leave X Y (pair 1 0) :-
cell X Y is "-",
enter X Y (pair 0 _).**
(The rules for |
are analogous.)
Finally, the reflecting mirrors were very nice to describe as one-rule-per-mirror-configuration, though I couldn’t help feeling like this in particular was an awkward way to describe multiplying a vector by a 2x2 rotation matrix.
**leave X Y (pair (minus 0 DY) (minus 0 DX)) :-
cell X Y is "/",
enter X Y (pair DX DY).
leave X Y (pair DY DX) :-
cell X Y is "&",
enter X Y (pair DX DY).**
These solutions have to use escape characters, I used file IO to avoid that when I solved the problem “for real.”