We're parsing instructions and plotting in the terminal today!
What is Advent of Code?
In this little series, I want to write about the thought processes I have behind solving the puzzles presented in Advent of Code.
During the Advent of Code small coding puzzles are presented with varying levels of difficulty. They're always Christmas-themed text puzzles where you help elves out of some mess to save the holidays. The puzzles are deliberately ambiguous to not bias puzzlers into a certain solution, they always have an example input in the text to explain some details and an input file for each day that comes in the form of a text file you can download. The solution is a simple number or a string you enter, which is checked by the website automatically. After you finish part 1, part 2 unlocks, which is a variation on part 2. This can be a little twist on part 1 or a large twist that changes the problem formulation into a problem that would take brute force solutions to compute longer than the heat death of the universe would take.
Find my solutions here: github.com/JesperDramsch/advent-of-code
These descriptions won't be a perfect narrative, but rather how I think about these problems and where I see different solutions. I apologise for the possibility of rambling!
The example input
Is this this year's compiler problem? Noice!
noop addx 3 addx -5
Right away I can say that I should use
This is another brain-in-a-knot problem.
We have instructions that take different amounts of time to complete. We want to have the values at certain times that may be in between instructions.
So I add an increment
inc in addition to the
def process_instruction(instruction, cycles, X): add = 0 match instruction.split(" "): case "noop",: inc = 1 case "addx", add: inc = 2 add = int(add) return inc, add
Important to note that we have
X that starts at
I wonder if some sort of queue system will be necessary and I'm terrified of what part 2 might throw at us. 👀
I think I want to go "sparse" with this one. I could set up a queue I fill up, but I can also simply increase the counters with a check, so I don't run into troubles, when the queues suddenly get long.
cycles, X = 0, 1 for line in instructions: inc, add = process_instruction(line, cycles, X) if cycles < check <= cycles + inc: checks[check] = X check += 40 cycles += inc X += add
Part 2 needed a bit of refactoring so I can reuse the instruction processing you saw in part 1.
Everything else was just using the
add arguments in different ways:
inc, add = process_instruction(line, cycles, X) for i in range(inc): if X - 1 <= cycles % 40 <= X + 1: crt.append("#") else: crt.append(".")
Then I simply added a little function to draw the CRT
def plot_crt(crt): return "\n".join("".join(crt[i : i + 40]) for i in range(0, len(crt), 40))
And it was the first solution I couldn't submit automagically, but I love these honestly.
Annoyingly repeated a mistake by forgetting to set a variable this time around and hade a small misunderstanding of part 2 which was quickly resolved.
cycle += 1 UnboundLocalError: cannot access local variable 'cycle' where it is not associated with a valueforgot to start cycles
check = checks.values() TypeError: 'dict_values' object is not subscriptablethought that would be a list or something.
check = checks KeyError: 20oh my. Good thing I caught that, I set up my
if cycles < check <= cycles+inc: TypeError: '<' not supported between instances of 'int' and 'NoneType'Time to debug what I messed up here! I clearly don't understand the
matchstatement well enough yet. Ok, since I split on an empty space the "noop" line still is a list, so the case has to also look into a list like this:
case "noop",:. Good to know.
if cycles < check <= cycles+inc: TypeError: '<' not supported between instances of 'int' and 'NoneType'ah. Messed up my logic about using
checks. It should be the keys I'm working with and I also caught that I need to increment it.
return sum(cyclce*X for cycle, X in checks.items()) NameError: name 'cyclce' is not defined. Did you mean: 'cycle'?haha, those typos will get me every time.
return inc, add UnboundLocalError: cannot access local variable 'add' where it is not associated with a valueyou'd think I'd learn this by now.
return plot_crt(draw_crt(instructions)) NameError: name 'instructions' is not definedargh. wrong name!
- Bit of an understanding error about the CRT. I thought it was continuous indexing, but in fact it is for every line individually. Easy fix!