Advent of Code 2020 Day 21

Author

Nathan Moore

Write the Puzzle explanation here

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.6
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.1     ✔ tibble    3.3.0
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.2.0     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
my_file <- here::here("2020", "data-2020-21.txt")
foods <- read.delim(my_file, header = FALSE)

Maybe write an explanation of the solution approach here

# a bit of back and forward with this, but I like it
# get the allergens out then expand them downwards
# get the ingredients and nest them
foods_allergen <- foods %>% 
  mutate(allergens = str_extract(V1, "\\(.*\\)"), 
         allergens = str_remove(allergens, "\\(contains "), 
         allergens = str_remove(allergens, "\\)"), 
         allergens = str_split(allergens, ", "), 
         ingred = str_remove(V1, " \\(.*\\)"), 
         ingred = str_split(ingred, " ")) %>% 
  select(-V1) %>% 
  unnest_longer(allergens) %>% 
  arrange(allergens) %>% 
  nest(ingred = c(ingred))

next

# check that intersect gives what we want
intersect(foods_allergen$ingred[[1]]$ingred[[1]], foods_allergen$ingred[[1]]$ingred[[2]])
 [1] "hmhll"   "tsfx"    "gkphjq"  "drnrd"   "hcxhl"   "mvqkdj"  "gkcplx" 
 [8] "fkfr"    "lttlx"   "dqsbql"  "fdfr"    "msfmt"   "cjxgg"   "ktv"    
[15] "vhchvg"  "srnbhq"  "zscj"    "cgbgf"   "sqzhc"   "ppdplc"  "ktlh"   
[22] "cmkqcs"  "lcqn"    "cdrm"    "xzxth"   "srzsljf" "krv"     "gxgbkd" 
[29] "xbp"     "vdnvf"  
# I have come to enjoy using intersect for all these tasks
Reduce(intersect, foods_allergen$ingred[[1]]$ingred)
[1] "gkcplx" "dqsbql" "ppdplc" "ktlh"  
# function to apply the intersect to the different allergens
reduce_intersect <- function(my_list) {
  Reduce(intersect, my_list$ingred)
}

# map is my fave
foods_possible <- foods_allergen %>% 
  mutate(possible = map(ingred, reduce_intersect))

# this is the list of allergens
allergen_list <- foods_possible$possible %>% unlist() %>% unique()

answer

# go back to the original rows
foods_safe <- foods %>% 
  mutate(ingred = str_remove(V1, " \\(.*\\)"), 
         ingred = str_split(ingred, " ")) %>% 
  select(-V1) %>% 
  unnest_longer(ingred) %>% 
  filter(!(ingred %in% allergen_list))

# answers
part_one <- nrow(foods_safe)

part_one
[1] 2098

Part Two

# sesame we know for sure
# could go along and eliminate from other vectors
# and eliminate those from the other vectors
# or just write it by hand
part_two_c = c("gbt", "rpj", "vdxb", "dtb", "bqmhk", "vqzbq", "zqjm", "nhjrzzj")

part_two = paste0(part_two_c, collapse = ",")

part_two
[1] "gbt,rpj,vdxb,dtb,bqmhk,vqzbq,zqjm,nhjrzzj"