~theothornhill/advent

6dff064735d1feaecae8f2461683a60fd9b51acd — Theodor Thornhill 4 years ago f5f42f0
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)))