DEV Community

Cover image for Code Chronicle
Robert Mion
Robert Mion

Posted on

Code Chronicle

Advent of Code 2024 Day 25

Part 1

A cool way to end the year

This seems like a fun challenge. And one I am excited to attempt.

The first thing I notice is:

  • The example input separates locks and keys
  • My puzzle input does not

So, my algorithm will need to be extra attentive when classifying them.

As per the explanation, I intend to store each lock and key as an array of numbers representing each column height.

Maybe from there I can write an algorithm that does this:

For each lock
  For each column
    Further filter the list of keys to those with 5 - N height
    in this column, where N is the lock column's height
  Any remaining keys are winners
Enter fullscreen mode Exit fullscreen mode

That seems like it could work.

I'm excited to try coding it!

Writing my lock-key matching algorithm

Processing the input into two lists that each contain 5-digit lists:

input = input.split('\n\n').reduce((group, item) => {
    item = item.split('\n').map(line => line.split(''))
    if (item[0].every(el => el == '#')) {
        // Lock
        let digits = []
        for (let i = 0; i < 5; i++) {
            let tally = 0
            while (item[tally + 1][i] == "#") {
                tally++
            }
            digits.push(tally)
        }
        group[0].push(digits)
    } else if (item[0].every(el => el == '.')) {
        // Key
        let digits = []
        for (let i = 0; i < 5; i++) {
            let tally = 0
            while (item[5 - tally][i] == "#") {
                tally++
            }
            digits.push(tally)
        }
        group[1].push(digits)
    }
    return group
}, [[],[]])
Enter fullscreen mode Exit fullscreen mode

I'm proud of both for and nested while loops that walk down and up each column to determine the height.

As expected, my reduce generates two lists, each one containing 5-digit arrays:

[ [ 0, 5, 3, 4, 3 ], [ 1, 2, 0, 5, 3 ] ] 
[ [ 5, 0, 2, 1, 3 ], [ 4, 3, 4, 0, 2 ], [ 3, 0, 2, 0, 1 ] ]
Enter fullscreen mode Exit fullscreen mode

Now for the fun part: matching keys with locks.

Comparing most keys to every lock

I have a list of locks and a list of keys.

What I intend to do:

For each lock
  Further filter the list of keys
  Based on the number in each column
  Until only keys that fit the lock remain
  Increment a running tally of valid keys
Enter fullscreen mode Exit fullscreen mode

That should get me the correct answer for Part 1.

It would certainly work to get the correct answer for the example input.

Now, to write the algorithm as code:

let tally = 0
locks.forEach(lock => {
    tally += lock.reduce((keysRemaining, digit, index) => {
        return keysRemaining.filter(item => item[index] <= 5 - digit)
    }, keys.map(el => el.slice())).length
})
Enter fullscreen mode Exit fullscreen mode

Could it really be that simple?

Here's what I'm doing:

  • Initialize a value to count all valid keys
  • Iterate through each lock
  • Increment the tally based on how long the final list of keys is after filtering it five times - once for each digit

When running it on the example input, I get 3, the correct answer.

I'm tempted to just run it on my puzzle input.

Worst case, I get a wrong submission and only have 3 more attempts to point me in the right direction.

I'm gonna do it!

Running on my puzzle input

What will it output?

...

A number in the low thousands.

Seems...right?

Time to submit.

...

It was correct!

Woohoo!!!

Year in review

I matched my lowest score in a year: 34.

Given that this year seemed like the hardest one, I'm very proud I didn't set a new lowest score.

My 2024 advent calendar

As for all time scores:
Yearly scores list

382/500 is 76.4% or a strong C.

That's been my average this entire journey thus far.

This was another real fun year with interesting new puzzles.

Up next, 2025!

Thanks again for reading.

Top comments (0)