2020-12-07 05:34:21 +00:00
|
|
|
#lang curly-fn racket
|
|
|
|
|
|
|
|
(require "scripts/aoc.rkt")
|
|
|
|
|
|
|
|
;; solution for day 7
|
|
|
|
|
2020-12-07 07:35:26 +00:00
|
|
|
(define (part1 G wanted)
|
|
|
|
(define-vertex-property G has-wanted #:init #f)
|
|
|
|
(do-dfs G
|
|
|
|
;; only visit when the to vertex is not already marked with has-wanted
|
|
|
|
#:visit?: (if (and $from (has-wanted $to))
|
|
|
|
(begin (has-wanted-set! $from #t) #f)
|
|
|
|
#t)
|
|
|
|
;; propagate has-wanted if the child has it
|
|
|
|
#:epilogue: (when (and $from (or (has-wanted $to) (string=? wanted $to)))
|
|
|
|
(has-wanted-set! $from #t)))
|
|
|
|
;; count the results
|
|
|
|
(for/sum ([(_ v) (in-hash (has-wanted->hash))] #:when v) 1))
|
|
|
|
|
|
|
|
(define (part2 G wanted)
|
|
|
|
;; initially, each vertex just counts the weight of itself, which is 1
|
|
|
|
(define-vertex-property G all-weight #:init 1)
|
|
|
|
|
|
|
|
;; accumulates the result in the vertex property tracking all weights
|
|
|
|
;; adds the total weight of $to multiplied by the edge weight of $from -> $to to the total weight
|
|
|
|
;; of $from
|
|
|
|
;; this will be called for each neighbor of $from, and $from's total weight starts at 1
|
|
|
|
(define (increment $from $to)
|
|
|
|
(when $from
|
|
|
|
(all-weight-set! $from
|
|
|
|
(+ (all-weight $from)
|
|
|
|
(* (edge-weight G $from $to) (all-weight $to))))))
|
|
|
|
|
|
|
|
(do-dfs G
|
|
|
|
#:order (lambda (_) (list wanted))
|
|
|
|
;; always check already-visited nodes
|
|
|
|
#:process-unvisited?: #t
|
|
|
|
;; add already-visited nodes to the total
|
|
|
|
#:process-unvisited: (increment $from $to)
|
|
|
|
;; add nodes we finished visiting to the total
|
|
|
|
#:epilogue: (increment $from $to))
|
|
|
|
;; subtract 1 because we counted the shiny gold bag itself, when we only need the weight of
|
|
|
|
;; what's inside it
|
|
|
|
(sub1 (all-weight wanted)))
|
2020-12-07 05:34:21 +00:00
|
|
|
|
|
|
|
(module+ main
|
2020-12-07 07:35:26 +00:00
|
|
|
(define input-lines (file->lines "inputs/7"))
|
|
|
|
(define edges
|
|
|
|
(apply append
|
|
|
|
(for/list ([line (in-list input-lines)])
|
|
|
|
(match line
|
|
|
|
[(pregexp #px"^([a-z ]+) bags contain ([^\\.]+).$" (list _ src-color contains))
|
2020-12-07 05:34:21 +00:00
|
|
|
(if (string=? "no other bags" contains)
|
|
|
|
'()
|
|
|
|
(for/list ([item (in-list (string-split contains ", "))])
|
|
|
|
(match item
|
|
|
|
[(pregexp #px"^([0-9]+) ([a-z ]+) bag[s]?"
|
2020-12-07 07:35:26 +00:00
|
|
|
(list _ (app string->number number) dst-color))
|
|
|
|
(list number src-color dst-color)]
|
|
|
|
[x (error "not shonks" x)])))]
|
|
|
|
[x (error "not shonks" x)]))))
|
|
|
|
(define input (weighted-graph/directed edges))
|
2020-12-07 05:34:21 +00:00
|
|
|
(define wanted "shiny gold")
|
|
|
|
|
|
|
|
;; part 1
|
2020-12-07 07:35:26 +00:00
|
|
|
(answer 7 1 (part1 input wanted))
|
2020-12-07 05:34:21 +00:00
|
|
|
|
|
|
|
;; part 2
|
2020-12-07 07:35:26 +00:00
|
|
|
(answer 7 2 (part2 input wanted))
|
2020-12-07 05:34:21 +00:00
|
|
|
|
|
|
|
(displayln "meow"))
|