Day 7: Part 1 complete, part 2 not working.
This commit is contained in:
parent
7df8cc0336
commit
2d67f04d6b
|
@ -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
|
43
src/05.rkt
43
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))
|
||||
(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)
|
|
@ -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)
|
Loading…
Reference in New Issue