aoc2020/21.rkt

85 lines
3.2 KiB
Racket

#lang curly-fn racket
(require "scripts/aoc.rkt")
;; solution for day 21
(define (part1 input)
; (define edges
; (for/fold ([edges '()]) ([line (in-list input)])
; (match-define (cons ingreds allergs) line)
; (append edges (for*/list ([i (in-list ingreds)] [a (in-list allergs)])
; (list i a)))))
; (define G (undirected-graph edges))
;(define matching (maximum-bipartite-matching G))
(define all-ingreds (for/fold ([all (set)]) ([line (in-list input)])
(set-union all (list->set (car line)))))
(define all-allergs (for/fold ([all (set)]) ([line (in-list input)])
(set-union all (list->set (cdr line)))))
(define tainted (mutable-set))
(for ([allerg (in-set all-allergs)])
(define necessary (for/fold ([necessary all-ingreds]) ([line (in-list input)] #:when (member allerg (cdr line)))
(set-intersect necessary (list->set (car line)))))
(set-union! tainted necessary))
(define untainted (set-subtract all-ingreds tainted))
(for*/sum ([line (in-list input)] [ingred (in-list (car line))])
(if (set-member? untainted ingred) 1 0)))
(define (part2 input)
(define all-ingreds (for/fold ([all (set)]) ([line (in-list input)])
(set-union all (list->set (car line)))))
(define all-allergs (for/fold ([all (set)]) ([line (in-list input)])
(set-union all (list->set (cdr line)))))
(define tainted (mutable-set))
(for ([allerg (in-set all-allergs)])
(define necessary (for/fold ([necessary all-ingreds]) ([line (in-list input)] #:when (member allerg (cdr line)))
(set-intersect necessary (list->set (car line)))))
(set-union! tainted necessary))
(define tainthash (for/hash ([a (in-set all-allergs)])
(values a (for/fold ([is all-ingreds]) ([line (in-list input)] #:when (member a (cdr line)))
(set-intersect is (list->set (filter #{set-member? tainted %} (car line))))))))
(define edges (for*/list ([k (in-list (hash-keys tainthash))]
[v (in-set (hash-ref tainthash k))])
(list k v)))
(pretty-write edges)
(define G (undirected-graph edges))
(define matching (maximum-bipartite-matching G))
(displayln matching)
(define mhash (for/hash ([item (in-list matching)]) (values (first item) (second item))))
(displayln mhash)
(define by-allergs (sort (hash-keys mhash) string<?))
(string-join
(for/list ([key (in-list by-allergs)])
(hash-ref mhash key))
",")
)
; (part2 (parse "test"))
; (error "not shonks")
;; parse input file
(define (parse fname)
(define lines (file->lines fname))
(for/list ([line (in-list lines)])
(match line
[(pregexp #px"^([^\\(]+) \\(contains ([^\\)]+)\\)+"
(list _ p1 p2))
(define ingredients (string-split p1 " "))
(define allergens (string-split p2 ", "))
(cons ingredients allergens)]
[_ (error "not shonks" line)])))
(module+ test
(require rackunit)
;; tests here
(displayln "no tests :("))
(module+ main
(define input (parse "inputs/21"))
(answer 21 1 (time (part1 input)))
(answer 21 2 (time (part2 input)))
(displayln "meow"))