day04.R (2055B)
1 #!/usr/bin/env Rscript 2 3 source("src/utils.R") 4 5 test_input <- c( 6 "..@@.@@@@.", 7 "@@@.@.@.@@", 8 "@@@@@.@.@@", 9 "@.@@@@..@.", 10 "@@.@@@@.@@", 11 ".@@@@@@@.@", 12 ".@.@.@.@@@", 13 "@.@@@.@@@@", 14 ".@@@@@@@@.", 15 "@.@.@@@.@." 16 ) 17 puzzle_input <- aoc_input(4) 18 19 parse_input <- function(input_lines) { 20 input_lines |> 21 strsplit("", fixed = TRUE) |> 22 (\(x) matrix(unlist(x), nrow = length(x), byrow = TRUE))() 23 } 24 25 count_neighbors <- function(diagram) { 26 nc <- ncol(diagram) 27 nr <- nrow(diagram) 28 neighbors <- matrix(0, nrow = nr, ncol = nc) 29 is_occupied <- ifelse(diagram == "@", 1, 0) 30 31 # shift = -1: 1 to nr-1 |-> 2 to nr-0 32 # shift = +1: 2 to nr-0 |-> 1 to nr-1 33 # shift = 0: 1 to nr-0 |-> 1 to nr-0 34 for (r_shift in (-1:1)) { 35 for (c_shift in (-1:1)) { 36 if (r_shift != 0 || c_shift != 0) { 37 neighbors[(1 + max(0, r_shift)):(nr + min(0, r_shift)), (1 + max(0, c_shift)):(nc + min(0, c_shift))] <- 38 neighbors[(1 + max(0, r_shift)):(nr + min(0, r_shift)), (1 + max(0, c_shift)):(nc + min(0, c_shift))] + 39 is_occupied[(1 - min(0, r_shift)):(nr - max(0, r_shift)), (1 - min(0, c_shift)):(nc - max(0, c_shift))] 40 } 41 } 42 } 43 neighbors 44 } 45 46 mark_moveable <- function(diagram) { 47 (diagram == "@") & (count_neighbors(diagram) < 4) 48 } 49 50 part1 <- function(input_lines) { 51 input_lines |> 52 parse_input() |> 53 mark_moveable() |> 54 sum() 55 } 56 57 test_part1 <- function() { 58 stopifnot(part1(test_input) == 13) 59 } 60 61 count_moveable <- function(diagram) { 62 total_moved <- 0 63 repeat { 64 moveable <- mark_moveable(diagram) 65 moveable_count <- sum(moveable) 66 if (moveable_count == 0) break 67 total_moved <- total_moved + moveable_count 68 diagram[moveable] <- "." 69 } 70 total_moved 71 } 72 73 part2 <- function(input_lines) { 74 input_lines |> 75 parse_input() |> 76 count_moveable() 77 } 78 79 test_part2 <- function() { 80 stopifnot(part2(test_input) == 43) 81 } 82 83 main <- function() { 84 test_part1() 85 cat("Part 1 solution: ", part1(puzzle_input), "\n") 86 test_part2() 87 cat("Part 2 solution: ", part2(puzzle_input), "\n") 88 } 89 90 main()