#lang curly-fn racket (require "scripts/aoc.rkt") ;; solution for day 21 (struct line [is as] #:transparent) (struct data [lines all-is all-as tainted] #:transparent) (define (part1 input) (match-define (data lines all-is all-as tainted) input) (define untainted (set-subtract all-is (apply set-union (hash-values tainted)))) (for*/sum ([l (in-list lines)] [i (in-set (line-is l))] #:when (set-member? untainted i)) 1)) (define (part2 input) (match-define (data lines all-is all-as tainted) input) (define edges (for*/list ([(k v*) (in-hash tainted)] [v (in-set v*)]) (list k v))) (define G (undirected-graph edges)) (define matching (maximum-bipartite-matching G)) (string-join (for/list ([val (in-list (sort matching #{stringlines fname))]) (match-define (list _ p1 p2) (regexp-match #px"^([^\\(]+) \\(contains ([^\\)]+)\\)+" l)) (define is (list->set (string-split p1 " "))) (define as (list->set (string-split p2 ", "))) (values (cons (line is as) lines) (set-union all-is is) (set-union all-as as)))) (define tainted (for/hash ([a (in-set all-as)]) (values a (for/fold ([necessary all-is]) ([l (in-list lines)] #:when (set-member? (line-as l) a)) (set-intersect (line-is l) necessary))))) (data lines all-is all-as tainted)) (module+ main (define input (parse "inputs/21")) (answer 21 1 (time (part1 input))) (answer 21 2 (time (part2 input))) (displayln "meow"))