So, today's Advent of Code puzzle somewhat reminded me of last year's intcode work, but it really seemed to be more formalizing code that looked like assembly with the use of
acc meaning "No Operation", "Jump" and "Increase the accumulator". The two parts both came from the source of a handheld device which doesn't boot up properly. Part one's objective was to determine the current accumulator value when it reached the same instruction for a second time, Part two's objective was to determine either which
nop should be a
jmp to get to the end of the instruction set completely or which
jmp should be a
nop to get to the end of the instruction set completely. After changing the correct instruction, reporting the accumulator value at the end provided the correct output.
I was able to pretty easily get part one complete by streaming the data input and then doing a while loop to calculate the current index of the instruction as well as the current accumulator value to report the accumulator value when the boot sequence was interrupted. I was unable to use streams for the processing logic in this problem and it was a bit frustrating, but I want to determine if streams are always something that can/should be used.
I've yet to find a way to use java streams "properly" when having to track external state things, and especially in scenarios where there's asynchronous movements afoot, today was yet another day where this kind of asynchronous processing needed to take place, this time, it was by taking a sum from going around to indexes that change at each step of the processing. I can still do streams for parts of the work (file reading, processing known values, etc.) but the bulk processing of that list of instructions I was unfortunately unable to perform by using Java Streams. Perhaps a good challenge for myself would be to try to convert that work into streams, who knows?
Part two required you iterate through the
nop instructions and flip their command (from
nop or from
jmp) to see if the boot was properly fixed by the change/update. In my initial solution, I went through the processing one time to collect the used
nop commands to change just those and it worked well, but when I tried to migrate to streams, I figured collecting all
nop items would be the "streams" approach to handle this approach. I simply made a method that supported changing either a
nop index from one command to the other and then from that change re-run the boot sequence. If that boot sequence successfully ran, it would then return the final accumulator value for that run, and that final accumulator value was the final answer for part two.
None of this puzzle was hard, it was somewhat involved, but I found it to be fairly simple to complete in the long run. The only REAL struggle that I had was setting up my while loop for the second part because I set the secondary condition in my loop (to see if we reached the end) to be the condition to exit, rather than the condition to stop processing (
index > instructions.size() rather than
index <= instructions.size()) and I made that an or, because again I wasn't super bright early on in the day. I suppose that's an issue I have with trying to do these problems early in my day, rather than after waking up (and no, coffee won't fix this, because I don't like coffee).
If you want to join my Advent of Code leaderboard, feel free to join with the code:
699615-aae0e8af. I'll keep pushing to complete these challenges, because I find them to be fun and interesting.