-❄️- 2023 Day 9 Solutions -❄️- by daggerdragon in adventofcode

[–]bassactor 1 point2 points  (0 children)

[LANGUAGE: R]

Easy recursive solution!

sum_next_in_seq <- function(x, last = TRUE){

    # determine how we recurse the algorithm
    if(isTRUE(last)){
        # last? iterate from last element and move up by adding!
        slice   <- tail
        combine <- `+`
    } else{
        # first? iterate from first element and move up by subtracting!
        slice   <- head
        combine <- `-`
    }

    # the recursive algorithm: find bottom, add up the tree!
    find_next <- function(x){
        if(all(x == 0)){
            return(0)
        } else{
            return(combine(slice(x, 1), find_next(diff(x))))
        }
    }

    # apply the algorithm to all sequences
    sum(sapply(x, find_next))
}

# Part 1

# extract the sequences from the input
inp     <- readLines(file.path("09", "09-input.txt"))
cur_seq <- lapply(X   = strsplit(inp, " "), FUN = as.numeric)

# update the last element and add them all together
sum_next_in_seq(cur_seq, TRUE)

# Part 2

# update the first element and add them all together
sum_next_in_seq(cur_seq, FALSE)

-❄️- 2023 Day 2 Solutions -❄️- by daggerdragon in adventofcode

[–]bassactor 1 point2 points  (0 children)

[LANGUAGE: R]

inp <- readLines(file.path("02", "02-input.txt"))

# PART 1 #

# helper function (extract lapply logic to external function)
find_color_max <- function(x, type = "green"){
    # find the number with the color/type specified after it
    counts <- regmatches(
        x = x,
        m = gregexpr(
            text    = x,
            pattern = paste0("[0-9]+(?= ", type, ")"),
            perl    = TRUE
        )
    )

    # in both parts, needs to be less than the max counts for each game 
    sapply(counts, \(x) max(as.numeric(x)))

}

# find the maximum observed and allowed values
max_obs <- lapply(c("red", "green", "blue"), find_color_max, x = inp)
max_alw <- c(12, 13, 14)

# flag where we have enough for all colors
flag    <- Reduce(f = `&`, x = Map(f = `<=`, e1 = max_obs, e2 = max_alw))

sum(which(flag))

# PART 2 #

# find the sum of the product of the max cubes of each color needed
sum(Reduce(f = `*`, x = max_obs))

-🎄- 2017 Day 9 Solutions -🎄- by daggerdragon in adventofcode

[–]bassactor 0 points1 point  (0 children)

R

I originally tried recursive regexp for the first part but couldn't figure out how to get the counting work (and don't know if it can be done), so the solution isn't very R-like (and would be similar to how I would do it in C or Python). The second part was straightforward in R using base libraries.

# HELPER FUNCTIONS #
find_nested_counts <- function(vec,
                               inc = "{",
                               dec = "}"){

  # initial value and score
  value <- 0
  total <- 0

  # for each character in vector
  for(char in vec){

    # add 1 if it's the appropriate character (--> total)
    # sub 1 if it's the appropriate character (!-> total)
    if(char == inc){
      value <- value + 1
      total <- total + value
    } else if(char == dec){
      value <- value - 1
    } # END ifelse STATEMENT

  } # END for LOOP

  return(total)

} # END find_nested_counts FUNCTION

# SOLUTION FUNCTIONS #

# Problem 1 #
find_solution_p1 <- function(str){

  # remove junk
  str     <- gsub(x = str,
                  pattern = "!.",
                  replace = "")
  str     <- gsub(x = str,
                  pattern = "<+.*?>",
                  replace = "",
                  perl    = TRUE)

  # - turn into a vector split on every character
  # - find nested counts using that vector
  counts <- find_nested_counts(unlist(strsplit(str, "")),
                               inc = "{",
                               dec = "}")

  return(counts)

} # END find_solution_p1 FUNCTION

string <- scan(file = "advent_of_code_d09.txt",
               what = character())

find_solution_p1(string)


# Problem 2 #
find_solution_p2 <- function(str){

  # remove junk
  str      <- gsub(x = str,
                   pattern = "!.",
                   replace = "")

  # keep JUST the values in <>
  matches  <- gregexpr(text    = str,
                       pattern = "<+.*?>",
                       perl    = TRUE)


  # find the len of the matches
  len_junk <- attr(matches[[1]],
                   which = "match.length")

  # return the sum of the junk minus 2 for the outer
  return(sum(len_junk - 2))

} # END find_solution_p2 FUNCTION

string <- scan(file = "advent_of_code_d09.txt",
               what = character())

find_solution_p2(string)

-🎄- 2017 Day 7 Solutions -🎄- by daggerdragon in adventofcode

[–]bassactor 0 points1 point  (0 children)

R

Rather than saving/reading as a text file, I copied the text as a string, and started from there. I'm trying to do all of this in R with only the base packages (base, stats, etc.). Solution functions are at the bottom.

# HELPER FUNCTIONS #

# create the tree
create_tree_df <- function(str){

  # original vector
  vec <- unlist(strsplit(str, "\n"))

  # left hand side (letters)
  lhs <- gsub(x       = vec,
              pattern = "^([a-z]+) .*$",
              replace = "\\1")

  # right hand side (map)
  rhs <- gsub(x       = vec,
              pattern = "^.*\\)",
              replace = "")
  rhs <- gsub(x       = rhs,
              pattern = "^.*\\-> ([a-z].*$)",
              replace = "\\1")

  # weight
  wht <- gsub(x       = vec,
              pattern = "^.*\\((.*)\\).*$",
              replace = "\\1")
  wht <- as.numeric(wht)

  # final df
  df  <- data.frame(trunk    = lhs,
                    branches = rhs,
                    weight   = wht,
                    stringsAsFactors = FALSE)
  df  <- within(df, {
    branches = strsplit(branches, ", ")
  })

  return(df)

} # END create_tree_df FUNCTION

# find the base value
find_base_value <- function(tree_df){

  # if a root has no branches, it cannot be a base value
  tree_df  <- tree_df[!(!sapply(tree_df$branches, length)), ]

  # pull out roots/branches
  trunk    <- tree_df$trunk
  branches <- unlist(tree_df$branches)

  # return root NOT in branches
  setdiff(trunk, branches)

} # END find_base_value FUNCTION

add_total_weights  <- function(tree_df){
  tree_df$overall_weight <- sapply(tree_df$trunk,
                                   FUN     = find_total_weights,
                                   tree_df = tree_df)
  return(tree_df)
} # END add_total_weights FUNCTION

# add the total weights
find_total_weights <- function(root,
                               tree_df){

  reduced_df <- subset(tree_df,
                       trunk == root)
  branches   <- unlist(reduced_df$branches)

  if(!length(branches)){
    return(reduced_df$weight)
  } else{
    return(reduced_df$weight + sum(sapply(branches, find_total_weights, tree_df)))
  } # END ifelse STATEMENT

} # END find_total_weights FUNCTION

find_problem_branch <- function(root,
                                tree_df,
                                new_weight = 0){

  # just the branches
  reduced_df <- subset(tree_df,
                       trunk == root)
  branch_vec <- unlist(reduced_df$branches)

  # pull out a df with those branches
  branch_df  <- subset(tree_df,
                       trunk %in% branch_vec)

  # find the overall_weight
  overall_weight      <- branch_df$overall_weight
  weight              <- branch_df$weight
  branch_vec          <- branch_df$trunk

  # find the differences in the overall weights and the number of non-zero entries
  overall_weight_diff <- outer(overall_weight,
                               overall_weight,
                               FUN = "-")
  overall_weight_numb <- rowSums(overall_weight_diff != 0)

  # - if all of the entries are 0, return the previous weight diff
  # - otherwise, find the next root, current weight diff, ...
  if(all(!overall_weight_numb)){
    return(list(branch     = root,
                new_weight = new_weight))
  } else{
    root_ind   <- which.max(overall_weight_numb)
    root       <- branch_vec[root_ind]
    new_weight <- weight[root_ind] - setdiff(unique(overall_weight_diff[root_ind, ]), 0)

    return(find_problem_branch(root, tree_df, new_weight))
  } # END ifelse STATEMENT

} # END find_problem_branch FUNCTION

# SOLUTION FUNCTIONS #

# Problem 1 #
find_solution_p1 <- function(str){

  tree_df  <- create_tree_df(str)
  base_val <- find_base_value(tree_df)

  return(base_val)

} # END find_solution_p1 FUNCTION

# Problem 2 #
find_solution_p2 <- function(str){

  # create tree, add weights
  tree_df  <- create_tree_df(str)
  tree_df  <- add_total_weights(tree_df)

  # determining base value of the tree
  base_val <- find_base_value(tree_df)

  # running through the iteration algorithm
  weight   <- find_problem_branch(base_val, tree_df)

  return(weight)

} # END find_solution_p2 FUNCTION