Factor out intcode computer
2 files changed, 12 insertions(+), 55 deletions(-) M day2-input.txt M day2.lisp
M day2-input.txt => day2-input.txt +1 -1
@@ 1,1 1,1 @@ 1,12,2,3,1,1,2,3,1,3,4,3,1,5,0,3,2,10,1,19,1,5,19,23,1,23,5,27,2,27,10,31,1,5,31,35,2,35,6,39,1,6,39,43,2,13,43,47,2,9,47,51,1,6,51,55,1,55,9,59,2,6,59,63,1,5,63,67,2,67,13,71,1,9,71,75,1,75,9,79,2,79,10,83,1,6,83,87,1,5,87,91,1,6,91,95,1,95,13,99,1,10,99,103,2,6,103,107,1,107,5,111,1,111,13,115,1,115,13,119,1,13,119,123,2,123,13,127,1,127,6,131,1,131,9,135,1,5,135,139,2,139,6,143,2,6,143,147,1,5,147,151,1,151,2,155,1,9,155,0,99,2,14,0,0,, 1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,10,1,19,1,5,19,23,1,23,5,27,2,27,10,31,1,5,31,35,2,35,6,39,1,6,39,43,2,13,43,47,2,9,47,51,1,6,51,55,1,55,9,59,2,6,59,63,1,5,63,67,2,67,13,71,1,9,71,75,1,75,9,79,2,79,10,83,1,6,83,87,1,5,87,91,1,6,91,95,1,95,13,99,1,10,99,103,2,6,103,107,1,107,5,111,1,111,13,115,1,115,13,119,1,13,119,123,2,123,13,127,1,127,6,131,1,131,9,135,1,5,135,139,2,139,6,143,2,6,143,147,1,5,147,151,1,151,2,155,1,9,155,0,99,2,14,0,0
M day2.lisp => day2.lisp +11 -54
@@ 1,60 1,17 @@ ;; Day 2: (defun read-op-codes (filename) (with-open-file (stream filename) (loop for num = (read-delimited-list #\, stream) while num append num))) (in-package :intcode) (defparameter *instruction-pointer* 0) (defparameter *increment-counter* 4) (defun actions (instruction) (ecase instruction (1 'add) (2 'mult) (99 'halt))) (defmacro access (memory address) `(aref ,memory (aref ,memory ,address))) (defun get-next-action (memory) (actions (aref memory *instruction-pointer*))) (defmacro define-instruction (name operation) `(defun ,name (memory) (let ((x (+ *instruction-pointer* 1)) (y (+ *instruction-pointer* 2)) (z (+ *instruction-pointer* 3))) (incf *instruction-pointer* *increment-counter*) (setf (access memory z) (,operation (access memory x) (access memory y)))))) (define-instruction add +) (define-instruction mult *) (defun halt (memory) (declare (ignorable memory)) memory) (defun run-computer (&rest args) (setf *instruction-pointer* 0) (do* ((memory (make-array (length args) :initial-contents args)) (action (get-next-action memory) (get-next-action memory))) ((eql action 'halt) memory) (funcall action memory))) (defun run (filename noun verb) (with-intcode (memory) (init-intcode filename) (setf (aref memory 1) noun) (setf (aref memory 2) verb) (run-intcode))) (defun find-result (filename target) (let ((op-codes (read-op-codes filename))) (loop named r for noun below (length op-codes) do (loop for verb below (length op-codes) do (rplaca (cdr op-codes) noun) (rplaca (cddr op-codes) verb) (if (= (aref (apply #'computer op-codes) 0) target) (with-intcode (memory memory-size) (loop named r for noun below 100 do (loop for verb below 100 do (if (= (run filename noun verb) target) (return-from r (+ (* 100 noun) verb))))))) (assert (equalp (run-computer 1 0 0 0 99) #(2 0 0 0 99))) (assert (equalp (run-computer 2 3 0 3 99) #(2 3 0 6 99))) (assert (equalp (run-computer 2 4 4 5 99 0) #(2 4 4 5 99 9801))) (assert (equalp (run-computer 1 1 1 4 99 5 6 0 99) #(30 1 1 4 2 5 6 0 99)))