Categories
#rstats

Advent of Code 2017 in #rstats: Day 9

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

 

Leave a Reply

Your email address will not be published. Required fields are marked *