From e8d262b55303a839ff4a80e074e5b768d6d3753a Mon Sep 17 00:00:00 2001 From: xenia Date: Sat, 31 Dec 2022 15:25:23 -0500 Subject: [PATCH] day 11 --- 11.rkt | 124 +++++++++++++++++++++++++++++++++++++++++++++++++ inputs/11 | 55 ++++++++++++++++++++++ inputs/11-test | 27 +++++++++++ 3 files changed, 206 insertions(+) create mode 100644 11.rkt create mode 100644 inputs/11 create mode 100644 inputs/11-test diff --git a/11.rkt b/11.rkt new file mode 100644 index 0000000..ab83d11 --- /dev/null +++ b/11.rkt @@ -0,0 +1,124 @@ +#lang curly-fn racket + +(require "scripts/aoc.rkt" + parser-tools/lex + (prefix-in : parser-tools/lex-sre) + parser-tools/yacc) + +;; solution for day 11 + +(define (part1 input) + (dbg input) + + (define (m-op n) (second (hash-ref input n))) + (define (m-test n) (third (hash-ref input n))) + (define (m-if-t n) (fourth (hash-ref input n))) + (define (m-if-f n) (fifth (hash-ref input n))) + + (define (m-op* n worry) + (define op (m-op n)) + ((match (first op) ['+ +] ['* *]) + (match (second op) ['old worry] [x x]) + (match (third op) ['old worry] [x x]))) + + (define inspect-count (make-hash)) + (for ([k (in-hash-keys input)]) + (hash-set! inspect-count k 0)) + + (for*/fold ([monkeys (for/hash ([(k v) (in-hash input)]) (values k (first v)))]) + ([rnd (in-range 20)] [mky (in-hash-keys input)]) + (define items (hash-ref monkeys mky)) + + (for/fold ([monkeys (hash-set monkeys mky '())]) + ([item (in-list items)]) + (hash-update! inspect-count mky add1) + (define new-worry (~> item (m-op* mky _) (/ _ 3) (floor))) + (define next-mky + (if (zero? (remainder new-worry (m-test mky))) (m-if-t mky) (m-if-f mky))) + (hash-update monkeys next-mky #{append % (list new-worry)}))) + + (match-define (list* top0 top1 rst) (sort (hash-values inspect-count) >)) + (* top0 top1)) + + +(define (part2 input) + (dbg input) + + (define (m-op n) (second (hash-ref input n))) + (define (m-test n) (third (hash-ref input n))) + (define (m-if-t n) (fourth (hash-ref input n))) + (define (m-if-f n) (fifth (hash-ref input n))) + + (define (m-op* n worry) + (define op (m-op n)) + ((match (first op) ['+ +] ['* *]) + (match (second op) ['old worry] [x x]) + (match (third op) ['old worry] [x x]))) + + (define inspect-count (make-hash)) + (for ([k (in-hash-keys input)]) + (hash-set! inspect-count k 0)) + + (define all-monkeys-modulo + (apply lcm (for/list ([mky (in-hash-keys input)]) (m-test mky)))) + + (for*/fold ([monkeys (for/hash ([(k v) (in-hash input)]) (values k (first v)))]) + ([rnd (in-range 10000)] [mky (in-hash-keys input)]) + (define items (hash-ref monkeys mky)) + + (for/fold ([monkeys (hash-set monkeys mky '())]) + ([item (in-list items)]) + (hash-update! inspect-count mky add1) + (define new-worry (~> item (m-op* mky _) (remainder _ all-monkeys-modulo))) + (define next-mky + (if (zero? (remainder new-worry (m-test mky))) (m-if-t mky) (m-if-f mky))) + (hash-update monkeys next-mky #{append % (list new-worry)}))) + + (match-define (list* top0 top1 rst) (sort (hash-values inspect-count) >)) + (* top0 top1)) + +(define (parse fname) + (define-tokens monkey-tokens (NUM)) + (define-empty-tokens monkey-tokens-empty (NEXT START OP OLD PLUS TIMES TEST IF-TRUE IF-FALSE EOF)) + + (define monkey-lex + (lexer + [(eof) (token-EOF)] + ["Monkey" (token-NEXT)] + ["Starting items" (token-START)] + ["Operation: new" (token-OP)] + ["old" (token-OLD)] + ["+" (token-PLUS)] + ["*" (token-TIMES)] + ["Test: divisible by" (token-TEST)] + ["If true: throw to monkey" (token-IF-TRUE)] + ["If false: throw to monkey" (token-IF-FALSE)] + [(:+ numeric) (token-NUM (string->number lexeme))] + [(:or whitespace ":" "=" ",") (monkey-lex input-port)])) + + (define monkey-parse + (parser + [start exps] [end EOF] [error void] + [tokens monkey-tokens monkey-tokens-empty] + [grammar + (exps [(exp) (list $1)] + [(exp exps) (cons $1 $2)]) + (exp [(NEXT NUM START num-list OP op-expr TEST NUM IF-TRUE NUM IF-FALSE NUM) + (list $2 $4 $6 $8 $10 $12)]) + (num-list [(NUM) (list $1)] + [(NUM num-list) (cons $1 $2)]) + (op-expr [(opnd op opnd) (list $2 $1 $3)]) + (opnd [(OLD) 'old] + [(NUM) $1]) + (op [(PLUS) '+] + [(TIMES) '*])])) + + (define file (open-input-file fname)) + (for/hash ([item (in-list (monkey-parse (thunk (monkey-lex file))))]) + (values (first item) (rest item)))) + +(module+ main + (define input (parse "inputs/11")) + (answer 11 1 (time (part1 input))) + (answer 11 2 (time (part2 input))) + (displayln "meow")) diff --git a/inputs/11 b/inputs/11 new file mode 100644 index 0000000..dd12745 --- /dev/null +++ b/inputs/11 @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 61 + Operation: new = old * 11 + Test: divisible by 5 + If true: throw to monkey 7 + If false: throw to monkey 4 + +Monkey 1: + Starting items: 76, 92, 53, 93, 79, 86, 81 + Operation: new = old + 4 + Test: divisible by 2 + If true: throw to monkey 2 + If false: throw to monkey 6 + +Monkey 2: + Starting items: 91, 99 + Operation: new = old * 19 + Test: divisible by 13 + If true: throw to monkey 5 + If false: throw to monkey 0 + +Monkey 3: + Starting items: 58, 67, 66 + Operation: new = old * old + Test: divisible by 7 + If true: throw to monkey 6 + If false: throw to monkey 1 + +Monkey 4: + Starting items: 94, 54, 62, 73 + Operation: new = old + 1 + Test: divisible by 19 + If true: throw to monkey 3 + If false: throw to monkey 7 + +Monkey 5: + Starting items: 59, 95, 51, 58, 58 + Operation: new = old + 3 + Test: divisible by 11 + If true: throw to monkey 0 + If false: throw to monkey 4 + +Monkey 6: + Starting items: 87, 69, 92, 56, 91, 93, 88, 73 + Operation: new = old + 8 + Test: divisible by 3 + If true: throw to monkey 5 + If false: throw to monkey 2 + +Monkey 7: + Starting items: 71, 57, 86, 67, 96, 95 + Operation: new = old + 7 + Test: divisible by 17 + If true: throw to monkey 3 + If false: throw to monkey 1 diff --git a/inputs/11-test b/inputs/11-test new file mode 100644 index 0000000..30e09e5 --- /dev/null +++ b/inputs/11-test @@ -0,0 +1,27 @@ +Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1