15: Science for Hungry People

library(mistlecode)
To install `mistlecode` yourself, run `devtools::install_github('guslipkin/mistlecode')`.

 Also loading:  cipheR data.table dplyr purrr slider stringr tidyverse glue
library(rlang)
library(furrr)
library(progressr)
dt <-
  fread("input.txt", sep = " ") |>
  select(seq(1, 11, by = 2)) |>
  `colnames<-`(
    c("candy", "capacity", "durability", "flavor", "texture", "calories")
  ) |>
  mutate(
    across(everything(), ~ str_remove_all(.x, "[,:]")),
    across(-candy, as.integer)
  )

Part 1

This is super dumb but I don’t feel like learning how to use one of the linear programming tools. I’ll probably regret it.

cost <-
  dt |>
  nrow() |>
  seq_len() |>
  map(\(x) {
    dt[x, ] |>
      mutate(count = 101) |>
      uncount(count, .id = "id") |>
      mutate(id = id - 1)
  }) |>
  bind_rows()

combos <-
  expand.grid(list(1:100)[rep(1,nrow(dt))]) |>
  `colnames<-`(dt$candy) |>
  filter(rowSums(across(everything())) == 100)

filter_cookies <- function(...) {
  p()
  list2(...) |>
    imap(\(.x, idx) {
      filter(cost, id == .x & candy == idx)
    }) |>
    bind_rows() |>
    mutate(across(capacity:calories, ~ .x * id)) |>
    select(capacity:texture) |>
    map_int(sum) |>
    data.frame() |>
    `colnames<-`("value") |>
    mutate(value = ifelse(value < 0, 0, value)) |>
    pull(value) |>
    prod()
}

plan(multisession, workers = availableCores())
with_progress({
  p <- progressor(steps = nrow(combos))
  combos |>
    future_pmap_int(filter_cookies) |>
    max()
})
[1] 13882464
plan(sequential)

Part 2

Remember how I said I’d probably regret it? It could’ve been worse.

check_calories <- function(cal) {
  if (cal$value[rownames(cal) == "calories"] == 500) {
    return(data.frame(value = cal[rownames(cal) != "calories",]))
  } else {
    return(data.frame(value = 0))
  }
}

filter_cookies <- function(...) {
  p()
  list2(...) |>
    imap(\(.x, idx) {
      filter(cost, id == .x & candy == idx)
    }) |>
    bind_rows() |>
    mutate(across(capacity:calories, ~ .x * id)) |>
    select(capacity:calories) |>
    map_int(sum) |>
    data.frame() |>
    `colnames<-`("value") |>
    check_calories() |>
    mutate(value = ifelse(value < 0, 0, value)) |>
    pull(value) |>
    prod()
}

plan(multisession, workers = availableCores())
with_progress({
  p <- progressor(steps = nrow(combos))
  combos |>
    future_pmap_int(filter_cookies) |>
    max()
})
[1] 11171160
plan(sequential)