day 21: revised clean solution
This commit is contained in:
parent
e5cc177d78
commit
79ff63e453
87
21.rkt
87
21.rkt
|
@ -4,78 +4,43 @@
|
||||||
|
|
||||||
;; solution for day 21
|
;; solution for day 21
|
||||||
|
|
||||||
|
(struct line [is as] #:transparent)
|
||||||
|
(struct data [lines all-is all-as tainted] #:transparent)
|
||||||
|
|
||||||
(define (part1 input)
|
(define (part1 input)
|
||||||
; (define edges
|
(match-define (data lines all-is all-as tainted) input)
|
||||||
; (for/fold ([edges '()]) ([line (in-list input)])
|
(define untainted (set-subtract all-is (apply set-union (hash-values tainted))))
|
||||||
; (match-define (cons ingreds allergs) line)
|
(for*/sum ([l (in-list lines)] [i (in-set (line-is l))] #:when (set-member? untainted i))
|
||||||
; (append edges (for*/list ([i (in-list ingreds)] [a (in-list allergs)])
|
1))
|
||||||
; (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 (part2 input)
|
||||||
(define all-ingreds (for/fold ([all (set)]) ([line (in-list input)])
|
(match-define (data lines all-is all-as tainted) input)
|
||||||
(set-union all (list->set (car line)))))
|
(define edges
|
||||||
(define all-allergs (for/fold ([all (set)]) ([line (in-list input)])
|
(for*/list ([(k v*) (in-hash tainted)] [v (in-set v*)])
|
||||||
(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)))
|
(list k v)))
|
||||||
|
|
||||||
(pretty-write edges)
|
|
||||||
(define G (undirected-graph edges))
|
(define G (undirected-graph edges))
|
||||||
(define matching (maximum-bipartite-matching G))
|
(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
|
(string-join
|
||||||
(for/list ([key (in-list by-allergs)])
|
(for/list ([val (in-list (sort matching #{string<? (first %1) (first %2)}))])
|
||||||
(hash-ref mhash key))
|
(second val))
|
||||||
",")
|
","))
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
; (part2 (parse "test"))
|
|
||||||
; (error "not shonks")
|
|
||||||
|
|
||||||
;; parse input file
|
;; parse input file
|
||||||
(define (parse fname)
|
(define (parse fname)
|
||||||
(define lines (file->lines fname))
|
(define-values [lines all-is all-as]
|
||||||
(for/list ([line (in-list lines)])
|
(for/fold ([lines '()] [all-is (set)] [all-as (set)]) ([l (in-list (file->lines fname))])
|
||||||
(match line
|
(match-define (list _ p1 p2) (regexp-match #px"^([^\\(]+) \\(contains ([^\\)]+)\\)+" l))
|
||||||
[(pregexp #px"^([^\\(]+) \\(contains ([^\\)]+)\\)+"
|
(define is (list->set (string-split p1 " ")))
|
||||||
(list _ p1 p2))
|
(define as (list->set (string-split p2 ", ")))
|
||||||
(define ingredients (string-split p1 " "))
|
(values (cons (line is as) lines) (set-union all-is is) (set-union all-as as))))
|
||||||
(define allergens (string-split p2 ", "))
|
|
||||||
(cons ingredients allergens)]
|
|
||||||
[_ (error "not shonks" line)])))
|
|
||||||
|
|
||||||
(module+ test
|
(define tainted
|
||||||
(require rackunit)
|
(for/hash ([a (in-set all-as)])
|
||||||
;; tests here
|
(values a (for/fold ([necessary all-is]) ([l (in-list lines)]
|
||||||
(displayln "no tests :("))
|
#:when (set-member? (line-as l) a))
|
||||||
|
(set-intersect (line-is l) necessary)))))
|
||||||
|
(data lines all-is all-as tainted))
|
||||||
|
|
||||||
(module+ main
|
(module+ main
|
||||||
(define input (parse "inputs/21"))
|
(define input (parse "inputs/21"))
|
||||||
|
|
Loading…
Reference in New Issue