You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/typed/day15.rkt

73 lines
3.8 KiB
Racket

#lang typed/racket
(require typed/rackunit)
(provide (all-defined-out))
(: str->ingredient-hash (-> String (HashTable String (Listof Integer))))
(define (str->ingredient-hash str)
(for/hash : (HashTable String (Listof Integer))
([ln (in-list (string-split (string-replace str "," " ") "\n"))])
(match-define (list ingredient-name characteristic-string)
(string-split ln ":"))
(values ingredient-name
(filter exact-integer? ;;bg;number?
(map string->number
(string-split characteristic-string))))))
(: make-recipes (-> Integer Integer (Listof (Listof Integer))))
(define (make-recipes how-many-ingredients total-tsps)
(cond
[(= 0 how-many-ingredients) empty]
[(= 1 how-many-ingredients) (list (list total-tsps))]
[else
(append*
(for/list ([first-amount (in-range (add1 total-tsps))])
: (Listof (Listof (Listof Integer)))
(map (λ ([x : (Listof Integer)]) (cons first-amount x)) ;(curry cons first-amount)
(make-recipes (sub1 how-many-ingredients)
(- total-tsps first-amount)))))]))
(: q1 (-> String Integer))
(define (q1 input-str)
(define ingredient-hash (str->ingredient-hash input-str))
(define ingredients (hash-keys ingredient-hash))
(define how-many-characteristics (length (car (hash-values ingredient-hash))))
(define tsps 100)
(define scores
(for/list ([recipe (in-list (make-recipes (length ingredients) tsps))])
: (Listof Integer)
(for/product : Integer ([char-idx (in-range (sub1 how-many-characteristics))])
(max 0 (for/sum : Integer
([tsp-quantity (in-list recipe)]
[ingredient (in-list ingredients)])
(* tsp-quantity
(list-ref (hash-ref ingredient-hash ingredient) char-idx)))))))
(apply max scores))
(: q2 (-> String Integer))
(define (q2 input-str)
(define ingredient-hash (str->ingredient-hash input-str))
(define ingredients (hash-keys ingredient-hash))
(define how-many-characteristics (length (car (hash-values ingredient-hash))))
(define tsps 100)
(: recipe->calories (-> (Listof Integer) Integer))
(define (recipe->calories recipe)
(for/sum : Integer ([tsp-quantity (in-list recipe)]
[ingredient (in-list ingredients)])
(* tsp-quantity (last (hash-ref ingredient-hash ingredient (λ () (error 'bg)))))))
(define scores
(for/list : (Listof Integer) ([recipe (in-list (make-recipes (length ingredients) tsps))]
#:when (= 500 (recipe->calories recipe)))
(for/product : Integer ([char-idx (in-range (sub1 how-many-characteristics))])
(max 0 (for/sum : Integer ([tsp-quantity (in-list recipe)]
[ingredient (in-list ingredients)])
(* tsp-quantity
(list-ref (hash-ref ingredient-hash ingredient) char-idx)))))))
(apply max scores))
(module+ test
(define input-str (file->string "../day15-input.txt"))
(check-equal? (q1 input-str) 18965440)
(check-equal? (q2 input-str) 15862900))