See more puzzles

Advent of Code

Session information

sessionInfo()

Brief

Somehow, a network packet got lost and ended up here. It’s trying to follow a routing diagram (your puzzle input), but it’s confused about where to go.

Its starting point is just off the top of the diagram. Lines (drawn with |, -, and +) show the path it needs to take, starting by going down onto the only line connected to the top of the diagram. It needs to follow this path until it reaches the end (located somewhere within the diagram) and stop there.

Sometimes, the lines cross over each other; in these cases, it needs to continue going the same direction, and only turn left or right when there’s no other option. In addition, someone has left letters on the line; these also don’t change its direction, but it can use them to keep track of where it’s been. For example:

     |          
     |  +--+    
     A  |  C    
 F---|----E|--+ 
     |  |  |  D 
     +B-+  +--+ 

Given this diagram, the packet needs to take the following path:

Starting at the only line touching the top of the diagram, it must go down, pass through A, and continue onward to the first +.

Travel right, up, and right, passing through B in the process.

Continue down (collecting C), right, and up (collecting D).

Finally, go all the way left through E and stopping at F.

Following the path to the end, the letters it sees on its path are ABCDEF.

The little packet looks up at you, hoping you can help it find the way. What letters will it see (in the order it would see them) if it follows the path? (The routing diagram is very wide; make sure you view it without line wrapping.)

Let’s go

Packages & functions

library(tidyverse)
library(testthat)
library(aocodeR)

Input

input <- aoc_get_input(day = 19, cookie_path = paste0(rprojroot::find_rstudio_root_file(),
                                                 "/secrets/session_cookie.txt")) %>% 
    strsplit(., "\n") %>% unlist
input %>% head()
[1] "|                                                                                                                             "                                                                           
[2] "     +-+         +---+   +---+   +-----------------------------------------|---+                                             +---+ +-------------------------------------+         +-------------------+ "
[3] "     | |         |   |   |   |   |                                         |   |                                             |   | |                                     |         |                   | "
[4] " +-------------------|-------|-------------+                           +---|-------------------------------+                 |   +---------------------------------+     |         |                   | "
[5] " |   | |         |   |   |   |   |         |                           |   |   |                           |                 |     |                               |     |         |                   | "
[6] " |   | |         |   +---|---|---|---------|---------------------+     |   |   |                           |                 |     |   +---+                       |     |         |                   | "

Functions

library(prodlim)
input_to_m <- function(input){
    m_i <- input %>% strsplit(., numeric()) %>% map(~ pad_row(.x)) %>% do.call("rbind", .)
    m <- matrix(" ", nrow = nrow(m_i) + 2, ncol = ncol(m_i) + 2)
    m[2:(1 + nrow(m_i)), 2:(1 + ncol(m_i))] <- m_i
    m
}
pad_row <- function(x){
    if(length(x) < 201){
        p <- rep(" ", 201 - length(x))
        if(x[1] != " "){x <- c(p, x)}else{
            x <- c(x, p) 
        }
    }
    x
}
start <- function(m) {
  mv$loc <- c(2, which(m[2,] == "|")) 
  mv$move <- c(1, 0)
  mv$trace <- NULL
  mv$end <- F
  mv$moves <- 1
}
move <- function(m, return = "trace") {
    next_loc <- mv$loc + mv$move
    next_val <- m[next_loc[1], next_loc[2]]
    
    while(next_val != " ") {
        if(grepl("[A-Z]", next_val)){
            mv$trace <- paste0(mv$trace, next_val)
        }
        mv$loc <- next_loc
        next_loc <- next_loc + mv$move
        mv$moves <- mv$moves + 1
        next_val <- m[next_loc[1], next_loc[2]]
    }
    scan_next(m)
    if(mv$end){return(mv[[return]])}else{move(m, return)}
}
scan_next <- function(m){
    moves <- matrix(c(0,0,-1,1, -1,1,0,0), ncol = 2)
    scan_locs <- moves[-prodlim::row.match(mv$move * -1, moves),]
    r <- which(m[t(t(scan_locs) + mv$loc)] != " ")
    if(length(r) == 0){mv$end <- T
    }else{
        mv$move <- scan_locs[r,]}
}

deploy

m <- input_to_m(input)
mv <- new.env(parent = emptyenv())
start(m)
move(m)
[1] "DTOUFARJQ"

Success!



—- Part 2 —-

Brief

Let’s go

Test

#expect_equal(,)

deploy

m <- input_to_m(input)
mv <- new.env(parent = emptyenv())
start(m)
move(m, return = "moves")
[1] 16642

Success!



template based on the workflowr standalone template

LS0tCnRpdGxlOiAiLS0tIERheSAxOTogQSBTZXJpZXMgb2YgVHViZXMgLS0tIgphdXRob3I6ICJhbm5ha3J5c3RhbGxpIgpkYXRlOiAyMDE3LTEyLTE5Cm91dHB1dDogaHRtbF9ub3RlYm9vawplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYHtyIGtuaXRyLW9wdHMtY2h1bmssIGluY2x1ZGU9RkFMU0V9CiMgVXBkYXRlIGtuaXRyIGNodW5rIG9wdGlvbnMKIyBodHRwczovL3lpaHVpLm5hbWUva25pdHIvb3B0aW9ucy8jY2h1bmstb3B0aW9ucwprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgY29tbWVudCA9IE5BLAogIGZpZy5hbGlnbiA9ICJjZW50ZXIiLAogIHRpZHkgPSBGQUxTRSwKICBmaWcucGF0aCA9IHBhc3RlMCgiZmlndXJlLyIsIGtuaXRyOjpjdXJyZW50X2lucHV0KCksICIvIikKKQpgYGAKCmBgYHtyIGxhc3QtdXBkYXRlZCwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CiMgSW5zZXJ0IHRoZSBkYXRlIHRoZSBmaWxlIHdhcyBsYXN0IHVwZGF0ZWQKY2F0KHNwcmludGYoIioqTGFzdCB1cGRhdGVkOioqICVzIiwgU3lzLkRhdGUoKSkpCmBgYAoKYGBge3IgY29kZS12ZXJzaW9uLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30KIyBJbnNlcnQgdGhlIGNvZGUgdmVyc2lvbiAoR2l0IGNvbW1pdCBTSEExKSBpZiBHaXQgcmVwb3NpdG9yeSBleGlzdHMgYW5kIFIKIyBwYWNrYWdlIGdpdDJyIGlzIGluc3RhbGxlZAppZihyZXF1aXJlTmFtZXNwYWNlKCJnaXQyciIsIHF1aWV0bHkgPSBUUlVFKSkgewogIGlmKGdpdDJyOjppbl9yZXBvc2l0b3J5KCkpIHsKICAgIGNvZGVfdmVyc2lvbiA8LSBzdWJzdHIoZ2l0MnI6OmNvbW1pdHMoKVtbMV1dQHNoYSwgMSwgNykKICB9IGVsc2UgewogICAgY29kZV92ZXJzaW9uIDwtICJVbmF2YWlsYWJsZS4gSW5pdGlhbGl6ZSBHaXQgcmVwb3NpdG9yeSB0byBlbmFibGUuIgogIH0KfSBlbHNlIHsKICBjb2RlX3ZlcnNpb24gPC0gIlVuYXZhaWxhYmxlLiBJbnN0YWxsIGdpdDJyIHBhY2thZ2UgdG8gZW5hYmxlLiIKfQpjYXQoc3ByaW50ZigiKipDb2RlIHZlcnNpb246KiogJXMiLCBjb2RlX3ZlcnNpb24pKQpybShjb2RlX3ZlcnNpb24pCmBgYAoKCj4gWyoqKlNlZSBtb3JlIHB1enpsZXMqKipdKGh0dHA6Ly9hbm5ha3J5c3RhbGxpLm1lL2FkdmVudF9vZl9jb2RlLykKClsqKkFkdmVudCBvZiBDb2RlKipdKGh0dHBzOi8vYWR2ZW50b2Zjb2RlLmNvbS8yMDE3LykKCgojIyBTZXNzaW9uIGluZm9ybWF0aW9uCgo8IS0tIEluc2VydCB0aGUgc2Vzc2lvbiBpbmZvcm1hdGlvbiBpbnRvIHRoZSBkb2N1bWVudCAtLT4KYGBge3Igc2Vzc2lvbi1pbmZvfQpzZXNzaW9uSW5mbygpCmBgYAoKCiMjIEJyaWVmCgo8IS0tIEluc2VydCBQYXJ0IDEgb2YgdGhlIHB1enpsZSBicmllZiBoZXJlIC0tPgoKU29tZWhvdywgYSBuZXR3b3JrIHBhY2tldCBnb3QgbG9zdCBhbmQgZW5kZWQgdXAgaGVyZS4gSXQncyB0cnlpbmcgdG8gZm9sbG93IGEgcm91dGluZyBkaWFncmFtICh5b3VyIHB1enpsZSBpbnB1dCksIGJ1dCBpdCdzIGNvbmZ1c2VkIGFib3V0IHdoZXJlIHRvIGdvLgoKSXRzIHN0YXJ0aW5nIHBvaW50IGlzIGp1c3Qgb2ZmIHRoZSB0b3Agb2YgdGhlIGRpYWdyYW0uIExpbmVzIChkcmF3biB3aXRoIHwsIC0sIGFuZCArKSBzaG93IHRoZSBwYXRoIGl0IG5lZWRzIHRvIHRha2UsIHN0YXJ0aW5nIGJ5IGdvaW5nIGRvd24gb250byB0aGUgb25seSBsaW5lIGNvbm5lY3RlZCB0byB0aGUgdG9wIG9mIHRoZSBkaWFncmFtLiBJdCBuZWVkcyB0byBmb2xsb3cgdGhpcyBwYXRoIHVudGlsIGl0IHJlYWNoZXMgdGhlIGVuZCAobG9jYXRlZCBzb21ld2hlcmUgd2l0aGluIHRoZSBkaWFncmFtKSBhbmQgc3RvcCB0aGVyZS4KClNvbWV0aW1lcywgdGhlIGxpbmVzIGNyb3NzIG92ZXIgZWFjaCBvdGhlcjsgaW4gdGhlc2UgY2FzZXMsIGl0IG5lZWRzIHRvIGNvbnRpbnVlIGdvaW5nIHRoZSBzYW1lIGRpcmVjdGlvbiwgYW5kIG9ubHkgdHVybiBsZWZ0IG9yIHJpZ2h0IHdoZW4gdGhlcmUncyBubyBvdGhlciBvcHRpb24uIEluIGFkZGl0aW9uLCBzb21lb25lIGhhcyBsZWZ0IGxldHRlcnMgb24gdGhlIGxpbmU7IHRoZXNlIGFsc28gZG9uJ3QgY2hhbmdlIGl0cyBkaXJlY3Rpb24sIGJ1dCBpdCBjYW4gdXNlIHRoZW0gdG8ga2VlcCB0cmFjayBvZiB3aGVyZSBpdCdzIGJlZW4uIEZvciBleGFtcGxlOgoKYGBgCiAgICAgfCAgICAgICAgICAKICAgICB8ICArLS0rICAgIAogICAgIEEgIHwgIEMgICAgCiBGLS0tfC0tLS1FfC0tKyAKICAgICB8ICB8ICB8ICBEIAogICAgICtCLSsgICstLSsgCmBgYAoKR2l2ZW4gdGhpcyBkaWFncmFtLCB0aGUgcGFja2V0IG5lZWRzIHRvIHRha2UgdGhlIGZvbGxvd2luZyBwYXRoOgoKU3RhcnRpbmcgYXQgdGhlIG9ubHkgbGluZSB0b3VjaGluZyB0aGUgdG9wIG9mIHRoZSBkaWFncmFtLCBpdCBtdXN0IGdvIGRvd24sIHBhc3MgdGhyb3VnaCBgQWAsIGFuZCBjb250aW51ZSBvbndhcmQgdG8gdGhlIGZpcnN0IGArYC4KClRyYXZlbCByaWdodCwgdXAsIGFuZCByaWdodCwgcGFzc2luZyB0aHJvdWdoIGBCYCBpbiB0aGUgcHJvY2Vzcy4KCkNvbnRpbnVlIGRvd24gKGNvbGxlY3RpbmcgYENgKSwgcmlnaHQsIGFuZCB1cCAoY29sbGVjdGluZyBgRGApLgoKRmluYWxseSwgZ28gYWxsIHRoZSB3YXkgbGVmdCB0aHJvdWdoIGBFYCBhbmQgc3RvcHBpbmcgYXQgYEZgLgoKRm9sbG93aW5nIHRoZSBwYXRoIHRvIHRoZSBlbmQsIHRoZSBsZXR0ZXJzIGl0IHNlZXMgb24gaXRzIHBhdGggYXJlIGBBQkNERUZgLgoKVGhlIGxpdHRsZSBwYWNrZXQgbG9va3MgdXAgYXQgeW91LCBob3BpbmcgeW91IGNhbiBoZWxwIGl0IGZpbmQgdGhlIHdheS4gV2hhdCBsZXR0ZXJzIHdpbGwgaXQgc2VlIChpbiB0aGUgb3JkZXIgaXQgd291bGQgc2VlIHRoZW0pIGlmIGl0IGZvbGxvd3MgdGhlIHBhdGg/IChUaGUgcm91dGluZyBkaWFncmFtIGlzIHZlcnkgd2lkZTsgbWFrZSBzdXJlIHlvdSB2aWV3IGl0IHdpdGhvdXQgbGluZSB3cmFwcGluZy4pCgoKCiMgTGV0J3MgZ28KCiMjIyBQYWNrYWdlcyAmIGZ1bmN0aW9ucwpgYGB7ciwgbWVzc2FnZSA9IEZ9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRlc3R0aGF0KQpsaWJyYXJ5KGFvY29kZVIpCmBgYAoKCiMjIElucHV0Cgo8IS0tIFN1cHBseSBkYXkuIGNvb2tpZV9wYXRoIGRlZmF1bHRzIHRvIHBhdGggaW4gbXkgcHJvamVjdCAtLT4KYGBge3J9CmlucHV0IDwtIGFvY19nZXRfaW5wdXQoZGF5ID0gMTksIGNvb2tpZV9wYXRoID0gcGFzdGUwKHJwcm9qcm9vdDo6ZmluZF9yc3R1ZGlvX3Jvb3RfZmlsZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi9zZWNyZXRzL3Nlc3Npb25fY29va2llLnR4dCIpKSAlPiUgCiAgICBzdHJzcGxpdCguLCAiXG4iKSAlPiUgdW5saXN0CgppbnB1dCAlPiUgaGVhZCgpCmBgYAoKIyMgRnVuY3Rpb25zCmBgYHtyfQpsaWJyYXJ5KHByb2RsaW0pCgppbnB1dF90b19tIDwtIGZ1bmN0aW9uKGlucHV0KXsKICAgIG1faSA8LSBpbnB1dCAlPiUgc3Ryc3BsaXQoLiwgbnVtZXJpYygpKSAlPiUgbWFwKH4gcGFkX3JvdygueCkpICU+JSBkby5jYWxsKCJyYmluZCIsIC4pCiAgICBtIDwtIG1hdHJpeCgiICIsIG5yb3cgPSBucm93KG1faSkgKyAyLCBuY29sID0gbmNvbChtX2kpICsgMikKICAgIG1bMjooMSArIG5yb3cobV9pKSksIDI6KDEgKyBuY29sKG1faSkpXSA8LSBtX2kKICAgIG0KfQoKcGFkX3JvdyA8LSBmdW5jdGlvbih4KXsKICAgIGlmKGxlbmd0aCh4KSA8IDIwMSl7CiAgICAgICAgcCA8LSByZXAoIiAiLCAyMDEgLSBsZW5ndGgoeCkpCiAgICAgICAgaWYoeFsxXSAhPSAiICIpe3ggPC0gYyhwLCB4KX1lbHNlewogICAgICAgICAgICB4IDwtIGMoeCwgcCkgCiAgICAgICAgfQogICAgfQogICAgeAp9CgpzdGFydCA8LSBmdW5jdGlvbihtKSB7CiAgbXYkbG9jIDwtIGMoMiwgd2hpY2gobVsyLF0gPT0gInwiKSkgCiAgbXYkbW92ZSA8LSBjKDEsIDApCiAgbXYkdHJhY2UgPC0gTlVMTAogIG12JGVuZCA8LSBGCiAgbXYkbW92ZXMgPC0gMQp9Cgptb3ZlIDwtIGZ1bmN0aW9uKG0sIHJldHVybiA9ICJ0cmFjZSIpIHsKICAgIG5leHRfbG9jIDwtIG12JGxvYyArIG12JG1vdmUKICAgIG5leHRfdmFsIDwtIG1bbmV4dF9sb2NbMV0sIG5leHRfbG9jWzJdXQogICAgCiAgICB3aGlsZShuZXh0X3ZhbCAhPSAiICIpIHsKICAgICAgICBpZihncmVwbCgiW0EtWl0iLCBuZXh0X3ZhbCkpewogICAgICAgICAgICBtdiR0cmFjZSA8LSBwYXN0ZTAobXYkdHJhY2UsIG5leHRfdmFsKQogICAgICAgIH0KICAgICAgICBtdiRsb2MgPC0gbmV4dF9sb2MKICAgICAgICBuZXh0X2xvYyA8LSBuZXh0X2xvYyArIG12JG1vdmUKICAgICAgICBtdiRtb3ZlcyA8LSBtdiRtb3ZlcyArIDEKICAgICAgICBuZXh0X3ZhbCA8LSBtW25leHRfbG9jWzFdLCBuZXh0X2xvY1syXV0KICAgIH0KICAgIHNjYW5fbmV4dChtKQogICAgaWYobXYkZW5kKXtyZXR1cm4obXZbW3JldHVybl1dKX1lbHNle21vdmUobSwgcmV0dXJuKX0KfQoKc2Nhbl9uZXh0IDwtIGZ1bmN0aW9uKG0pewogICAgbW92ZXMgPC0gbWF0cml4KGMoMCwwLC0xLDEsIC0xLDEsMCwwKSwgbmNvbCA9IDIpCiAgICBzY2FuX2xvY3MgPC0gbW92ZXNbLXByb2RsaW06OnJvdy5tYXRjaChtdiRtb3ZlICogLTEsIG1vdmVzKSxdCiAgICByIDwtIHdoaWNoKG1bdCh0KHNjYW5fbG9jcykgKyBtdiRsb2MpXSAhPSAiICIpCiAgICBpZihsZW5ndGgocikgPT0gMCl7bXYkZW5kIDwtIFQKICAgIH1lbHNlewogICAgICAgIG12JG1vdmUgPC0gc2Nhbl9sb2NzW3IsXX0KfQpgYGAKCiMjIGRlcGxveQoKYGBge3J9Cm0gPC0gaW5wdXRfdG9fbShpbnB1dCkKbXYgPC0gbmV3LmVudihwYXJlbnQgPSBlbXB0eWVudigpKQpzdGFydChtKQptb3ZlKG0pCmBgYAoKCiMjIFN1Y2Nlc3MhCgohW10oLi4vc2NyZWVuc2hvdHMvRGF5MV8xLnBuZykKCjxicj4KCioqKgoKIyAtLS0tIFBhcnQgMiAtLS0tCgoKIyMgQnJpZWYKPCEtLSBJbnNlcnQgUGFydCAyIG9mIHRoZSBwdXp6bGUgYnJpZWYgaGVyZSAtLT4KCgojIExldCdzIGdvCgojIyBUZXN0CmBgYHtyfQojZXhwZWN0X2VxdWFsKCwpCmBgYAoKIyMgZGVwbG95CgpgYGB7cn0KbSA8LSBpbnB1dF90b19tKGlucHV0KQptdiA8LSBuZXcuZW52KHBhcmVudCA9IGVtcHR5ZW52KCkpCnN0YXJ0KG0pCm1vdmUobSwgcmV0dXJuID0gIm1vdmVzIikKYGBgCgojIyBTdWNjZXNzIQoKIVtdKC4uL3NjcmVlbnNob3RzL0RheTFfMi5wbmcpCgo8YnI+CgoqKioKCnRlbXBsYXRlIGJhc2VkIG9uIHRoZSBbd29ya2Zsb3dyXShodHRwczovL2dpdGh1Yi5jb20vamRibGlzY2hhay93b3JrZmxvd3IpIHN0YW5kYWxvbmUgdGVtcGxhdGUK