#lang curly-fn racket (require "scripts/aoc.rkt") ;; solution for day 7 (define *hand-order* (for/hash ([chr (in-string "AKQJT98765432")] [n (in-naturals)]) (values chr n))) (define (rank-hand h) (define groups (group-by identity (string->list h))) (define counts (sort (map length groups) >)) (match counts ['(5) 6] ['(4 1) 5] ['(3 2) 4] ['(3 1 1) 3] ['(2 2 1) 2] ['(2 1 1 1) 1] ['(1 1 1 1 1) 0])) (define (hand-string> a b) (for/first ([as (in-string a)] [bs (in-string b)] #:do [(define ac (hash-ref *hand-order* as)) (define bc (hash-ref *hand-order* bs))] #:unless (= ac bc)) (< ac bc))) (define (hand> a b) (define a-rank (rank-hand a)) (define b-rank (rank-hand b)) (cond [(> a-rank b-rank) #t] [(< a-rank b-rank) #f] [else (hand-string> a b)])) (define (part1 input) (define sorted (sort input hand> #:key car)) (for/sum ([n (in-inclusive-range 1 (length input))] [item (reverse sorted)]) (* n (cdr item)))) (define *hand-order-p2* (for/hash ([chr (in-string "AKQT98765432J")] [n (in-naturals)]) (values chr n))) (define (hand-string>-part2 a b) (for/first ([as (in-string a)] [bs (in-string b)] #:do [(define ac (hash-ref *hand-order-p2* as)) (define bc (hash-ref *hand-order-p2* bs))] #:unless (= ac bc)) (< ac bc))) (define (repeat n x) (for/list ([i (in-range n)]) x)) (define (make-hand hand pos replace) (list->string (for/fold ([hl (string->list hand)]) ([i (in-list pos)] [x (in-list replace)]) (list-set hl i x)))) (define/memoized (best-rank-part2 hand) (define joker-positions (indexes-of (string->list hand) #\J)) (define possibilities (apply cartesian-product (repeat (length joker-positions) (string->list "AKQT98765432")))) (define best (argmax (λ (p) (rank-hand (make-hand hand joker-positions p))) possibilities)) (make-hand hand joker-positions best)) (define (hand>-part2 a b) (define best-a (best-rank-part2 a)) (define best-b (best-rank-part2 b)) (define a-rank (rank-hand best-a)) (define b-rank (rank-hand best-b)) (cond [(> a-rank b-rank) #t] [(< a-rank b-rank) #f] [else (hand-string>-part2 a b)])) (define (part2 input) (define sorted (sort input hand>-part2 #:key car)) (for/sum ([n (in-inclusive-range 1 (length input))] [item (reverse sorted)]) (* n (cdr item)))) (define (parse fname) (for/list ([line (in-list (file->lines fname))]) (match-define (list hand-raw bid-raw) (string-split line)) (cons hand-raw (string->number bid-raw)))) (module+ main (define input (parse "inputs/7")) (answer 7 1 (time (part1 input))) (answer 7 2 (time (part2 input))) (displayln "meow"))