I write less deeply-nested code now that I program in R. When writing code poorly in other programs, I’d often use nested IF statements (hi, Excel!). Debugging that often looked like counting my nesting depth out loud: add one for every (
, subtract one for every )
.
That strategy formed the basis for my solution today. And I was excited to do Part 2 with arithmetic, not writing new code.
Part 1
Strategy: maintain counter of open braces, decreasing for closed braces.
So `{{<a>},{<a>},{<a>},{<a>}}` = 1 2 2 2 2. Sum = 9.
library(pacman) p_load(stringr, testthat) # cancel the character after ! cancel_chars <- function(x){ gsub("!.", "", x) } group_score <- function(dat){ clean <- gsub("<.*?>", "" , dat) # non-greedy regex to remove garbage lvl <- 1 # depth of braces nesting counts <- rep(0, nchar(clean)) # default value for non-{ characters for(i in seq.int(nchar(counts))){ if(str_sub(clean, i, i) == "{"){ # log the nested depth and increment counter counts[i] <- counts[i] + lvl lvl <- lvl + 1 } if(str_sub(clean, i, i) == "}"){ lvl <- lvl - 1 } } sum(counts) } # Test expect_equal(group_score("{{{}}}"), 6) expect_equal(group_score("{{},{}}"), 5) expect_equal(group_score("{{{},{},{{}}}}"), 16) dat <- scan("09_1_dat.txt", "character") group_score(cancel_chars(dat)) # 15922
Part 2
The answer is the total number of characters, minus:
- The characters canceled by
!
- The bracketing `<>` for each garbage string
- The valid characters remaining after removing the garbage in Part 1
To wit:
cleaned <- cancel_chars(dat) nchar(cleaned) - 2*str_count(string = cleaned, pattern = fixed(">")) - nchar(gsub("<.*?>", "" , cleaned)) # 7314