Day 10 Stacks all the way down

This one is about matching parenthesis, which means that anyone writing in closure is likely to be able to do this one just by instinct!

Ok, we need to match parenthesis in 4 different types.

The golden rule here is actually pretty simple, there's a kind of state machine, in which each character on a line should only be one of 4 options, (, {, [, < and then the closing parenthesis of whatever type we last opened. So when we see a (, the closing type is ).

But when we do see the closing type, we need to get the next previous one that we saw.

This is a stack, like a stack of plates in a canteen. If you put something on the top of the stack, then when you take it off, whatever was there before is revealed.

Python doesn't have a stack data type itself, what it does is provide a set of methods on a list that mean you can treat it as a stack. Generally a stack has 4 main methods, push, pop, peek, empty?. These map in pythin to append, pop, [-1] and the comparison to [].

That combined with the 3.10 match statement should make processing a line pretty simple.

Read each character, if it's an open parenthesis, push the matching close onto the stack. If it's a close, compare it to whats on the stack, if it doesn't match, stop processing and return the character that broke for scoring. If it does match, pop that item off the stack and keep going

So that works... let's try it on some of the example lines

The total there is calculated by looking through the results, getting all the corrupted lines and then finding the error, and mapping that to a score.

Part 2

Ok, unusually for us, part 2 has itself two main parts. The first is that we need to essentially return the stack. Those are the letters, in order, that can close all of the open lines. In our case that part is pretty simple.

The second issue however is the unneccesarily complex scoring mechanism. We'll write a function to take a stack and turn it into a score, and the change in our main code is simply to return the stack when we get to the end of teh line.

Note: the stack is a list, in reverse order. Since we want to process each item, isntead of popping them, we cna simply reverse the list and then iterate over them.

Let's confirm that the changes to the process_chunks can return teh right stacks

Ok, final thing, we don't want the actual score, we want the middle number from the scores once sorted. With a given list of scores, given the constraint that there will always be an odd number of items, the midpoint should be at (len(list)-1)//2.

Let's try that on prod data then