AoC - Day 16

:date: 2023-12-16 12:00

Part One

This was a 2d grid situation and somewhat deserving of a game engine. In fact, it was about lasers being turned on a game board with mirrors and sometimes splitting. So very much like a game; certainly as complicated as some casual games get. That splitting made me think of recursion but at this point, I am suspicious about this challenge. Now I suspect that there will be so much recursion that it will cause trouble with depth limits and so on. I wondered if I could use a stack of my own to handle the branching. I have a stack outlined in my C notes, and I got the ambitious idea to use C. I also used my dynamic memory reading code, which means I could operate on inputs much bigger than specified. It took a lot of time but I finally got the game board setup. I got my stack setup to handle the branching. I got all the logic encoded. That was no small thing! I had nested case statements and I had to use goto, something I've not done since the 1980s. (Though check out day 19 for an extreme goto bonanza!)

I had a lot of really gruesome debugging episodes. The worst was a stray } which was left after rearranging some lines. C can be brutal with stuff like that and mystery behavior. I finally got all the action working and started encoding where the beam had been. For that I used a bit mask so I never repeated a path I'd traversed (in a particular direction) before. Finally I got the sample to come good. I ran it on the full data and the answer was correct. It ran in under 22ms!

Here's what the solution to part one looked like.

16.png

This final full data set finished in a respectable 188ms.

Part Two

Finally a part two that doesn't require me to totally rewrite part one. Part two is basically just running my part one program from lots of starting positions. Well, I have a struct that contained the starting position. I just wrapped it in a loop and... well, I got lazy and made four copies of the program so that I could have one dedicated to each direction. I then ran it like this.

$ cat <(./16beamN-U <$I) <(./16beamN-D <$I) <(./16beamN-L <$I) <(./16beamN-R <$I) | sort -n | tail -n5
7217 =Total N:69 ^0
7217 =Total N:75 ^0
7264 =Total N:15 v2
7275 =Total N:18 >1
7313 =Total N:56 >1

And that was correct! The test input finished in 36.0ms! Those are the moments when you love C!