~theothornhill/advent

e4bab0966b55315e14280e4f857813733a21c96a — Theodor Thornhill 4 years ago 65e7db2
Day 5 passing
3 files changed, 129 insertions(+), 25 deletions(-)

A day5-input.txt
A day5-input2.txt
M intcode.lisp
A day5-input.txt => day5-input.txt +1 -0
@@ 0,0 1,1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1002,43,69,224,101,-483,224,224,4,224,1002,223,8,223,1001,224,5,224,1,224,223,223,1101,67,60,225,1102,5,59,225,1101,7,16,225,1102,49,72,225,101,93,39,224,101,-98,224,224,4,224,102,8,223,223,1001,224,6,224,1,224,223,223,1102,35,82,225,2,166,36,224,101,-4260,224,224,4,224,102,8,223,223,101,5,224,224,1,223,224,223,102,66,48,224,1001,224,-4752,224,4,224,102,8,223,223,1001,224,2,224,1,223,224,223,1001,73,20,224,1001,224,-55,224,4,224,102,8,223,223,101,7,224,224,1,223,224,223,1102,18,41,224,1001,224,-738,224,4,224,102,8,223,223,101,6,224,224,1,224,223,223,1101,68,71,225,1102,5,66,225,1101,27,5,225,1101,54,63,224,1001,224,-117,224,4,224,102,8,223,223,1001,224,2,224,1,223,224,223,1,170,174,224,101,-71,224,224,4,224,1002,223,8,223,1001,224,4,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,1007,226,226,224,1002,223,2,223,1006,224,329,1001,223,1,223,1007,226,677,224,102,2,223,223,1006,224,344,1001,223,1,223,108,677,677,224,102,2,223,223,1005,224,359,1001,223,1,223,1007,677,677,224,1002,223,2,223,1006,224,374,101,1,223,223,8,677,226,224,1002,223,2,223,1006,224,389,101,1,223,223,7,226,226,224,1002,223,2,223,1005,224,404,101,1,223,223,7,677,226,224,102,2,223,223,1005,224,419,1001,223,1,223,8,226,677,224,1002,223,2,223,1005,224,434,101,1,223,223,1008,226,677,224,102,2,223,223,1006,224,449,1001,223,1,223,7,226,677,224,1002,223,2,223,1006,224,464,1001,223,1,223,108,677,226,224,102,2,223,223,1005,224,479,101,1,223,223,108,226,226,224,1002,223,2,223,1006,224,494,101,1,223,223,8,226,226,224,1002,223,2,223,1005,224,509,1001,223,1,223,1107,677,226,224,102,2,223,223,1005,224,524,1001,223,1,223,1107,226,226,224,102,2,223,223,1005,224,539,1001,223,1,223,1108,677,677,224,1002,223,2,223,1006,224,554,101,1,223,223,107,226,677,224,102,2,223,223,1005,224,569,1001,223,1,223,1108,226,677,224,1002,223,2,223,1005,224,584,1001,223,1,223,1107,226,677,224,1002,223,2,223,1005,224,599,1001,223,1,223,1008,226,226,224,1002,223,2,223,1005,224,614,101,1,223,223,107,226,226,224,102,2,223,223,1006,224,629,1001,223,1,223,1008,677,677,224,1002,223,2,223,1006,224,644,101,1,223,223,107,677,677,224,1002,223,2,223,1005,224,659,101,1,223,223,1108,677,226,224,1002,223,2,223,1006,224,674,1001,223,1,223,4,223,99,226

A day5-input2.txt => day5-input2.txt +1 -0
@@ 0,0 1,1 @@
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

M intcode.lisp => intcode.lisp +127 -25
@@ 12,9 12,6 @@
  ((memory
    :initarg :memory
    :accessor memory)
   (memory-size
    :initarg :memory-size
    :accessor memory-size)
   (instruction-pointer
    :initarg :instruction-pointer
    :initform 0


@@ 34,39 31,144 @@
  `(with-slots ,rest *intcode*
     ,@body))

(defparameter *increment-counter* 4)
(defun parse-instruction (instruction)
  (let ((i (format nil "~5,'0d" instruction)))
    ;; KLUDGE: This thing does too many things.
    ;; Handle case for halt value better, and maybe split the mv-bind?
    (values (if (string= (subseq i 3) "99")
                99
                (parse-integer (subseq i 4)))
            (reverse (mapcar #'parse-integer
                             (split "" (subseq i 0 3)))))))

(defmacro with-modes (&body body)
  "Anaphoric MODES variables"
  `(let* ((modes (nth-value
                  1 (parse-instruction
                     (get-mem 1 (instruction-pointer *intcode*)))))
          (first-param-mode (car modes))
          (second-param-mode (cadr modes)))
     ,@body))

(defmacro with-x (&body body)
  "Anaphoric X value"
  `(let ((x (+ (instruction-pointer *intcode*) 1)))
     ,@body))

(defmacro with-xy (&body body)
  "Anaphoric X Y values"
  `(let ((x (+ (instruction-pointer *intcode*) 1))
         (y (+ (instruction-pointer *intcode*) 2)))
     ,@body))

(defmacro with-xyz (&body body)
  "Anaphoric X Y Z values"
  `(let ((x (+ (instruction-pointer *intcode*) 1))
         (y (+ (instruction-pointer *intcode*) 2))
         (z (+ (instruction-pointer *intcode*) 3)))
     ,@body))

(defun actions (instruction)
  (ecase instruction
(defun instruction (instruction)
  (ecase (parse-instruction instruction)
    (1 'add)
    (2 'mult)
    (3 'input)
    (4 'output)
    (5 'jump-if-true)
    (6 'jump-if-false)
    (7 'less-than)
    (8 'equals)
    (99 'halt)))

(defun get-next-action ()
(defun next-instruction ()
  (with-intcode (memory instruction-pointer)
    (actions (aref memory instruction-pointer))))

(defmacro def-instruction (name operation)
  `(defun ,name ()
    (with-intcode (instruction-pointer memory)
      (let ((x (+ instruction-pointer 1))
            (y (+ instruction-pointer 2))
            (z (+ instruction-pointer 3)))
        (incf instruction-pointer *increment-counter*)
        (setf (aref memory (aref memory z))
              (,operation (aref memory (aref memory x))
                 (aref memory (aref memory y))))))))

(def-instruction add +)
(def-instruction mult *)
    (instruction (aref memory instruction-pointer))))

(defun (setf set-mem) (value position)
  (with-intcode (memory)
    (setf (aref memory (aref memory position)) value)))

(defun get-mem (mode position)
  (with-intcode (memory)
    (if (zerop mode)
        (aref memory (aref memory position))
        (aref memory position))))

(defmacro with-instruction-pointer (&body body)
  `(with-intcode (instruction-pointer)
     ,@body))

(defmacro with-binary-expr (&body body)
  `(with-instruction-pointer
     (with-xyz
       (with-modes
         ,@body
         (incf instruction-pointer 4)))))

(defmacro with-jump (&body body)
  `(with-instruction-pointer
     (with-xy
       (with-modes
         ,@body
         (incf instruction-pointer 3)))))

(defmacro with-io (&body body)
  `(with-instruction-pointer
     (with-x
       ,@body
       (incf instruction-pointer 2))))

(defun add ()
  (with-binary-expr
    (setf (set-mem z) (+ (get-mem first-param-mode x)
                         (get-mem second-param-mode y)))))

(defun mult ()
  (with-binary-expr
    (setf (set-mem z) (* (get-mem first-param-mode x)
                         (get-mem second-param-mode y)))))

(defun input ()
  (with-io
    (setf (set-mem x) (parse-integer (read-line)))))

(defun output ()
  (with-io
    (print (get-mem 0 x))))

(defun jump-if-true ()
  (with-jump
    (unless (zerop (get-mem first-param-mode x))
      (setf instruction-pointer (get-mem second-param-mode y))
      (return-from jump-if-true))))

(defun jump-if-false ()
  (with-jump
    (when (zerop (get-mem first-param-mode x))
      (setf instruction-pointer (get-mem second-param-mode y))
      (return-from jump-if-false))))

(defun less-than ()
  (with-binary-expr
    (if (< (get-mem first-param-mode x)
           (get-mem second-param-mode y))
        (setf (set-mem z) 1)
        (setf (set-mem z) 0))))

(defun equals ()
  (with-binary-expr
    (if (= (get-mem first-param-mode x)
           (get-mem second-param-mode y))
        (setf (set-mem z) 1)
        (setf (set-mem z) 0))))

(defun halt () :halt)

(defun init-intcode (filename)
  (let* ((op-codes (read-op-codes filename))
         (mem-size (length op-codes)))
    (with-intcode (memory instruction-pointer memory-size)
      (setf memory-size mem-size)
    (with-intcode (memory instruction-pointer)
      (setf instruction-pointer 0)
      (setf memory (make-array mem-size :initial-contents op-codes))
      :initialized)))



@@ 74,7 176,7 @@
  "Makes an assumption that memory is set, either from INIT-INTCODE or manually."
  (with-intcode (memory instruction-pointer)
    (setf instruction-pointer 0)
    (do* ((action (get-next-action) (get-next-action)))
    (do* ((action (next-instruction) (next-instruction)))
         ((eql action 'halt) (aref memory 0))
      (funcall action))))