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:
| M | src/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()