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.
93 lines
3.6 KiB
Racket
93 lines
3.6 KiB
Racket
8 years ago
|
#lang typed/racket
|
||
|
(require typed/rackunit)
|
||
|
(provide (all-defined-out))
|
||
|
|
||
|
(: groups (-> (Listof Integer) Integer Integer (Listof (Listof Integer))))
|
||
|
(define (groups packages len goal-weight)
|
||
|
(cond
|
||
|
[(= len 0) empty]
|
||
|
[(= len 1) (map (ann list (-> Integer (Listof Integer))) (filter (ann (curry = goal-weight) (-> Integer Boolean)) packages))] ;;bg OMG
|
||
|
[else
|
||
|
(append*
|
||
|
(for/list ([x (in-list packages)])
|
||
|
: (Listof (Listof (Listof Integer)))
|
||
|
(define later-packages (cdr (or (member x packages) (error 'bg))))
|
||
|
(append-map (λ([ss : (Listof Integer)]) (define new-group (cons x ss))
|
||
|
(if (= goal-weight (weight new-group))
|
||
|
(list new-group)
|
||
|
empty))
|
||
|
(groups later-packages (sub1 len) (- goal-weight x)))))]))
|
||
|
|
||
|
(: weight (-> (Listof Integer) Integer))
|
||
|
(define (weight group) (apply + group))
|
||
|
|
||
|
(: quantum-entanglement (-> (Listof Integer) Integer))
|
||
|
(define (quantum-entanglement group) (apply * group))
|
||
|
|
||
|
(: remove-group (-> (Listof Integer) (Listof Integer) (Listof Integer)))
|
||
|
(define (remove-group group packages)
|
||
|
(filter (λ([p : Integer]) (not (member p group))) packages))
|
||
|
|
||
|
(: has-solution? (-> (Listof Integer) (Listof Integer) Boolean))
|
||
|
(define (has-solution? group packages)
|
||
|
(define target-weight (weight group))
|
||
|
(define remaining-packages (remove-group group packages))
|
||
|
(for/or : Boolean ([len (in-range (length remaining-packages))]
|
||
|
#:when (not (empty?
|
||
|
(groups remaining-packages len target-weight))))
|
||
|
#t))
|
||
|
|
||
|
(: find-three-group-solution (-> (Listof Integer) Integer (U #f Integer)))
|
||
|
(define (find-three-group-solution all-packages target-weight)
|
||
|
(for/or : (U #f Integer) ([len (in-range (length all-packages))]) ;;bg cannot do for*/or
|
||
|
(let loop : (U #f Integer) (
|
||
|
[groups ;in-list
|
||
|
((inst sort (Listof Integer) Integer)
|
||
|
(groups all-packages len target-weight)
|
||
|
#:key quantum-entanglement <)])
|
||
|
(cond
|
||
|
[(null? groups)
|
||
|
#f]
|
||
|
[(has-solution? (car groups) all-packages)
|
||
|
(quantum-entanglement (car groups))]
|
||
|
[else
|
||
|
(loop (cdr groups))]))))
|
||
|
; #:when (has-solution? group all-packages))
|
||
|
; (quantum-entanglement group)))
|
||
|
|
||
|
(: q1 (-> String (U #f Integer)))
|
||
|
(define (q1 input-str)
|
||
|
(define all-packages (map string->integer (string-split input-str)))
|
||
|
(define target-weight (cast (/ (weight all-packages) 3) Integer))
|
||
|
(find-three-group-solution all-packages target-weight))
|
||
|
|
||
|
;;bg
|
||
|
(: string->integer (-> String Integer))
|
||
|
(define (string->integer s)
|
||
|
(cast (string->number s) Integer))
|
||
|
|
||
|
(: q2 (-> String (U #f Integer)))
|
||
|
(define (q2 input-str)
|
||
|
(define all-packages (map string->integer (string-split input-str)))
|
||
|
(define target-weight (cast (/ (weight all-packages) 4) Integer))
|
||
|
(for/or : (U #f Integer) ([len (in-range (length all-packages))]) ;;bg cannot do for*/or
|
||
|
(let loop : (U #f Integer) (
|
||
|
[groups ((inst sort (Listof Integer) Integer)
|
||
|
(groups all-packages len target-weight)
|
||
|
#:key quantum-entanglement <)])
|
||
|
(cond
|
||
|
[(null? groups)
|
||
|
#f]
|
||
|
[(find-three-group-solution
|
||
|
(remove-group (car groups) all-packages) target-weight)
|
||
|
(quantum-entanglement (car groups))]
|
||
|
[else
|
||
|
(loop (cdr groups))]))))
|
||
|
|
||
|
(module+ test
|
||
|
(define input-str (file->string "../day24-input.txt"))
|
||
|
(check-equal? (q1 input-str) 10439961859)
|
||
|
(check-equal? (q2 input-str) 72050269))
|
||
|
|
||
|
|