Day 5.
This commit is contained in:
parent
6ad4c77ce1
commit
ee4ca7279d
|
@ -0,0 +1 @@
|
||||||
|
3,225,1,225,6,6,1100,1,238,225,104,0,1002,188,27,224,1001,224,-2241,224,4,224,102,8,223,223,1001,224,6,224,1,223,224,223,101,65,153,224,101,-108,224,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,1,158,191,224,101,-113,224,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1001,195,14,224,1001,224,-81,224,4,224,1002,223,8,223,101,3,224,224,1,224,223,223,1102,47,76,225,1102,35,69,224,101,-2415,224,224,4,224,102,8,223,223,101,2,224,224,1,224,223,223,1101,32,38,224,101,-70,224,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,1102,66,13,225,1102,43,84,225,1101,12,62,225,1102,30,35,225,2,149,101,224,101,-3102,224,224,4,224,102,8,223,223,101,4,224,224,1,223,224,223,1101,76,83,225,1102,51,51,225,1102,67,75,225,102,42,162,224,101,-1470,224,224,4,224,102,8,223,223,101,1,224,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1108,226,677,224,1002,223,2,223,1005,224,329,101,1,223,223,108,226,226,224,1002,223,2,223,1005,224,344,1001,223,1,223,1107,677,226,224,1002,223,2,223,1006,224,359,101,1,223,223,1008,226,226,224,1002,223,2,223,1005,224,374,101,1,223,223,8,226,677,224,102,2,223,223,1006,224,389,101,1,223,223,7,226,677,224,1002,223,2,223,1005,224,404,1001,223,1,223,7,226,226,224,1002,223,2,223,1005,224,419,101,1,223,223,107,226,677,224,1002,223,2,223,1005,224,434,101,1,223,223,107,226,226,224,1002,223,2,223,1005,224,449,1001,223,1,223,1107,226,677,224,102,2,223,223,1006,224,464,1001,223,1,223,1007,677,226,224,1002,223,2,223,1006,224,479,1001,223,1,223,1107,677,677,224,1002,223,2,223,1005,224,494,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,509,101,1,223,223,7,677,226,224,1002,223,2,223,1005,224,524,1001,223,1,223,1008,677,226,224,102,2,223,223,1005,224,539,1001,223,1,223,1108,226,226,224,102,2,223,223,1005,224,554,101,1,223,223,107,677,677,224,102,2,223,223,1006,224,569,1001,223,1,223,1007,226,226,224,102,2,223,223,1006,224,584,101,1,223,223,8,677,677,224,102,2,223,223,1005,224,599,1001,223,1,223,108,677,677,224,1002,223,2,223,1005,224,614,101,1,223,223,108,226,677,224,102,2,223,223,1005,224,629,101,1,223,223,8,677,226,224,102,2,223,223,1006,224,644,1001,223,1,223,1007,677,677,224,1002,223,2,223,1006,224,659,1001,223,1,223,1008,677,677,224,1002,223,2,223,1005,224,674,101,1,223,223,4,223,99,226
|
36
lib.rkt
36
lib.rkt
|
@ -5,7 +5,12 @@
|
||||||
|
|
||||||
(provide problem-input
|
(provide problem-input
|
||||||
show-solution
|
show-solution
|
||||||
sum)
|
sum
|
||||||
|
neq?
|
||||||
|
nzero?
|
||||||
|
list-ref*
|
||||||
|
number->digits-reverse
|
||||||
|
number->digits)
|
||||||
|
|
||||||
;; IO helpers
|
;; IO helpers
|
||||||
|
|
||||||
|
@ -26,3 +31,32 @@
|
||||||
|
|
||||||
;; sum : (listof number) -> number
|
;; sum : (listof number) -> number
|
||||||
(define (sum ns) (apply + ns))
|
(define (sum ns) (apply + ns))
|
||||||
|
|
||||||
|
;; neq : any -> any -> boolean
|
||||||
|
(define (neq? v1 v2)
|
||||||
|
(not (eq? v1 v2)))
|
||||||
|
|
||||||
|
;; nzero? : number -> boolean
|
||||||
|
(define (nzero? n)
|
||||||
|
(not (zero? n)))
|
||||||
|
|
||||||
|
;; 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.
|
||||||
|
(define (list-ref* lst pos failure-result)
|
||||||
|
(if (>= pos (length lst))
|
||||||
|
failure-result
|
||||||
|
(list-ref lst pos)))
|
||||||
|
|
||||||
|
;; number->digits-reverse : number -> (listof number)
|
||||||
|
;; Return the digits of the given number in reverse order (i.e. RTL)
|
||||||
|
(define (number->digits-reverse n)
|
||||||
|
(if (< n 10)
|
||||||
|
(list n)
|
||||||
|
(cons (remainder n 10)
|
||||||
|
(number->digits-reverse (quotient n 10)))))
|
||||||
|
|
||||||
|
;; number->digits : number -> (listof number)
|
||||||
|
;; Return the digits of the given number (LTR)
|
||||||
|
(define (number->digits n)
|
||||||
|
(reverse (number->digits-reverse n)))
|
|
@ -0,0 +1,98 @@
|
||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require "../lib.rkt")
|
||||||
|
|
||||||
|
;; string->program : string -> (listof number)
|
||||||
|
;; A program is a list of numbers,
|
||||||
|
;; which are sequences of instructions and parameters.
|
||||||
|
(define (string->program str)
|
||||||
|
(map string->number (string-split str ",")))
|
||||||
|
|
||||||
|
(define input
|
||||||
|
(string->program (car (problem-input 5))))
|
||||||
|
|
||||||
|
(struct instruction
|
||||||
|
(opcode mode1 mode2 mode3)
|
||||||
|
#:transparent)
|
||||||
|
|
||||||
|
;; fetch : number -> number -> program -> program
|
||||||
|
;; If the mode is 0, the value at pointer is an address.
|
||||||
|
;; If the mode is 1, the value at pointer is immediate.
|
||||||
|
;; Return the value at that address or the immediate.
|
||||||
|
(define (fetch mode pointer program)
|
||||||
|
(if (zero? mode)
|
||||||
|
(list-ref program (list-ref program pointer))
|
||||||
|
(list-ref program pointer)))
|
||||||
|
|
||||||
|
;; write : number -> number -> program -> program
|
||||||
|
;; Write the value into the location at pointer.
|
||||||
|
(define (write value pointer program)
|
||||||
|
(list-set program (list-ref program pointer) value))
|
||||||
|
|
||||||
|
;; decode-instr : number -> instruction
|
||||||
|
;; 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
|
||||||
|
;; - 3: take an input and store in parameter 1
|
||||||
|
;; - 4: output parameter 1
|
||||||
|
;; - 5/6: if parameter 1 is non-zero/zero, jump to parameter 2
|
||||||
|
;; - 7/8: if parameter 1 is less-than/equal-to parameter 2,
|
||||||
|
;; store 1 else store 0 in parameter 3
|
||||||
|
;; - 99: halt
|
||||||
|
;; The next few digits to the left of the opcode (if any) represent
|
||||||
|
;; the mode of each parameter, with that of parameter i in the digit
|
||||||
|
;; i digits to the left of the opcode.
|
||||||
|
;; Note that leading zeroes in the encoded instruction are omitted.
|
||||||
|
(define (decode-instr n)
|
||||||
|
(let* ([cs (number->digits-reverse n)]
|
||||||
|
[ops '(1 2 3 4 5 6 7 8 99)]
|
||||||
|
[op? (λ (v) (member v ops))])
|
||||||
|
(match cs
|
||||||
|
[(list-rest (? op? op) rest)
|
||||||
|
(instruction op
|
||||||
|
(list-ref* rest 1 0)
|
||||||
|
(list-ref* rest 2 0)
|
||||||
|
(list-ref* rest 3 0))]
|
||||||
|
[(list-rest 9 9 _)
|
||||||
|
(instruction 99 0 0 0)])))
|
||||||
|
|
||||||
|
;; exec : number -> program -> program
|
||||||
|
(define (exec pointer program)
|
||||||
|
(let* ([instr (decode-instr (list-ref program pointer))]
|
||||||
|
[v1 (λ () (fetch (instruction-mode1 instr) (+ pointer 1) program))]
|
||||||
|
[v2 (λ () (fetch (instruction-mode2 instr) (+ pointer 2) program))]
|
||||||
|
[next-pointer
|
||||||
|
(λ (op) (match op
|
||||||
|
[(or 1 2 7 8) (+ pointer 4)]
|
||||||
|
[(or 3 4) (+ pointer 2)]
|
||||||
|
[(or 5 6) (+ pointer 3)]))]
|
||||||
|
[arith
|
||||||
|
(λ (op) (match op [1 +] [2 *]))]
|
||||||
|
[jump-if
|
||||||
|
(λ (op) (match op [5 nzero?] [6 zero?]))]
|
||||||
|
[lt-eq
|
||||||
|
(λ (op) (match op [7 <] [8 =]))])
|
||||||
|
(match (instruction-opcode instr)
|
||||||
|
[(and op (or 1 2))
|
||||||
|
(let* ([program (write ((arith op) (v1) (v2)) (+ pointer 3) program)])
|
||||||
|
(exec (next-pointer op) program))]
|
||||||
|
[3
|
||||||
|
(let* ([input (read)]
|
||||||
|
[program (write input (+ pointer 1) program)])
|
||||||
|
(exec (next-pointer 3) program))]
|
||||||
|
[4
|
||||||
|
(displayln (v1))
|
||||||
|
(exec (next-pointer 4) program)]
|
||||||
|
[(and op (or 5 6))
|
||||||
|
(let* ([pointer (if ((jump-if op) (v1)) (v2)
|
||||||
|
(next-pointer op))])
|
||||||
|
(exec pointer program))]
|
||||||
|
[(and op (or 7 8))
|
||||||
|
(let* ([v3 (if ((lt-eq op) (v1) (v2)) 1 0)]
|
||||||
|
[program (write v3 (+ pointer 3) program)])
|
||||||
|
(exec (next-pointer op) program))]
|
||||||
|
[99 program])))
|
||||||
|
|
||||||
|
(define (execute)
|
||||||
|
(exec 0 input)
|
||||||
|
(void))
|
Loading…
Reference in New Issue