diff --git a/input/19.txt b/input/19.txt new file mode 100644 index 0000000..b7b2f69 --- /dev/null +++ b/input/19.txt @@ -0,0 +1,30 @@ +Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 15 obsidian. +Blueprint 2: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 17 clay. Each geode robot costs 2 ore and 13 obsidian. +Blueprint 3: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 6 clay. Each geode robot costs 2 ore and 14 obsidian. +Blueprint 4: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 14 obsidian. +Blueprint 5: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 12 clay. Each geode robot costs 2 ore and 10 obsidian. +Blueprint 6: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 4 ore and 11 obsidian. +Blueprint 7: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 9 clay. Each geode robot costs 3 ore and 15 obsidian. +Blueprint 8: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 10 clay. Each geode robot costs 2 ore and 7 obsidian. +Blueprint 9: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 4 ore and 9 obsidian. +Blueprint 10: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 19 clay. Each geode robot costs 2 ore and 18 obsidian. +Blueprint 11: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 3 ore and 10 obsidian. +Blueprint 12: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 10 clay. Each geode robot costs 4 ore and 10 obsidian. +Blueprint 13: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 3 ore and 14 obsidian. +Blueprint 14: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 4 ore and 13 obsidian. +Blueprint 15: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 8 obsidian. +Blueprint 16: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 11 clay. Each geode robot costs 3 ore and 8 obsidian. +Blueprint 17: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 4 ore and 8 obsidian. +Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 6 clay. Each geode robot costs 3 ore and 11 obsidian. +Blueprint 19: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 3 ore and 18 obsidian. +Blueprint 20: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 4 ore and 11 obsidian. +Blueprint 21: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 2 ore and 19 obsidian. +Blueprint 22: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 19 clay. Each geode robot costs 2 ore and 12 obsidian. +Blueprint 23: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 3 ore and 13 obsidian. +Blueprint 24: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 8 obsidian. +Blueprint 25: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 2 ore and 9 obsidian. +Blueprint 26: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 2 ore and 14 obsidian. +Blueprint 27: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 10 obsidian. +Blueprint 28: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 3 ore and 16 obsidian. +Blueprint 29: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 17 obsidian. +Blueprint 30: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 4 ore and 20 obsidian. diff --git a/src/19.rkt b/src/19.rkt new file mode 100644 index 0000000..08f8a8c --- /dev/null +++ b/src/19.rkt @@ -0,0 +1,80 @@ +#lang curly-fn racket + +(require "../lib.rkt" + data/queue) + +(define blueprints + (for/list ([bp (problem-input 19)]) + (match bp + [(pregexp (string-append "Blueprint (\\d+): " + "Each ore robot costs (\\d+) ore. " + "Each clay robot costs (\\d+) ore. " + "Each obsidian robot costs (\\d+) ore and (\\d+) clay. " + "Each geode robot costs (\\d+) ore and (\\d+) obsidian.") + blueprint) + (map string->number (rest blueprint))]))) + +(define ((run-blueprint time) ore-ore clay-ore obsidian-ore obsidian-clay geode-ore geode-obsidian) + (define seen (mutable-set)) + (define Q (make-queue)) + (enqueue! Q `(,time 0 0 0 0 1 0 0 0)) + (define (enqueue*! time . args) + (unless (set-member? seen args) + (set-add! seen args) + (enqueue! Q (cons time args)))) + (let loop ([geodes 0] + [time/geodes (make-immutable-hash)]) + (if (queue-empty? Q) geodes + (match-let ([`(,time ,ore ,clay ,obsidian ,geode ,ore-robot ,clay-robot ,obsidian-robot ,geode-robot) (dequeue! Q)]) + (cond + [(zero? time) (loop (max geodes geode) time/geodes)] + [(< (add1 geode) (hash-ref time/geodes time geode)) (loop geodes time/geodes)] + [(and (>= ore geode-ore) (>= obsidian geode-obsidian)) + (enqueue*! (sub1 time) + (+ (- ore geode-ore) ore-robot) + (+ clay clay-robot) + (+ (- obsidian geode-obsidian) obsidian-robot) + (+ geode geode-robot) + ore-robot clay-robot obsidian-robot (add1 geode-robot)) + (loop geodes (hash-update time/geodes time #{max % geode} geode))] + [else + (when (and (>= ore obsidian-ore) (>= clay obsidian-clay) (< obsidian-robot geode-obsidian)) + (enqueue*! (sub1 time) + (+ (- ore obsidian-ore) ore-robot) + (+ (- clay obsidian-clay) clay-robot) + (+ obsidian obsidian-robot) + (+ geode geode-robot) + ore-robot clay-robot (add1 obsidian-robot) geode-robot)) + (when (and (>= ore clay-ore) (< clay-robot obsidian-clay)) + (enqueue*! (sub1 time) + (+ (- ore clay-ore) ore-robot) + (+ clay clay-robot) + (+ obsidian obsidian-robot) + (+ geode geode-robot) + ore-robot (add1 clay-robot) obsidian-robot geode-robot)) + (when (and (>= ore ore-ore) (< ore-robot (max clay-ore obsidian-ore geode-ore))) + (enqueue*! (sub1 time) + (+ (- ore ore-ore) ore-robot) + (+ clay clay-robot) + (+ obsidian obsidian-robot) + (+ geode geode-robot) + (add1 ore-robot) clay-robot obsidian-robot geode-robot)) + (enqueue*! (sub1 time) + (+ ore ore-robot) + (+ clay clay-robot) + (+ obsidian obsidian-robot) + (+ geode geode-robot) + ore-robot clay-robot obsidian-robot geode-robot) + (loop geodes (hash-update time/geodes time #{max % geode} geode))]))))) + +(define part1 + (for/sum ([blueprint blueprints]) + (match-define `(,b ,costs ...) blueprint) + (* b (apply (run-blueprint 24) costs)))) + +(define part2 + (for/product ([blueprint (take blueprints 3)]) + (match-define `(,b ,costs ...) blueprint) + (apply (run-blueprint 32) costs))) + +(show-solution part1 part2) \ No newline at end of file