R/day15.R

Defines functions example_data_15 f15_create_full_map f15b f15a

Documented in example_data_15 f15a f15b

#' Day 15: Chiton
#'
#' [Chiton](https://adventofcode.com/2021/day/15)
#'
#' @name day15
#' @rdname day15
#' @details
#'
#' **Part One**
#'
#' You\'ve almost reached the exit of the cave, but the walls are getting
#' closer together. Your submarine can barely still fit, though; the main
#' problem is that the walls of the cave are covered in
#' [chitons](https://en.wikipedia.org/wiki/Chiton), and it would be best
#' not to bump any of them.
#'
#' The cavern is large, but has a very low ceiling, restricting your motion
#' to two dimensions. The shape of the cavern resembles a square; a quick
#' scan of chiton density produces a map of *risk level* throughout the
#' cave (your puzzle input). For example:
#'
#'     1163751742
#'     1381373672
#'     2136511328
#'     3694931569
#'     7463417111
#'     1319128137
#'     1359912421
#'     3125421639
#'     1293138521
#'     2311944581
#'
#' You start in the top left position, your destination is the bottom right
#' position, and you [cannot move
#' diagonally]{title="Can't go diagonal until we can repair the caterpillar unit. Could be the liquid helium or the superconductors."}.
#' The number at each position is its *risk level*; to determine the total
#' risk of an entire path, add up the risk levels of each position you
#' *enter* (that is, don\'t count the risk level of your starting position
#' unless you enter it; leaving it adds no risk to your total).
#'
#' Your goal is to find a path with the *lowest total risk*. In this
#' example, a path with the lowest total risk is highlighted here:
#'
#'     1163751742
#'     1381373672
#'     2136511328
#'     3694931569
#'     7463417111
#'     1319128137
#'     1359912421
#'     3125421639
#'     1293138521
#'     2311944581
#'
#' The total risk of this path is `40` (the starting position is never
#' entered, so its risk is not counted).
#'
#' *What is the lowest total risk of any path from the top left to the
#' bottom right?*
#'
#' **Part Two**
#'
#' Now that you know how to find low-risk paths in the cave, you can try to
#' find your way out.
#'
#' The entire cave is actually *five times larger in both dimensions* than
#' you thought; the area you originally scanned is just one tile in a 5x5
#' tile area that forms the full map. Your original map tile repeats to the
#' right and downward; each time the tile repeats to the right or downward,
#' all of its risk levels *are 1 higher* than the tile immediately up or
#' left of it. However, risk levels above `9` wrap back around to `1`. So,
#' if your original map had some position with a risk level of `8`, then
#' that same position on each of the 25 total tiles would be as follows:
#'
#'     8 9 1 2 3
#'     9 1 2 3 4
#'     1 2 3 4 5
#'     2 3 4 5 6
#'     3 4 5 6 7
#'
#' Each single digit above corresponds to the example position with a value
#' of `8` on the top-left tile. Because the full map is actually five times
#' larger in both dimensions, that position appears a total of 25 times,
#' once in each duplicated tile, with the values shown above.
#'
#' Here is the full five-times-as-large version of the first example above,
#' with the original map in the top left corner highlighted:
#'
#'     11637517422274862853338597396444961841755517295286
#'     13813736722492484783351359589446246169155735727126
#'     21365113283247622439435873354154698446526571955763
#'     36949315694715142671582625378269373648937148475914
#'     74634171118574528222968563933317967414442817852555
#'     13191281372421239248353234135946434524615754563572
#'     13599124212461123532357223464346833457545794456865
#'     31254216394236532741534764385264587549637569865174
#'     12931385212314249632342535174345364628545647573965
#'     23119445813422155692453326671356443778246755488935
#'     22748628533385973964449618417555172952866628316397
#'     24924847833513595894462461691557357271266846838237
#'     32476224394358733541546984465265719557637682166874
#'     47151426715826253782693736489371484759148259586125
#'     85745282229685639333179674144428178525553928963666
#'     24212392483532341359464345246157545635726865674683
#'     24611235323572234643468334575457944568656815567976
#'     42365327415347643852645875496375698651748671976285
#'     23142496323425351743453646285456475739656758684176
#'     34221556924533266713564437782467554889357866599146
#'     33859739644496184175551729528666283163977739427418
#'     35135958944624616915573572712668468382377957949348
#'     43587335415469844652657195576376821668748793277985
#'     58262537826937364893714847591482595861259361697236
#'     96856393331796741444281785255539289636664139174777
#'     35323413594643452461575456357268656746837976785794
#'     35722346434683345754579445686568155679767926678187
#'     53476438526458754963756986517486719762859782187396
#'     34253517434536462854564757396567586841767869795287
#'     45332667135644377824675548893578665991468977611257
#'     44961841755517295286662831639777394274188841538529
#'     46246169155735727126684683823779579493488168151459
#'     54698446526571955763768216687487932779859814388196
#'     69373648937148475914825958612593616972361472718347
#'     17967414442817852555392896366641391747775241285888
#'     46434524615754563572686567468379767857948187896815
#'     46833457545794456865681556797679266781878137789298
#'     64587549637569865174867197628597821873961893298417
#'     45364628545647573965675868417678697952878971816398
#'     56443778246755488935786659914689776112579188722368
#'     55172952866628316397773942741888415385299952649631
#'     57357271266846838237795794934881681514599279262561
#'     65719557637682166874879327798598143881961925499217
#'     71484759148259586125936169723614727183472583829458
#'     28178525553928963666413917477752412858886352396999
#'     57545635726865674683797678579481878968159298917926
#'     57944568656815567976792667818781377892989248891319
#'     75698651748671976285978218739618932984172914319528
#'     56475739656758684176786979528789718163989182927419
#'     67554889357866599146897761125791887223681299833479
#'
#' Equipped with the full map, you can now find a path from the top left
#' corner to the bottom right corner with the lowest total risk:
#'
#'     11637517422274862853338597396444961841755517295286
#'     13813736722492484783351359589446246169155735727126
#'     21365113283247622439435873354154698446526571955763
#'     36949315694715142671582625378269373648937148475914
#'     74634171118574528222968563933317967414442817852555
#'     13191281372421239248353234135946434524615754563572
#'     13599124212461123532357223464346833457545794456865
#'     31254216394236532741534764385264587549637569865174
#'     12931385212314249632342535174345364628545647573965
#'     23119445813422155692453326671356443778246755488935
#'     22748628533385973964449618417555172952866628316397
#'     24924847833513595894462461691557357271266846838237
#'     32476224394358733541546984465265719557637682166874
#'     47151426715826253782693736489371484759148259586125
#'     85745282229685639333179674144428178525553928963666
#'     24212392483532341359464345246157545635726865674683
#'     24611235323572234643468334575457944568656815567976
#'     42365327415347643852645875496375698651748671976285
#'     23142496323425351743453646285456475739656758684176
#'     34221556924533266713564437782467554889357866599146
#'     33859739644496184175551729528666283163977739427418
#'     35135958944624616915573572712668468382377957949348
#'     43587335415469844652657195576376821668748793277985
#'     58262537826937364893714847591482595861259361697236
#'     96856393331796741444281785255539289636664139174777
#'     35323413594643452461575456357268656746837976785794
#'     35722346434683345754579445686568155679767926678187
#'     53476438526458754963756986517486719762859782187396
#'     34253517434536462854564757396567586841767869795287
#'     45332667135644377824675548893578665991468977611257
#'     44961841755517295286662831639777394274188841538529
#'     46246169155735727126684683823779579493488168151459
#'     54698446526571955763768216687487932779859814388196
#'     69373648937148475914825958612593616972361472718347
#'     17967414442817852555392896366641391747775241285888
#'     46434524615754563572686567468379767857948187896815
#'     46833457545794456865681556797679266781878137789298
#'     64587549637569865174867197628597821873961893298417
#'     45364628545647573965675868417678697952878971816398
#'     56443778246755488935786659914689776112579188722368
#'     55172952866628316397773942741888415385299952649631
#'     57357271266846838237795794934881681514599279262561
#'     65719557637682166874879327798598143881961925499217
#'     71484759148259586125936169723614727183472583829458
#'     28178525553928963666413917477752412858886352396999
#'     57545635726865674683797678579481878968159298917926
#'     57944568656815567976792667818781377892989248891319
#'     75698651748671976285978218739618932984172914319528
#'     56475739656758684176786979528789718163989182927419
#'     67554889357866599146897761125791887223681299833479
#'
#' The total risk of this path is `315` (the starting position is still
#' never entered, so its risk is not counted).
#'
#' Using the full map, *what is the lowest total risk of any path from the
#' top left to the bottom right?*
#'
#' @param x some data
#' @return For Part One, `f15a(x)` returns .... For Part Two,
#'   `f15b(x)` returns ....
#' @export
#' @examples
#' f15a(example_data_15())
#' f15b(example_data_15())
f15a <- function(x) {

  r <- raster::raster(x, xmn = 0, xmx = nrow(x), ymn = 0, ymx = ncol(x))
  tr <- gdistance::transition(r, function(x) 1/sum(x), 4)
  start <- c(nrow(x)-0.5, 0.5)
  end <- c(0.5, ncol(x) - 0.5)
  shortest_path <- gdistance::shortestPath(tr, start, end, output="SpatialLines")
  shortest_path_coords <- sp::coordinates(shortest_path)[[1]][[1]]

  # Convert from raster coords to standard matrix coords
  shortest_path_coords[, 2] <- nrow(x) - shortest_path_coords[, 2]
  shortest_path_coords <- shortest_path_coords[, c(2, 1)]
  shortest_path_coords <- shortest_path_coords + 0.5

  # Remove first step (as specified in instructions
  shortest_path_coords <- shortest_path_coords[-nrow(shortest_path_coords), ]

  return(sum(x[shortest_path_coords]))

}


#' @rdname day15
#' @export
f15b <- function(x) {

  f15a(f15_create_full_map(x))

}

f15_create_full_map <- function(x) {

  for (f in c("cbind", "rbind")) {
    tile <- x

    for (i in 1:4) {
      new_tile <- (tile + 1) %% 10
      new_tile[new_tile == 0] <- 1

      x <- do.call(f, list(x, new_tile))

      tile <- new_tile
    }
  }

  return(x)
}


#' @param example Which example data to use (by position or name). Defaults to
#'   1.
#' @rdname day15
#' @export
example_data_15 <- function(example = 1) {
  l <- list(
    a = matrix(nrow = 10, byrow = 10, c(
      1, 1, 6, 3, 7, 5, 1, 7, 4, 2,
      1, 3, 8, 1, 3, 7, 3, 6, 7, 2,
      2, 1, 3, 6, 5, 1, 1, 3, 2, 8,
      3, 6, 9, 4, 9, 3, 1, 5, 6, 9,
      7, 4, 6, 3, 4, 1, 7, 1, 1, 1,
      1, 3, 1, 9, 1, 2, 8, 1, 3, 7,
      1, 3, 5, 9, 9, 1, 2, 4, 2, 1,
      3, 1, 2, 5, 4, 2, 1, 6, 3, 9,
      1, 2, 9, 3, 1, 3, 8, 5, 2, 1,
      2, 3, 1, 1, 9, 4, 4, 5, 8, 1
    ))
  )
  l[[example]]
}
Bisaloo/adventofcode21 documentation built on Dec. 17, 2021, 11:48 a.m.