Background

On Day 3, we helped the EBs' design department by removing invalid triangles from the list.

On Day 4, we will figure out which rooms on an encrypted information kiosk are valid and which ones are not.

Problem - Part 1

The kiosk lists one room per line. Each room entry consists of 3 parts.

Encrypted name comprised of lowercase letters separated by dashes

Always follows by a dash

Sector ID

Checksum

Always in square brackets

For Part 1, we have to determine which entries are real by calculating a checksum based on the encrypted name. The actual answer we have to provide is the sum of the sector IDs for all valid rooms.

Before I dive into the solution, I want to note that this problem has a lot of moving parts and, even though I've already solved it, it took me over half an hour to understand it again. There's just something about it that confuses the heck out of me every time.

Solution - Part 1

I approached the solution from a few different angles before I settled on the following solution.

I started by first trying to understand the overall steps involved in the solution. Then, once I had a basic picture worked out, I focused on creating a data structure that could hold all the data that I needed.

I knew I wanted a single 'flow' to the logic and to do that, I would have to pull together separate pieces of data and then start tying them together. With the right data structure, I could basically thread it through all my functions and tie them together nicely at the end.

My overall solution strategy is as follows.

Store each unchanged line of data.

Extract the sector ID and checksum.

Based on the requested answer, we can assume that all sector IDs are numeric values.

Calculate the checksums for each encrypted room name.

Finally, filter the list and add up the valid rooms' sector IDs.

The one thing that I noticed above all else is that I had to go out and learn a lot more about regular expressions in general and .NET regular expressions specifically to solve this problem.

Create the data structure

My whole solution hinges on a data structure that can hold all the data I need a series of disparate functions that only come together at the end.

Extract the provided sector ID and checksum

Extracting the sector ID proved to be quite an issue until I read the problem over a few more times. Once I understood that the sector ID is numeric only (since we have to add them up) and the encrypted name (and thus the checksum) is composed of lower-case letters only, the regular expression was relatively simple.

All the heavy lifting has already been done by the time we get to Seq.filter. I chose to go with Seq.fold instead of Seq.reduce because the latter can fail with an ArgumentException when the sequence is empty.

When you run this function on the input file, you get 158835, which is, in fact, the correct answer.

Problem - Part 2

For Part 2, we have to decrypt the encrypted room name using a shift cipher.

The question we have to answer is "what is the sector ID of the room where North Pole objects are stored?"

When you calculate day4part2, you get sector ID 993, which is the correct answer.

Testing

This is the first AOC problem where I introduced testing, something that was long overdue. I did not use any framework, but created a separate script file that contained basic unit tests. These tests printed their results to the console and were quite crude (I calculated the results manually and then turned those results into unit tests).

Despite how simple the tests were, they cut down the trial and error time considerably. I especially felt the impact on this problem where I kept hitting roadblocks every step of the way.

Lessons Learned

I learned a few lessons from this exercise.

Creating separate functions for different pieces of the solution was a good idea and allowed for a lot of reusability.

I will definitely be continuing this trend in the future.

The semi-automated testing, as crude as it was, helped immensely.

This is even easier for AOC since we have specific examples given with each Part of each problem.