(defparameter *input-file* #P"input.txt") (defparameter *input* (uiop:read-file-string *input-file*)) (defvar *program*) (defun opcode (pc) (mod (aref *program* pc) 100)) (defun parameter-mode (pc index) (mod (truncate (aref *program* pc) (expt 10 (+ 1 index))) 10)) (defun parameter (pc index) (ecase (parameter-mode pc index) (1 (aref *program* (+ index pc))) (0 (aref *program* (aref *program* (+ pc index)))))) (defun (setf parameter) (new-value pc index) (ecase (parameter-mode pc index) (0 (setf (aref *program* (aref *program* (+ pc index))) new-value)) (1 (error "Cannot write with a parameter in immediate mode")))) (defun execute (inputs) (defun execute-instruction (pc inputs outputs) (ecase (opcode pc) (99 (return-from execute-instruction outputs)) (1 (setf (parameter pc 3) (+ (parameter pc 1) (parameter pc 2))) (execute-instruction (+ pc 4) inputs outputs)) (2 (setf (parameter pc 3) (* (parameter pc 1) (parameter pc 2))) (execute-instruction (+ pc 4) inputs outputs)) (3 (setf (parameter pc 1) (car inputs)) (execute-instruction (+ pc 2) (cdr inputs) outputs)) (4 (execute-instruction (+ pc 2) inputs (cons (parameter pc 1) outputs))) (5 (if (/= 0 (parameter pc 1)) (execute-instruction (parameter pc 2) inputs outputs) (execute-instruction (+ pc 3) inputs outputs))) (6 (if (= 0 (parameter pc 1)) (execute-instruction (parameter pc 2) inputs outputs) (execute-instruction (+ pc 3) inputs outputs))) (7 (if (< (parameter pc 1) (parameter pc 2)) (setf (parameter pc 3) 1) (setf (parameter pc 3) 0)) (execute-instruction (+ pc 4) inputs outputs)) (8 (if (= (parameter pc 1) (parameter pc 2)) (setf (parameter pc 3) 1) (setf (parameter pc 3) 0)) (execute-instruction (+ pc 4) inputs outputs)))) (execute-instruction 0 inputs nil)) (defun parse-program (program-string) (map 'vector #'parse-integer (uiop:split-string program-string :separator ","))) (defun part1 () (let ((*program* (parse-program *input*))) (car (execute '(1))))) (defun part2 () (let ((*program* (parse-program *input*))) (car (execute '(5))))) (assert (= (part1) 12896948)) (assert (= (part2) 7704130))