Day 01

Author

Hendrik Wagenseil

Data

Load and preview the data set.

y = "2023"
d = "01"

ifl = file.path(
  here::here()
  , y
  , "data"
  , paste0(y, "-day", d, "input")
)

txt = readLines(ifl)

head(txt, n = 12L)
 [1] "nine92jnhgqzctpgbcbpz"             "sevensddvc73three"                
 [3] "9986fmfqhdmq8"                     "7onexmxbzllfqb"                   
 [5] "six777"                            "1zbngsixxrfrpr"                   
 [7] "threeeight9seven"                  "nhds975three6"                    
 [9] "ninepgp9"                          "22fourninetzfourfsnxjglthreeeight"
[11] "mhcvqmsg7bdj"                      "seven67"                          

Part I

For each element in the given vector of characters do:

  • extract the first and the last digit
  • concatenate to a new number
  • calculate the sum

Approach:

  • get indices of all digits per element using gregexpr
  • get the first and last digit using range
  • extract the first and last digits using substtr
  • create the new number and calculate the sum
l = gregexpr("[[:digit:]]", text = txt) |> 
  lapply(FUN = range) 

mapply(
  \(t, f){
    paste0(
      substr(t, f[1], f[1])
      , substr(t, f[2], f[2])
    ) |> 
      as.numeric()
  }
  , t = txt
  , f = l
  , SIMPLIFY = FALSE
) |> 
  unname() |> 
  unlist() |> 
  sum(na.rm = TRUE)
[1] 54601

Approach:

  • extract all digits from a string using list comprehension
  • get the first and last digit by index and concatenate
  • calculate the sum
def getdigits(x: str):
  digit = [i for i in x if i.isdigit()]
  digit = digit[0] + digit[-1]
  return int(digit)

sum([getdigits(i) for i in r.txt])
54601

Part II

The task is the same as in part I, but in addition to digits, also written numbers (one, two, three, …) shall be considered.

Approach:

  • replace the second character of any written numbers with their digit (e.g.  one -> o1e, two -> t2o, …)
  • replacing the entire string would cause issues in case of adjacent written numbers like oneight, sevenine
  • apply the approach from part I
fromto = c(
  'one' = 'o1e'
  , 'two' = 't2o'
  , 'three' = 't3ree'
  , 'four' = 'f4ur'
  , 'five' = 'f5ve'
  , 'six' = 's6x'
  , 'seven' = 's7ven'
  , 'eight' = 'e8ght'
  , 'nine' = 'n9ne'
)

txt_digits = Map(
  stringi::stri_replace_all_fixed
  , str = txt
  , pattern = list(names(fromto))
  , replacement = list(fromto)
  , vectorize_all = FALSE
) |> 
  unlist() |> 
  unname()

l = gregexpr("[[:digit:]]", text = txt_digits) |> 
  lapply(FUN = range) 

mapply(
  \(t, f){
    paste0(
      substr(t, f[1], f[1])
      , substr(t, f[2], f[2])
    ) |> 
      as.numeric()
  }
  , t = txt_digits
  , f = l
  , SIMPLIFY = FALSE
) |> 
  unname() |> 
  unlist() |> 
  sum(na.rm = TRUE)
[1] 54078
fromto = {
  'one': 'o1e'
  , 'two': 't2o'
  , 'three': 't3ree'
  , 'four': 'f4ur'
  , 'five': 'f5ve'
  , 'six': 's6x'
  , 'seven': 's7ven'
  , 'eight': 'e8ght'
  , 'nine': 'n9ne'
}

def digitstring2digit(x: str, dic: dict):
  for i, k in enumerate(dic):
    x = x.replace(k, dic[k])
  return x

txt_digits = [digitstring2digit(i, fromto) for i in r.txt]    

sum([getdigits(i) for i in txt_digits])
54078