AoC 2022 D13: Distress Signal
| Problem statement | Source code | Tags: ParsingRecursion
← Previous Back to AoC Index Next →
Part 1
I first define the data type for the packets:
And, very importantly, the Ord instance:
(This shows how convenient Haskell type classes are: once we have compare, the type is automatically endowed with all the other comparison operators.)
This input reminds me of 2021 day 18, where we also had to parse a nested list structure. The difference is that this time I am using Haskell, and I do want strong types, so no Data.Aeson; manual parsing it is.
I do parsing the old school way: tokenize, then recursively parse. Tokens are just brackets and numbers (commas and whitespace are ignored):
Now I can parse the tokens into our TreeNode structure, using the following BNF:
It's all standard recursive descent parsing, so not much to say. Each time, I consume the tokens I need, and return the rest for the next step. For parseListElements, I keep consuming ListElements until I can't anymore (i.e., I hit a CloseBracket).
Now when parsing the whole input, I just unwrap and get the constructed tree. Technically, I should check that the parse was successful and that there are no remaining tokens, but I just assume that the input is well-formed and my parser is correct.
With the Ord and the parser in place, the actual solution is straightforward.
Part 2
I guess the more efficient way is to implement my own sorting algorithm that tracks the indices of the elements, but I just sort the packets and find the indices of the divider packets.