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)
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])
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)
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])