diff --git a/2019/05.rkt b/2019/05.rkt new file mode 100644 index 0000000..80828dc --- /dev/null +++ b/2019/05.rkt @@ -0,0 +1,87 @@ +#lang br +(require racket/file rackunit) + +(define (parse-ptr ptr proc) + (match (for/list ([c (in-string (~r ptr #:min-width 5 #:pad-string "0"))]) + (string->number (string c))) + [(list d4 d3 d2 d1 d0) (cons (+ (* 10 d1) d0) + (for/list ([val (list d2 d3 d4)]) + (if (zero? val) proc values)))])) + +(define (string->regs str) + (list->vector (map string->number (string-split (string-replace str "," " "))))) + +(define (run str starting-input) + (define regs (string->regs str)) + (define (deref ptr) (vector-ref regs ptr)) + (let loop ([ptr 0]) + (match-define (list opcode mode1 mode2 mode3) (parse-ptr (vector-ref regs ptr) deref)) + (match opcode + ;; add & multiply + [(or 1 2) + (vector-set! regs (deref (+ ptr 3)) + ((match opcode [1 +][_ *]) + (mode1 (deref (+ ptr 1))) + (mode2 (deref (+ ptr 2))))) + (loop (+ ptr 4))] + ;; input + [3 (vector-set! regs (mode1 (+ ptr 1)) starting-input) + (loop (+ ptr 2))] + ;; output + [4 (println (vector-ref regs (mode1 (+ ptr 1)))) + (loop (+ ptr 2))] + ;; jump + [(or 5 6) + (if ((match opcode [5 not][_ values]) (zero? (mode1 (deref (+ ptr 1))))) + (loop (mode2 (deref (+ ptr 2)))) + (loop (+ ptr 3)))] + ;; compare + [(or 7 8) + (vector-set! regs (deref (+ ptr 3)) + (if ((match opcode [7 <][_ =]) (mode1 (deref (+ ptr 1))) (mode2 (deref (+ ptr 2)))) + 1 + 0)) + (loop (+ ptr 4))] + ;; terminate + [99 (void)] + [_ (error 'unknown-opcode)]))) + +(define-syntax-rule (last-output-line func) + (last (map string->number (string-split (with-output-to-string (λ () func)))))) + +(check-eq? (last-output-line (run "3,0,4,0,99" 42)) 42) +;; 1 +(check-eq? + (last-output-line (run (file->string "05.rktd") 1)) + 15386262) + +(check-eq? (last-output-line (run "3,9,8,9,10,9,4,9,99,-1,8" 8)) 1) +(check-eq? (last-output-line (run "3,9,7,9,10,9,4,9,99,-1,8" 8)) 0) +(check-eq? (last-output-line (run "3,3,1108,-1,8,3,4,3,99" 8)) 1) +(check-eq? (last-output-line (run "3,3,1107,-1,8,3,4,3,99" 8)) 0) +(check-eq? (last-output-line (run "3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9" 0)) 0) +(check-eq? (last-output-line (run "3,3,1105,-1,9,1101,0,0,12,4,12,99,1" 0)) 0) + +(check-eq? + (last-output-line + (run "3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31, +1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104, +999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99" 0)) + 999) +(check-eq? + (last-output-line + (run "3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31, +1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104, +999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99" 8)) + 1000) +(check-eq? + (last-output-line + (run "3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31, +1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104, +999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99" 10)) + 1001) + +;; 2 +(check-eq? + (last-output-line (run (file->string "05.rktd") 5)) + 10376124) \ No newline at end of file diff --git a/2019/05.rktd b/2019/05.rktd new file mode 100644 index 0000000..28abfc0 --- /dev/null +++ b/2019/05.rktd @@ -0,0 +1 @@ +3,225,1,225,6,6,1100,1,238,225,104,0,1101,65,39,225,2,14,169,224,101,-2340,224,224,4,224,1002,223,8,223,101,7,224,224,1,224,223,223,1001,144,70,224,101,-96,224,224,4,224,1002,223,8,223,1001,224,2,224,1,223,224,223,1101,92,65,225,1102,42,8,225,1002,61,84,224,101,-7728,224,224,4,224,102,8,223,223,1001,224,5,224,1,223,224,223,1102,67,73,224,1001,224,-4891,224,4,224,102,8,223,223,101,4,224,224,1,224,223,223,1102,54,12,225,102,67,114,224,101,-804,224,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1101,19,79,225,1101,62,26,225,101,57,139,224,1001,224,-76,224,4,224,1002,223,8,223,1001,224,2,224,1,224,223,223,1102,60,47,225,1101,20,62,225,1101,47,44,224,1001,224,-91,224,4,224,1002,223,8,223,101,2,224,224,1,224,223,223,1,66,174,224,101,-70,224,224,4,224,102,8,223,223,1001,224,6,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,108,226,226,224,102,2,223,223,1005,224,329,101,1,223,223,1107,226,677,224,1002,223,2,223,1005,224,344,101,1,223,223,8,226,677,224,102,2,223,223,1006,224,359,101,1,223,223,108,677,677,224,1002,223,2,223,1005,224,374,1001,223,1,223,1108,226,677,224,1002,223,2,223,1005,224,389,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,404,1001,223,1,223,1108,677,677,224,102,2,223,223,1006,224,419,1001,223,1,223,1008,226,677,224,102,2,223,223,1005,224,434,101,1,223,223,107,677,677,224,102,2,223,223,1006,224,449,1001,223,1,223,1007,226,677,224,102,2,223,223,1005,224,464,101,1,223,223,7,677,226,224,102,2,223,223,1005,224,479,101,1,223,223,1007,226,226,224,102,2,223,223,1005,224,494,101,1,223,223,7,677,677,224,102,2,223,223,1006,224,509,101,1,223,223,1008,677,677,224,1002,223,2,223,1006,224,524,1001,223,1,223,108,226,677,224,1002,223,2,223,1006,224,539,101,1,223,223,8,226,226,224,102,2,223,223,1006,224,554,101,1,223,223,8,677,226,224,102,2,223,223,1005,224,569,1001,223,1,223,1108,677,226,224,1002,223,2,223,1006,224,584,101,1,223,223,1107,677,226,224,1002,223,2,223,1005,224,599,101,1,223,223,107,226,226,224,102,2,223,223,1006,224,614,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,629,1001,223,1,223,107,677,226,224,1002,223,2,223,1005,224,644,1001,223,1,223,1107,677,677,224,102,2,223,223,1006,224,659,101,1,223,223,1008,226,226,224,1002,223,2,223,1006,224,674,1001,223,1,223,4,223,99,226 \ No newline at end of file