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
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
}, [[],[]])
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 ] ]
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
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
})
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.
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)