advent_of_code_2025

My (attempted) solutions to the 2025 Advent of Code
git clone https://git.eamoncaddigan.net/advent_of_code_2025.git
Log | Files | Refs | README

day02.R (2100B)


      1 #!/usr/bin/env Rscript
      2 
      3 source("src/utils.R")
      4 
      5 test_input <- "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124"
      6 puzzle_input <- aoc_input(2)
      7 
      8 parse_input <- function(input_string) {
      9   lapply(strsplit(strsplit(input_string, ",")[[1]], "-"), as.numeric)
     10 }
     11 
     12 stem_to_id <- function(id_stem, reps) {
     13   sprintf("%d", id_stem) |>
     14     rep(reps) |>
     15     paste(collapse = "") |>
     16     as.numeric()
     17 }
     18 
     19 ids_in_range_with_reps <- function(num_range, num_reps) {
     20   ids_in_range_iter <- function(id_stem) {
     21     id_num <- stem_to_id(id_stem, num_reps)
     22 
     23     if (id_num < num_range[[1]]) {
     24       ids_in_range_iter(id_stem + 1)
     25     } else if (id_num <= num_range[[2]]) {
     26       c(id_num, ids_in_range_iter(id_stem + 1))
     27     } else {
     28       NULL
     29     }
     30   }
     31 
     32   start_str <- as.character(num_range[[1]])
     33   if (nchar(start_str) %% num_reps == 0) {
     34     min_stem <- as.numeric(
     35       substr(start_str, 1, nchar(start_str) / num_reps)
     36     )
     37   } else {
     38     min_stem <- 10^(ceiling(nchar(start_str) / num_reps) - 1)
     39   }
     40   ids_in_range_iter(min_stem)
     41 }
     42 
     43 part1 <- function(input_string) {
     44   input_string |>
     45     parse_input() |>
     46     lapply(\(x) ids_in_range_with_reps(x, 2)) |>
     47     vapply(sum, numeric(1)) |>
     48     sum()
     49 }
     50 
     51 test_part1 <- function() {
     52   stopifnot(part1(test_input) == 1227775554)
     53 }
     54 
     55 ids_in_range_all <- function(num_range) {
     56   ids_in_range_rep_iter <- function(num_reps) {
     57     if (num_reps > nchar(as.character(num_range[[2]]))) {
     58       NULL
     59     } else {
     60       c(
     61         ids_in_range_with_reps(num_range, num_reps),
     62         ids_in_range_rep_iter(num_reps + 1)
     63       )
     64     }
     65   }
     66   unique(ids_in_range_rep_iter(2))
     67 }
     68 
     69 part2 <- function(input_string) {
     70   input_string |>
     71     parse_input() |>
     72     lapply(ids_in_range_all) |>
     73     vapply(sum, numeric(1)) |>
     74     sum()
     75 }
     76 
     77 test_part2 <- function() {
     78   stopifnot(part2(test_input) == 4174379265)
     79 }
     80 
     81 main <- function() {
     82   test_part1()
     83   cat("Part 1 solution: ", part1(puzzle_input), "\n")
     84   test_part2()
     85   cat("Part 2 solution: ", part2(puzzle_input), "\n")
     86 }
     87 
     88 main()