From d0f827554341906955110a98a1dac35de9ce5210 Mon Sep 17 00:00:00 2001 From: Jonathan Chan Date: Sat, 7 Dec 2019 00:17:16 -0800 Subject: [PATCH] Day 7: Part 1 complete, part 2 not working. --- input/07.txt | 1 + src/05.rkt | 43 +++++++++++++++++-------- src/07.rkt | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 input/07.txt create mode 100644 src/07.rkt diff --git a/input/07.txt b/input/07.txt new file mode 100644 index 0000000..2236f2f --- /dev/null +++ b/input/07.txt @@ -0,0 +1 @@ +3,8,1001,8,10,8,105,1,0,0,21,42,63,76,101,114,195,276,357,438,99999,3,9,101,2,9,9,102,5,9,9,1001,9,3,9,1002,9,5,9,4,9,99,3,9,101,4,9,9,102,5,9,9,1001,9,5,9,102,2,9,9,4,9,99,3,9,1001,9,3,9,1002,9,5,9,4,9,99,3,9,1002,9,2,9,101,5,9,9,102,3,9,9,101,2,9,9,1002,9,3,9,4,9,99,3,9,101,3,9,9,102,2,9,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,99 diff --git a/src/05.rkt b/src/05.rkt index 2acb497..8ca8754 100644 --- a/src/05.rkt +++ b/src/05.rkt @@ -2,6 +2,9 @@ (require "../lib.rkt") +(provide string->program + exec) + ;; string->program : string -> (listof number) ;; A program is a list of numbers, ;; which are sequences of instructions and parameters. @@ -11,7 +14,13 @@ (define input (string->program (car (problem-input 5)))) -;; exec : number -> program -> program +;; leave-one : (listof any) -> (listof any) +;; If the list has one or fewer elements, return the list; +;; otherwise, return the rest of the list +(define (leave-one lst) + (if (<= (length lst) 1) lst (cdr lst))) + +;; exec : program -> number -> (listof number) -> (listof number) -> program ;; An encoded instruction is anywhere from 1 to 4 digits long. ;; The last one or two digits represent the opcode, which can be: ;; - 1/2: add/multiply parameters 1 and 2 and store in parameter 3 @@ -27,7 +36,7 @@ ;; If the mode is 0, the value at pointer is an address. ;; If the mode is 1, the value at pointer is immediate. ;; Note that leading zeroes in the encoded instruction are omitted. -(define (exec pointer program) +(define (exec program #:ptr [pointer 0] #:in [input '()] #:out [output '()]) (let* ([instruction (list-ref program pointer)] [opcode (remainder instruction 100)] [mode1 (remainder (quotient instruction 100) 10)] @@ -52,24 +61,32 @@ (let* ([arith (match opcode [1 +] [2 *])] [value (arith (v1) (v2))] [program (list-set program (l3) value)]) - (exec next-pointer program))] + (exec program #:ptr next-pointer #:in input #:out output))] [3 - (let* ([program (list-set program (l1) (read))]) - (exec next-pointer program))] + (let* ([value (car input)] + [input (cdr input)] + [program (list-set program (l1) value)]) + (exec program #:ptr next-pointer #:in input #:out output))] [4 - (displayln (v1)) - (exec next-pointer program)] + (let* ([output (append output `(,(v1)))]) + (exec program #:ptr next-pointer #:in input #:out output))] [(or 5 6) (let* ([jump-if (match opcode [5 nzero?] [6 zero?])] [next-pointer (if (jump-if (v1)) (v2) next-pointer)]) - (exec next-pointer program))] + (exec program #:ptr next-pointer #:in input #:out output))] [(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 next-pointer program))] - [99 program]))) + (exec program #:ptr next-pointer #:in input #:out output))] + [99 (values program output)]))) -(define (execute) - (exec 0 input) - (void)) \ No newline at end of file +(define part1 + (let-values ([(_ out) (exec input #:in '(1))]) + (last out))) + +(define part2 + (let-values ([(_ out) (exec input #:in '(5))]) + (last out))) + +(show-solution part1 part2) \ No newline at end of file diff --git a/src/07.rkt b/src/07.rkt new file mode 100644 index 0000000..857749e --- /dev/null +++ b/src/07.rkt @@ -0,0 +1,88 @@ +#lang racket + +(require "../lib.rkt" + "05.rkt") + +(define input + (string->program (car (problem-input 7)))) + +(define (amplify phase) + (let*-values ([(_ outA) (exec input #:in (list (first phase) 0))] + [(_ outB) (exec input #:in (list (second phase) (car outA)))] + [(_ outC) (exec input #:in (list (third phase) (car outB)))] + [(_ outD) (exec input #:in (list (fourth phase) (car outC)))] + [(_ outE) (exec input #:in (list (fifth phase) (car outD)))]) + (car outE))) + +(define part1 + (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) + (let* ([instruction (list-ref program pointer)] + [opcode (remainder instruction 100)] + [mode1 (remainder (quotient instruction 100) 10)] + [mode2 (remainder (quotient instruction 1000) 10)] + [mode3 (remainder (quotient instruction 10000) 10)] + ;; l* : call to get write location from program + [l1 (λ () (if (zero? mode1) (list-ref program (+ pointer 1)) (+ pointer 1)))] + [l2 (λ () (if (zero? mode2) (list-ref program (+ pointer 2)) (+ pointer 2)))] + [l3 (λ () (if (zero? mode3) (list-ref program (+ pointer 3)) (+ pointer 3)))] + ;; v* : call to read values from program + [v1 (λ () (list-ref program (l1)))] + [v2 (λ () (list-ref program (l2)))] + [v3 (λ () (list-ref program (l3)))] + [next-pointer + (match opcode + [(or 1 2 7 8) (+ pointer 4)] + [(or 3 4) (+ pointer 2)] + [(or 5 6) (+ pointer 3)] + [99 (+ pointer 1)])]) + (match opcode + [(or 1 2) + (let* ([arith (match opcode [1 +] [2 *])] + [value (arith (v1) (v2))] + [program (list-set program (l3) value)]) + (exec-pipe program #:ptr next-pointer #:thr thread))] + [3 + (let* ([value (thread-receive)] + [program (list-set program (l1) value)]) + (exec-pipe program #:ptr next-pointer #:thr thread))] + [4 + (thread-send thread (v1)) + (exec-pipe program #:ptr next-pointer #:thr thread)] + [(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))] + [(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))] + [99 + (thread-send thread (values program (thread-receive)))]))) + +(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)))))) + +(show-solution part1 #f) \ No newline at end of file