From 9dddb473a8a7cb277ec2147a5e09e1dca5f087db Mon Sep 17 00:00:00 2001 From: Jonathan Chan Date: Sat, 7 Dec 2019 19:46:28 -0800 Subject: [PATCH] Day 7: Part 2 done. --- lib.rkt | 6 +++++ src/07.rkt | 67 +++++++++++++++++++++++++++--------------------------- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/lib.rkt b/lib.rkt index 00ca38b..dbfd882 100644 --- a/lib.rkt +++ b/lib.rkt @@ -8,6 +8,7 @@ sum neq? nzero? + rac list-ref* number->digits-reverse number->digits) @@ -40,6 +41,11 @@ (define (nzero? n) (not (zero? n))) +;; rac : (listof any) -> any -> (listof any) +;; Append element to the back of the list. +(define (rac lst v) + (append lst (list v))) + ;; list-ref* : (listof any) -> number -> any -> any ;; Same as list-ref, except a default value is provided ;; if the index is beyond the length of the list. diff --git a/src/07.rkt b/src/07.rkt index 857749e..33d1cf2 100644 --- a/src/07.rkt +++ b/src/07.rkt @@ -1,6 +1,7 @@ #lang racket -(require "../lib.rkt" +(require data/queue + "../lib.rkt" "05.rkt") (define input @@ -15,11 +16,12 @@ (car outE))) (define part1 - (let ([phases (permutations '(0 1 2 3 4))]) - (apply max (append (map amplify phases))))) + (let ([phases (permutations '(0 1 2 3 4))]) + (apply max (append (map amplify phases))))) -;; The IntCode interpreter from Day 5, except it uses threads -(define (exec-pipe program #:ptr [pointer 0] #:thr thread) +(struct state (program pointer input) #:transparent) + +(define (exec-state program #:ptr [pointer 0] #:in [input '()]) (let* ([instruction (list-ref program pointer)] [opcode (remainder instruction 100)] [mode1 (remainder (quotient instruction 100) 10)] @@ -44,45 +46,44 @@ (let* ([arith (match opcode [1 +] [2 *])] [value (arith (v1) (v2))] [program (list-set program (l3) value)]) - (exec-pipe program #:ptr next-pointer #:thr thread))] + (exec-state program #:ptr next-pointer #:in input))] [3 - (let* ([value (thread-receive)] + (let* ([value (car input)] + [input (cdr input)] [program (list-set program (l1) value)]) - (exec-pipe program #:ptr next-pointer #:thr thread))] + (exec-state program #:ptr next-pointer #:in input))] [4 - (thread-send thread (v1)) - (exec-pipe program #:ptr next-pointer #:thr thread)] + (values 'yield (v1) + (state program next-pointer input))] [(or 5 6) (let* ([jump-if (match opcode [5 nzero?] [6 zero?])] [next-pointer (if (jump-if (v1)) (v2) next-pointer)]) - (exec-pipe program #:ptr next-pointer #:thr thread))] + (exec-state program #:ptr next-pointer #:in input))] [(or 7 8) (let* ([lt-eq (match opcode [7 <] [8 =])] [value (if (lt-eq (v1) (v2)) 1 0)] [program (list-set program (l3) value)]) - (exec-pipe program #:ptr next-pointer #:thr thread))] + (exec-state program #:ptr next-pointer #:in input))] [99 - (thread-send thread (values program (thread-receive)))]))) + (values 'halt (car input) + (state program next-pointer (cdr input)))]))) (define (amplify-loop phase) - (let* ([threadE (thread (exec-pipe input #:thr (current-thread)))] - [threadD (thread (exec-pipe input #:thr threadE))] - [threadC (thread (exec-pipe input #:thr threadD))] - [threadB (thread (exec-pipe input #:thr threadC))] - [threadA (thread (exec-pipe input #:thr threadB))]) - (thread-send threadE (fifth phase)) - (thread-send threadD (fourth phase)) - (thread-send threadC (third phase)) - (thread-send threadB (second phase)) - (thread-send threadA (first phase)) - (thread-send threadA 0) - (let loop () - (let ([msg (thread-receive)]) - (if (number? msg) - (begin - (thread-send threadA msg) - (loop)) - (let-values ([(_ output) msg]) - output)))))) + (let* ([amps (map (compose (curry state input 0) list) phase)] + [Q (make-queue)]) + (map (curry enqueue! Q) amps) + (let loop ([signal 0]) + (let* ([amp (dequeue! Q)]) + (let-values ([(code signal amp) + (exec-state (state-program amp) + #:ptr (state-pointer amp) + #:in (rac (state-input amp) signal))]) + (match code + ['yield (enqueue! Q amp) (loop signal)] + ['halt signal])))))) -(show-solution part1 #f) \ No newline at end of file +(define part2 + (let ([phases (permutations '(5 6 7 8 9))]) + (apply max (map amplify-loop phases)))) + +(show-solution part1 part2) \ No newline at end of file