2019-12-07 08:17:16 +00:00
|
|
|
#lang racket
|
|
|
|
|
2019-12-08 03:46:28 +00:00
|
|
|
(require data/queue
|
|
|
|
"../lib.rkt"
|
2019-12-07 08:17:16 +00:00
|
|
|
"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
|
2019-12-08 03:46:28 +00:00
|
|
|
(let ([phases (permutations '(0 1 2 3 4))])
|
|
|
|
(apply max (append (map amplify phases)))))
|
2019-12-07 08:17:16 +00:00
|
|
|
|
2019-12-08 03:46:28 +00:00
|
|
|
(struct state (program pointer input) #:transparent)
|
|
|
|
|
|
|
|
(define (exec-state program #:ptr [pointer 0] #:in [input '()])
|
2019-12-07 08:17:16 +00:00
|
|
|
(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)])
|
2019-12-08 03:46:28 +00:00
|
|
|
(exec-state program #:ptr next-pointer #:in input))]
|
2019-12-07 08:17:16 +00:00
|
|
|
[3
|
2019-12-08 03:46:28 +00:00
|
|
|
(let* ([value (car input)]
|
|
|
|
[input (cdr input)]
|
2019-12-07 08:17:16 +00:00
|
|
|
[program (list-set program (l1) value)])
|
2019-12-08 03:46:28 +00:00
|
|
|
(exec-state program #:ptr next-pointer #:in input))]
|
2019-12-07 08:17:16 +00:00
|
|
|
[4
|
2019-12-08 03:46:28 +00:00
|
|
|
(values 'yield (v1)
|
|
|
|
(state program next-pointer input))]
|
2019-12-07 08:17:16 +00:00
|
|
|
[(or 5 6)
|
|
|
|
(let* ([jump-if (match opcode [5 nzero?] [6 zero?])]
|
|
|
|
[next-pointer (if (jump-if (v1)) (v2) next-pointer)])
|
2019-12-08 03:46:28 +00:00
|
|
|
(exec-state program #:ptr next-pointer #:in input))]
|
2019-12-07 08:17:16 +00:00
|
|
|
[(or 7 8)
|
|
|
|
(let* ([lt-eq (match opcode [7 <] [8 =])]
|
|
|
|
[value (if (lt-eq (v1) (v2)) 1 0)]
|
|
|
|
[program (list-set program (l3) value)])
|
2019-12-08 03:46:28 +00:00
|
|
|
(exec-state program #:ptr next-pointer #:in input))]
|
2019-12-07 08:17:16 +00:00
|
|
|
[99
|
2019-12-08 03:46:28 +00:00
|
|
|
(values 'halt (car input)
|
|
|
|
(state program next-pointer (cdr input)))])))
|
2019-12-07 08:17:16 +00:00
|
|
|
|
|
|
|
(define (amplify-loop phase)
|
2019-12-08 03:46:28 +00:00
|
|
|
(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]))))))
|
|
|
|
|
|
|
|
(define part2
|
|
|
|
(let ([phases (permutations '(5 6 7 8 9))])
|
|
|
|
(apply max (map amplify-loop phases))))
|
2019-12-07 08:17:16 +00:00
|
|
|
|
2019-12-08 03:46:28 +00:00
|
|
|
(show-solution part1 part2)
|