:date: 2023-12-16 12:00
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.
This final full data set finished in a respectable 188ms.
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!