AoC 2025 Day 1
2025-12-14, Sunday
Starting very late to the party this year, but finally starting Advent of Code.
It's a very thematic, slightly amusing, and very interesting set of puzzles set each year. A new puzzle is made available each day of December up to the 25th (although only 12 days this year) and once you complete a puzzle for the day, you get another version of the puzzle with a tricky twist that you have to account for.
Thar be spoilars ahead! I'm also writing assuming you're familiar with the challenge, so go and read that first. Even better, give it a go yourself if you haven't already!
Day 1 is usually very simple to get you started, and this year was no exception. Part 2 however gave me some trouble, and it took me a long time to figure out why. So, let's start with my initial implementation:
for (let line of inputLines) {
if (!line) continue
let dir = line[0]
let amount = parseInt(line.substring(1))
if (dir === 'R') {
dialPosition += amount
while (dialPosition > 99) {
dialPosition -= 100
}
} else {
dialPosition -= amount
while (dialPosition < 0) {
dialPosition += 100
}
}
if (dialPosition === 0) {
zeroesCount++
}
}
Basically, interpret the line's instructions from the input, then calculate where the dial will end up, and for part 1 all we need to know is how many times it ends on zero. Simple enough so far.
Part 2 steps it up by saying that actually, we need to count how many times the dial passes over zero. So I added an increment to the total in my while statements, and that should cover it. Easy peasy!
But my answer was too high. OK, maybe I'm accounting for the dial ending on zero at the end as well as in the whiles somehow, so let's try without that. Still wrong - but not "too high" this time, so it's somewhere close, maybe just a few off. Where could it be wrong?
I checked on the Reddit megathread for any ideas, and there wasn't really any discussion rather than just people posting their solutions. So I read a couple of these and found one that interested me: it cranked the dial on the safe one digit at a time, and calculated the state appropriately from there. I couldn't see at the time how this could be more accurate than what my clever was doing, surely I'm just skipping over what they're doing in hundreds of tiny steps? But I gave it a try anyway:
for (let line of inputLines) {
// avoid the empty line at the end of the file
if (!line) continue
// extract the info we need
let dir = line[0]
let rotateAmount = parseInt(line.substring(1))
// turn the dial one click at a time
function rotateLeft(amount) {
while (amount > 0) {
amount--
dialPosition--
// check if we click zero
if (dialPosition === 0) {
duringZeroesCount++
} else if (dialPosition === -1) {
dialPosition = 99
}
}
}
function rotateRight(amount) {
while (amount > 0) {
amount--
dialPosition++
// check if we click zero
if (dialPosition === 100) {
duringZeroesCount++
dialPosition = 0
}
}
}
// begin rotating the dial
if (dir === 'R') rotateRight(rotateAmount)
else rotateLeft(rotateAmount)
// check if we landed on zero
if (dialPosition === 0) endOnZeroesCount++
}
Correct answer.
It was hours later that I realised the probable case that wasn't accounted for in my original code: say it's on 50, and it clicks 350 to the right. It would go up to 400, so my original code would take 100 off 4 times to bring it to down to 0, then also add one for ending up on a zero. Whoops!
Well, the point of these things is to think through the details of what's going on and try to come up with alternative (and ideally better) solutions. Hopefully I can get my brain in gear, and be more ready for the next few days' puzzles!
Oh, and I'll be pushing all my solutions to GitHub as usual. You'll find repos with past years there as well.
Later, alligators!