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

commit d3860d3b6c58fb2fd8fa8ffc3b2760c6cd32195b
parent afeb5d8953656863993c134c0f244f02adab4a20
Author: Eamon Caddigan <ec@eamoncaddigan.net>
Date:   Wed,  3 Dec 2025 08:41:13 -0800

Solve day 02, part 2

Diffstat:
Msrc/day02.R | 91+++++++++++++++++++++++++++++++++++++++++++------------------------------------
1 file changed, 50 insertions(+), 41 deletions(-)

diff --git a/src/day02.R b/src/day02.R @@ -1,3 +1,5 @@ +#!/usr/bin/env Rscript + source("src/utils.R") test_input <- "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124" @@ -7,73 +9,80 @@ parse_input <- function(input_string) { lapply(strsplit(strsplit(input_string, ",")[[1]], "-"), as.numeric) } -has_even_length <- function(num_string) { - nchar(num_string) %% 2 == 0 +stem_to_id <- function(id_stem, reps) { + sprintf("%d", id_stem) |> + rep(reps) |> + paste(collapse = "") |> + as.numeric() } -stem_to_id <- function(stem) { - as.numeric(sprintf("%d%d", stem, stem)) -} +ids_in_range_with_reps <- function(num_range, num_reps) { + ids_in_range_iter <- function(id_stem) { + id_num <- stem_to_id(id_stem, num_reps) -first_stem_after_start <- function(num_range) { - find_stem_after_start <- function(stem) { - if (stem_to_id(stem) >= num_range[[1]]) { - stem + if (id_num < num_range[[1]]) { + ids_in_range_iter(id_stem + 1) + } else if (id_num <= num_range[[2]]) { + c(id_num, ids_in_range_iter(id_stem + 1)) } else { - find_stem_after_start(stem + 1) + NULL } } - start_string <- as.character(num_range[[1]]) - if (has_even_length(start_string)) { - substr(start_string, 1, nchar(num_range[[1]]) / 2) |> - as.numeric() |> - find_stem_after_start() + start_str <- as.character(num_range[[1]]) + if (nchar(start_str) %% num_reps == 0) { + min_stem <- as.numeric( + substr(start_str, 1, nchar(start_str) / num_reps) + ) } else { - 10^(floor(nchar(start_string) / 2)) + min_stem <- 10^(ceiling(nchar(start_str) / num_reps) - 1) } + ids_in_range_iter(min_stem) } -is_stem_in_range <- function(stem, num_range) { - stem_repeated <- stem_to_id(stem) - (num_range[[1]] <= stem_repeated) && - (num_range[[2]] >= stem_repeated) +part1 <- function(input_string) { + input_string |> + parse_input() |> + lapply(\(x) ids_in_range_with_reps(x, 2)) |> + vapply(sum, numeric(1)) |> + sum() } -stems_in_range <- function(num_range) { - add_stems_to_list <- function(stem, stems_list) { - if (is_stem_in_range(stem, num_range)) { - add_stems_to_list(stem + 1, c(stems_list, stem)) - } else { - stems_list - } - } - add_stems_to_list(first_stem_after_start(num_range), NULL) +test_part1 <- function() { + stopifnot(part1(test_input) == 1227775554) } -safer_sum <- function(x) { - if (length(x) < 1) { - 0 - } else { - sum(x) +ids_in_range_all <- function(num_range) { + ids_in_range_rep_iter <- function(num_reps) { + if (num_reps > nchar(as.character(num_range[[2]]))) { + NULL + } else { + c( + ids_in_range_with_reps(num_range, num_reps), + ids_in_range_rep_iter(num_reps + 1) + ) + } } + unique(ids_in_range_rep_iter(2)) } -part1 <- function(input_string) { - input_ranges <- parse_input(input_string) - lapply(input_ranges, stems_in_range) |> - lapply(Vectorize(stem_to_id)) |> - vapply(safer_sum, numeric(1)) |> +part2 <- function(input_string) { + input_string |> + parse_input() |> + lapply(ids_in_range_all) |> + vapply(sum, numeric(1)) |> sum() } -test_part1 <- function() { - stopifnot(part1(test_input) == 1227775554) +test_part2 <- function() { + stopifnot(part2(test_input) == 4174379265) } main <- function() { test_part1() cat("Part 1 solution: ", part1(puzzle_input), "\n") + test_part2() + cat("Part 2 solution: ", part2(puzzle_input), "\n") } main()