Contents

Advent of Code 2025 - Day 1: Secret Entrance

Day 1 of Advent of Code 2025 is in the books. The puzzle involved a safe with a circular dial numbered 0-99, and the goal was to count how many times the dial landed on 0 after following a series of rotation instructions.

Part 1: The Straightforward Approach

Part 1 was pretty straightforward. Given a starting position of 50 and a sequence of left (L) and right (R) rotations, I needed to count how many times the dial ended up pointing at 0 after each rotation.

The solution came naturally - modulo arithmetic handles circular movement perfectly:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def part1():
    arr = loadFile(input_f)
    start = 50
    current = start
    score = 0
    
    for x in arr: 
        if x[0] == 'L':
            current = (current - int(x[1:]))%100
        elif x[0] == 'R':
            current = (current + int(x[1:]))%100
        if current == 0:
            score += 1
    
    return score

Got it right on the first try.

Part 2: When Modulo Isn’t Enough

Part 2 threw a curveball. Now I needed to count every time the dial passed through 0 during a rotation, not just where it ended up. So a rotation like R1000 would pass through 0 ten times before returning to where it started.

My initial instinct was to stick with modulo - after all, it worked great in Part 1. But I quickly realized the problem: numbers larger than 100 meant the dial would circle around multiple times in a single rotation. Modulo gives you the final position, but it doesn’t tell you how many times you crossed 0 getting there.

I tried a few approaches:

  • itertools.cycle - but you can’t go backwards through a cycle, and left rotations need that
  • Floor division (//) - couldn’t quite get the logic right

The guesses tell the story:

  • 2620 (too low)
  • 6879 (too high)
  • 5224 (too low again)
  • 6430 (incorrect)
  • 6412 ✓

After burning time on clever solutions, I went with the straightforward approach - just simulate each click:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def part2():
    arr = loadFile(input_f)
    start = 50
    current = start
    score = 0

    for x in arr:
        dir = x[0]
        num = int(x[1:])
        if dir == 'L':
            for i in range(num):
                current = (current - 1)%100
                if current == 0:
                    score += 1
        elif dir == 'R':
            for i in range(num):
                current = (current + 1)%100
                if current == 0:
                    score += 1

    return score

Sometimes brute force is the answer. The performance hit doesn’t matter when you’re dealing with puzzle input sizes, and it got me to the right answer.

Takeaways

Part 1 rewarded recognizing the problem pattern quickly. Part 2 was a good reminder that the elegant solution isn’t always the one that works - and that spending 20 minutes trying to be clever when you could just loop through the values is sometimes the wrong call.

Both stars collected. On to Day 2.