day08.R (2477B)
1 #!/usr/bin/env Rscript 2 3 source("src/utils.R") 4 5 test_input <- c( 6 "162,817,812", 7 "57,618,57", 8 "906,360,560", 9 "592,479,940", 10 "352,342,300", 11 "466,668,158", 12 "542,29,236", 13 "431,825,988", 14 "739,650,466", 15 "52,470,668", 16 "216,146,977", 17 "819,987,18", 18 "117,168,530", 19 "805,96,715", 20 "346,949,466", 21 "970,615,88", 22 "941,993,340", 23 "862,61,35", 24 "984,92,344", 25 "425,690,689" 26 ) 27 puzzle_input <- aoc_input(8) 28 29 parse_input <- function(input_lines) { 30 input_lines |> 31 strsplit(",") |> 32 lapply(as.numeric) |> 33 (\(x) do.call(rbind, x))() 34 } 35 36 order_distances <- function(distmat) { 37 # Put the pairs from the distance matrix in increasing order 38 which(lower.tri(distmat), arr.ind = TRUE)[order(distmat), ] 39 } 40 41 greedy_connect <- function(coords, max_steps = NULL) { 42 # Circuit IDs for each junction box 43 coord_circuits <- seq_len(nrow(coords)) 44 # Junction box (coordinate) IDs for each circuit 45 circuit_coords <- as.list(seq_along(coord_circuits)) 46 47 pair_order <- coords |> 48 dist() |> 49 order_distances() 50 51 max_steps <- min(max_steps, nrow(pair_order)) 52 for (i in seq_len(max_steps)) { 53 c1 <- coord_circuits[pair_order[i, 1]] 54 c2 <- coord_circuits[pair_order[i, 2]] 55 if (c1 < c2) { 56 coord_circuits[circuit_coords[[c2]]] <- c1 57 circuit_coords[[c1]] <- union(circuit_coords[[c1]], circuit_coords[[c2]]) 58 circuit_coords[c2] <- list(NULL) 59 if (length(circuit_coords[[c1]]) == nrow(coords)) break 60 } else if (c1 > c2) { 61 coord_circuits[circuit_coords[[c1]]] <- c2 62 circuit_coords[[c2]] <- union(circuit_coords[[c1]], circuit_coords[[c2]]) 63 circuit_coords[c1] <- list(NULL) 64 if (length(circuit_coords[[c2]]) == nrow(coords)) break 65 } 66 } 67 68 list(circuits = circuit_coords, last_pair = pair_order[i, ]) 69 } 70 71 part1 <- function(input_lines, steps) { 72 input_lines |> 73 parse_input() |> 74 (\(x) greedy_connect(x, steps)$circuits)() |> 75 vapply(length, integer(1)) |> 76 sort(decreasing = TRUE) |> 77 (\(x) prod(x[1:3]))() 78 } 79 80 test_part1 <- function() { 81 stopifnot(part1(test_input, 10) == 40) 82 } 83 84 part2 <- function(input_lines) { 85 coords <- parse_input(input_lines) 86 last_pair <- greedy_connect(coords)$last_pair 87 88 prod(coords[last_pair, ][, 1]) 89 } 90 91 test_part2 <- function() { 92 stopifnot(part2(test_input) == 25272) 93 } 94 95 main <- function() { 96 test_part1() 97 cat("Part 1 solution: ", part1(puzzle_input, 1000), "\n") 98 test_part2() 99 cat("Part 2 solution: ", part2(puzzle_input), "\n") 100 } 101 102 main()