The Problem

Imagine a circular dial (like a combination lock) with 100 positions numbered 0 to 99. The dial starts pointing at 50.

You receive a sequence of rotation instructions:

  • L = rotate Left (toward lower numbers)

  • R = rotate Right (toward higher numbers)

  • The number following indicates how many "clicks" to rotate

Because the dial is circular:

  • Going left from 0 wraps to 99

  • Going right from 99 wraps to 0

Summary

Part

Question

Strategy

1

How many times do we end on 0?

Simple: check dial === 0 after each move

2

How many times do we pass through 0?

Calculate distance to first 0, then count full rotations

Part 1: Count Final Positions at Zero

Goal: Count how many times the dial lands on 0 at the end of a rotation.

dial = (((dial + sign * distance) % range) + range) % range;

The Modulo Wrap-Around Formula

This formula handles circular arithmetic:

  1. dial + sign * distance → Calculate the raw new position

    • sign is -1 for Left, +1 for Right

  2. % range → First modulo brings it into range, but can be negative!

    • Example: (5 - 10) % 100 = -5

  3. + range → Add 100 to handle negative results

    • -5 + 100 = 95

  4. % range → Final modulo ensures we're in [0, 99]

    • If the first result was positive, this cancels the extra + range

Why this works: In JavaScript, -5 % 100 returns -5, not 95. The double-modulo trick ensures we always get a positive result in the valid range.

VISUALIZER
0
8
17
25
33
42
50
58
67
75
83
92
Position
50
Zero Lands
0
EVENT LOG
No actions yet

Part 2: Count Every Click Through Zero

Goal: Count every time the dial passes through 0, not just when it lands there.

This is the tricky part! If you're at position 50 and rotate L200, you'll pass through 0 twice.

The Key Insight: Calculate Distance to First Zero

const firstZero =
    dial === 0 ? range : direction === "L" ? dial : range - dial;

Current Position

Direction

Distance to First Zero

dial = 50

Left (L)

50 clicks (50→49→...→1→0)

dial = 50

Right (R)

50 clicks (50→51→...→99→0)

dial = 0

Either

100 clicks (full rotation needed)

Visual example going Left from 50:

50 → 49 → 48 → ... → 2 → 1 → [0]

Visual example going Right from 50:

50 → 51 → 52 → ... → 98 → 99 → [0]

Counting All Zero Crossings

if (distance >= firstZero) {
    zeroCount += Math.floor((distance - firstZero) / range) + 1;
}

The logic:

  1. Check if we even reach zero: distance >= firstZero

    • If we don't travel far enough, we never hit zero

  2. Count the crossings:

    • +1 → We definitely hit zero at least once (at firstZero)

    • (distance - firstZero) / range → After the first zero, how many complete 100-click rotations fit?

    • Each complete rotation = one more pass through zero

Example: Position 50, instruction L250

  • firstZero = 50 (distance to reach 0 going left)

  • distance = 25050 ✓ we will hit zero

  • Remaining after first zero: 250 - 50 = 200

  • Complete rotations: Math.floor(200 / 100) = 2

  • Total zeros: 2 + 1 = 3 🎯

Start at 50
├── 50 clicks left → hit [0] (1st time)
├── 100 more clicks → hit [0] (2nd time)  
├── 100 more clicks → hit [0]

VISUALIZER
0
8
17
25
33
42
50
58
67
75
83
92
Position
50
Zero Lands
0
EVENT LOG
No actions yet