diff --git a/input/16.txt b/input/16.txt new file mode 100644 index 0000000..6eeba98 --- /dev/null +++ b/input/16.txt @@ -0,0 +1,58 @@ +Valve GJ has flow rate=14; tunnels lead to valves UV, AO, MM, UD, GM +Valve HE has flow rate=0; tunnels lead to valves QE, SV +Valve ET has flow rate=0; tunnels lead to valves LU, SB +Valve SG has flow rate=0; tunnels lead to valves FF, SB +Valve LC has flow rate=0; tunnels lead to valves QJ, GM +Valve EE has flow rate=13; tunnels lead to valves RE, BR +Valve AA has flow rate=0; tunnels lead to valves QC, ZR, NT, JG, FO +Valve TF has flow rate=0; tunnels lead to valves LU, MM +Valve GO has flow rate=0; tunnels lead to valves LB, AH +Valve QE has flow rate=24; tunnels lead to valves LG, HE +Valve MI has flow rate=0; tunnels lead to valves KU, FF +Valve BR has flow rate=0; tunnels lead to valves HY, EE +Valve UV has flow rate=0; tunnels lead to valves GP, GJ +Valve EH has flow rate=0; tunnels lead to valves UU, FF +Valve WK has flow rate=0; tunnels lead to valves HY, EL +Valve NT has flow rate=0; tunnels lead to valves FF, AA +Valve KI has flow rate=0; tunnels lead to valves OQ, AO +Valve AH has flow rate=22; tunnels lead to valves GO, RE +Valve EL has flow rate=0; tunnels lead to valves WK, SQ +Valve GP has flow rate=0; tunnels lead to valves SB, UV +Valve GM has flow rate=0; tunnels lead to valves LC, GJ +Valve LU has flow rate=9; tunnels lead to valves UU, DW, TF, ET, ML +Valve LB has flow rate=0; tunnels lead to valves GO, VI +Valve QC has flow rate=0; tunnels lead to valves ML, AA +Valve JJ has flow rate=0; tunnels lead to valves QJ, DV +Valve MM has flow rate=0; tunnels lead to valves TF, GJ +Valve VI has flow rate=18; tunnel leads to valve LB +Valve NV has flow rate=0; tunnels lead to valves SB, KU +Valve VT has flow rate=0; tunnels lead to valves HY, JG +Valve RE has flow rate=0; tunnels lead to valves AH, EE +Valve FO has flow rate=0; tunnels lead to valves SB, AA +Valve DV has flow rate=10; tunnels lead to valves JH, UD, JJ +Valve SQ has flow rate=12; tunnels lead to valves EL, QA +Valve OQ has flow rate=23; tunnels lead to valves KI, IV, JS +Valve FF has flow rate=3; tunnels lead to valves EU, NT, SG, MI, EH +Valve IV has flow rate=0; tunnels lead to valves LG, OQ +Valve HY has flow rate=8; tunnels lead to valves VT, BR, WK +Valve ML has flow rate=0; tunnels lead to valves LU, QC +Valve JS has flow rate=0; tunnels lead to valves EM, OQ +Valve KU has flow rate=5; tunnels lead to valves MI, VL, NV, HU, DW +Valve QA has flow rate=0; tunnels lead to valves OS, SQ +Valve EU has flow rate=0; tunnels lead to valves FF, OS +Valve SV has flow rate=0; tunnels lead to valves QJ, HE +Valve JG has flow rate=0; tunnels lead to valves AA, VT +Valve DW has flow rate=0; tunnels lead to valves LU, KU +Valve UD has flow rate=0; tunnels lead to valves DV, GJ +Valve QJ has flow rate=17; tunnels lead to valves JJ, SV, LC, EM, YA +Valve HU has flow rate=0; tunnels lead to valves JH, KU +Valve ZR has flow rate=0; tunnels lead to valves AA, VL +Valve YA has flow rate=0; tunnels lead to valves QJ, OS +Valve JH has flow rate=0; tunnels lead to valves HU, DV +Valve OS has flow rate=15; tunnels lead to valves EU, YA, QA +Valve LG has flow rate=0; tunnels lead to valves QE, IV +Valve SB has flow rate=4; tunnels lead to valves FO, SG, NV, GP, ET +Valve UU has flow rate=0; tunnels lead to valves EH, LU +Valve VL has flow rate=0; tunnels lead to valves ZR, KU +Valve AO has flow rate=0; tunnels lead to valves GJ, KI +Valve EM has flow rate=0; tunnels lead to valves QJ, JS diff --git a/src/16.rkt b/src/16.rkt new file mode 100644 index 0000000..8eaa62c --- /dev/null +++ b/src/16.rkt @@ -0,0 +1,65 @@ +#lang curly-fn racket + +(require "../lib.rkt" + data/queue + (except-in graph transpose)) + +(define flows (make-hash)) + +(define graph + (for/fold ([edges '()] + #:result (unweighted-graph/undirected edges)) + ([valve (problem-input 16)]) + (match-let* ([(pregexp "Valve (\\w\\w) has flow rate=(\\d+); tunnels? leads? to valves? (.+)" `(,_ ,v ,r ,ts)) valve] + [valve (string->symbol v)] + [flow (string->number r)]) + (hash-set! flows valve flow) + (for/fold ([edges edges]) + ([tunnel (string-split ts ", ")]) + (cons (list valve (string->symbol tunnel)) edges))))) + +(define graph* + (weighted-graph/undirected + (for/list ([(edge weight) (floyd-warshall graph)] + #:when (or (and (symbol=? 'AA (first edge)) + (not (zero? (hash-ref flows (second edge))))) + (and (not (zero? weight)) + (not (zero? (hash-ref flows (first edge)))) + (not (zero? (hash-ref flows (second edge))))))) + (cons weight edge)))) + +(define (part1) + (define Q (make-queue)) + (enqueue! Q (list 'AA 30 0 (set 'AA))) + (let loop ([pressure 0]) + (if (queue-empty? Q) pressure + (match-let ([`(,v ,t ,p ,seen) (dequeue! Q)]) + (for ([n (in-neighbors graph* v)] + #:when (not (set-member? seen n))) + (define time (- t (edge-weight graph* v n) 1)) + (define flow (hash-ref flows n)) + (when (> time 0) + (enqueue! Q (list n time (+ p (* flow time)) (set-add seen n))))) + (loop (max pressure p)))))) + +(define (part2) + (define Q (make-queue)) + (define paths (make-hash)) + (enqueue! Q (list 'AA 26 0 (set 'AA))) + (let loop () + (if (queue-empty? Q) + (for*/max ([(path1 p1) paths] + [(path2 p2) paths] + #:when (set-empty? (set-remove (set-intersect path1 path2) 'AA))) + (+ p1 p2)) + (match-let ([`(,v ,t ,p ,seen) (dequeue! Q)]) + (for ([n (in-neighbors graph* v)] + #:when (not (set-member? seen n))) + (define time (- t (edge-weight graph* v n) 1)) + (define flow (hash-ref flows n)) + (if (> time 0) + (enqueue! Q (list n time (+ p (* flow time)) (set-add seen n))) + (hash-set! paths seen (max p (hash-ref paths seen 0))))) + (loop))))) + +(show-solution* part1 part2) \ No newline at end of file