Initial commit
This commit is contained in:
commit
f242d2b0df
420 changed files with 62521 additions and 0 deletions
81
2019/day14/day14.rkt
Normal file
81
2019/day14/day14.rkt
Normal file
|
@ -0,0 +1,81 @@
|
|||
#lang racket
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(module+ main
|
||||
(displayln "Day 14"))
|
||||
|
||||
(define (read-rules filename)
|
||||
(with-input-from-file filename
|
||||
(lambda ()
|
||||
(define h (make-hash))
|
||||
(for ([line (in-lines)])
|
||||
(define rule
|
||||
(for/list ([elt (regexp-match* #rx"([0-9]+) ([A-Z]+)" line #:match-select cdr)])
|
||||
(list (string->number (car elt)) (string->symbol (cadr elt)))))
|
||||
(define output (last rule))
|
||||
(hash-set! h
|
||||
(cadr output)
|
||||
(cons (car output)
|
||||
(make-hash (for/list ([elt (drop-right rule 1)])
|
||||
(cons (cadr elt) (car elt)))))))
|
||||
h)))
|
||||
|
||||
(define (generate! rules needed available)
|
||||
(for ([(target target-amount) (in-hash needed)]
|
||||
#:unless (eq? target 'ORE))
|
||||
(define inputs (cdr (hash-ref rules target)))
|
||||
(define output-amount (car (hash-ref rules target)))
|
||||
(define new-target-amount (- target-amount (hash-ref available target 0)))
|
||||
(define multiple (ceiling (/ new-target-amount output-amount)))
|
||||
(hash-set! available target (- (* multiple output-amount) new-target-amount))
|
||||
(hash-set! needed target 0)
|
||||
(for ([(input input-amount) (in-hash inputs)])
|
||||
(hash-update! needed input (lambda (v) (+ v (* multiple input-amount))) 0))))
|
||||
|
||||
(define (ore-per-fuel rules amount)
|
||||
(define needed (make-hash `((FUEL . ,amount))))
|
||||
(define available (make-hash))
|
||||
(for ([i (in-naturals)]
|
||||
#:break (= (apply + (hash-values needed)) (hash-ref needed 'ORE 0)))
|
||||
(generate! rules needed available))
|
||||
(hash-ref needed 'ORE))
|
||||
|
||||
(define (part1 filename)
|
||||
(define rules (read-rules filename))
|
||||
(ore-per-fuel rules 1))
|
||||
|
||||
(module+ test
|
||||
(check-eq? 31 (part1 "test1"))
|
||||
(check-eq? 165 (part1 "test2"))
|
||||
(check-eq? 13312 (part1 "test3"))
|
||||
(check-eq? 180697 (part1 "test4"))
|
||||
(check-eq? 2210736 (part1 "test5")))
|
||||
|
||||
(module+ main
|
||||
(display "Part 1: ")
|
||||
(displayln (part1 "input")))
|
||||
|
||||
(define (part2 filename)
|
||||
(define rules (read-rules filename))
|
||||
(define max-fuel 1000000000000)
|
||||
(define min-fuel 1)
|
||||
(bisect rules 1000000000000 min-fuel max-fuel))
|
||||
|
||||
(define (bisect rules target-ore min-fuel max-fuel)
|
||||
(define mid-fuel (floor (+ min-fuel (/ (- max-fuel min-fuel) 2))))
|
||||
(define ore (ore-per-fuel rules mid-fuel))
|
||||
(cond
|
||||
[(= 1 (- max-fuel min-fuel)) min-fuel]
|
||||
[(< ore target-ore) (bisect rules target-ore mid-fuel max-fuel)]
|
||||
[(< target-ore ore) (bisect rules target-ore min-fuel mid-fuel)]))
|
||||
|
||||
(module+ test
|
||||
(check-eq? 82892753 (part2 "test3"))
|
||||
(check-eq? 5586022 (part2 "test4"))
|
||||
(check-eq? 460664 (part2 "test5")))
|
||||
|
||||
(module+ main
|
||||
(display "Part 2: ")
|
||||
(displayln (part2 "input")))
|
Loading…
Add table
Add a link
Reference in a new issue