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

day07.R (1997B)


      1 #!/usr/bin/env Rscript
      2 
      3 source("src/utils.R")
      4 
      5 test_input <- c(
      6   ".......S.......",
      7   "...............",
      8   ".......^.......",
      9   "...............",
     10   "......^.^......",
     11   "...............",
     12   ".....^.^.^.....",
     13   "...............",
     14   "....^.^...^....",
     15   "...............",
     16   "...^.^...^.^...",
     17   "...............",
     18   "..^...^.....^..",
     19   "...............",
     20   ".^.^.^.^.^...^.",
     21   "..............."
     22 )
     23 puzzle_input <- aoc_input(7)
     24 
     25 parse_input <- function(input_lines) {
     26   input_lines |>
     27     strsplit("", fixed = TRUE) |>
     28     (\(x) do.call(rbind, x))()
     29 }
     30 
     31 lshift <- function(x, fill = vector(mode = class(x), length = 1)) {
     32   c(x[2:length(x)], fill)
     33 }
     34 
     35 rshift <- function(x, fill = vector(mode = class(x), length = 1)) {
     36   c(fill, x[1:(length(x) - 1)])
     37 }
     38 
     39 trace_beams_one_step <- function(manifold_row, beams_in) {
     40   # This returns the number of splits as well as the updated beams in order to
     41   # solve part 1
     42   splits <- (manifold_row == "^") * beams_in
     43   list(
     44     num_splits = sum(splits > 0),
     45     beams_out = (manifold_row == "S") + ((manifold_row == ".") * beams_in) +
     46       lshift(splits) + rshift(splits)
     47   )
     48 }
     49 
     50 trace_beams <- function(manifold) {
     51   num_splits <- 0
     52   beams <- rep(0.0, ncol(manifold))
     53   for (i in seq_len(nrow(manifold))) {
     54     res <- trace_beams_one_step(manifold[i, ], beams)
     55     num_splits <- num_splits + res$num_splits
     56     beams <- res$beams_out
     57   }
     58   list(num_splits = num_splits, beams_out = beams)
     59 }
     60 
     61 part1 <- function(input_lines) {
     62   trace_beams(parse_input(input_lines))$num_splits
     63 }
     64 
     65 test_part1 <- function() {
     66   stopifnot(part1(test_input) == 21)
     67 }
     68 
     69 part2 <- function(input_lines) {
     70   sum(trace_beams(parse_input(input_lines))$beams_out)
     71 }
     72 
     73 test_part2 <- function() {
     74   stopifnot(part2(test_input) == 40)
     75 }
     76 
     77 main <- function() {
     78   # It's not remotely efficient to solve the puzzle twice, but it's fine
     79   test_part1()
     80   cat("Part 1 solution: ", part1(puzzle_input), "\n")
     81   test_part2()
     82   cat(sprintf("Part 2 solution: %0.0f\n", part2(puzzle_input)))
     83 }
     84 
     85 main()