2025

Previous years have taught me to reach for modulo when dealing with cycles, and part 1 was pretty comfy. However, I took a long time stumbling on part 2 with floor division and adjusting for my undercounting. I did get there in the end with my R solution, and then went on to try using Python just to run through every click, which turned out to be a much simpler with a faster time-to-solution.

— R Day 1 Part 1 —

solve_day1_part1 <- function(input) {
  pos <- 50L
  dial_size <- 100L
  zero_counter <- 0L

  dir <- substr(input, 1L, 1L)
  val <- as.integer(substr(input, 2L, nchar(input)))

  turns <- ifelse(dir == "R", val, -val)

  for (turn in turns) {
    pos <- (pos + turn) %% dial_size

    zero_counter <- (pos == 0L) + zero_counter
  }

  zero_counter
}
Run
aoc_source(day = 1, part = 1)

input = aoc_read(day = 1)

aoc_run(solve_day1_part1(input))
Elapsed: 0.002 seconds
Memory:  381 KB

— R Day 1 Part 2 —

solve_day1_part2 <- function(input) {
  pos <- 50L
  dial_size <- 100L
  counter <- 0L

  dir <- substr(input, 1L, 1L)
  val <- as.integer(substr(input, 2L, nchar(input)))
  turns <- ifelse(dir == "R", val, -val)

  for (turn in turns) {
    # position on infinite number line
    abs_pos <- pos + turn

    # count multiple of 100 between the start and end
    if (turn > 0) {
      counter <- counter +
        (abs_pos %/% dial_size) -
        (pos %/% dial_size)
    } else {
      counter <- counter +
        (pos - 1L) %/% dial_size -
        (abs_pos - 1L) %/% dial_size
    }

    pos <- (pos + turn) %% dial_size
  }

  counter
}
Run
aoc_source(day = 1, part = 2)

input = aoc_read(day = 1)

aoc_run(solve_day1_part2(input))
Elapsed: 0.003 seconds
Memory:  421 KB

— Python Day 1 Part 1 —

def solve_day1_part1(text):
    zero_counter = 0
    dial_size = 100
    pos = 50

    turns = [turn.replace("L", "-").replace("R", "") for turn in text]
    turns = [int(turn) for turn in turns]

    for turn in turns:
        pos = (pos + turn) % dial_size

        zero_counter += pos == 0

    return(zero_counter)
Run
aoc_source(day = 1, part = 1)

input = aoc_read(day = 1)

result = aoc_run("solve_day1_part1(input)")
Elapsed: 0.002 seconds
Memory:  409 KB

— Python Day 1 Part 2 —

def solve_day1_part2(text):
    zero_counter = 0
    dial_size = 100
    pos = 50

    for line in text:
        if line[0] == "R":
            step = 1
        else:
            step = -1

        amount = int(line[1:])

        for _ in range(amount):
            pos = (pos + step) % dial_size
            if pos == 0:
                zero_counter += 1

    return(zero_counter)
Run
aoc_source(day = 1, part = 2)

input = aoc_read(day = 1)

result = aoc_run("solve_day1_part2(input)")
Elapsed: 0.161 seconds
Memory:  12 KB
Back to top