From df25235f1e020f943397a28d6a87c6d84b542c17 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sat, 14 Dec 2024 22:46:34 +0100 Subject: Add 2019 day 2 solutions --- 2019/interpreter.lisp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 2019/interpreter.lisp (limited to '2019/interpreter.lisp') diff --git a/2019/interpreter.lisp b/2019/interpreter.lisp new file mode 100644 index 0000000..30bee82 --- /dev/null +++ b/2019/interpreter.lisp @@ -0,0 +1,56 @@ +(defpackage #:intcode + (:use :cl) + (:export :run :parse)) + +(in-package #:intcode) + +;;; Interpreter + +(defun run (ram) + (let ((ip 0)) + (loop + (let ((opcode (aref ram ip)) + (arg-1 (try-aref ram (+ ip 1))) + (arg-2 (try-aref ram (+ ip 2))) + (arg-3 (try-aref ram (+ ip 3)))) + (case opcode + (1 + (setf (aref ram arg-3) + (+ (aref ram arg-1) + (aref ram arg-2)))) + (2 + (setf (aref ram arg-3) + (* (aref ram arg-1) + (aref ram arg-2)))) + (99 + (return-from run)) + (otherwise + (error (format nil "Invalid opcode ā€˜~dā€™" opcode))))) + (incf ip 4)))) + +;;; Input Parsing + +(defun parse (filename) + (with-open-file (stream filename) + (let ((contents (make-string (file-length stream)))) + (read-sequence contents stream) + (extract-numbers-from-string contents)))) + +(defun extract-numbers-from-string (string) + (loop for comma-pos = (position-if #'commap string) + collect (parse-integer (subseq string 0 comma-pos)) into numbers + unless comma-pos + return (coerce numbers 'vector) + do (setq string (subseq string (1+ comma-pos))))) + +;;; Helper Functions + +(defun commap (char) + (char= char #\,)) + +(defun try-aref (array &rest subscripts) + (loop for i in subscripts + for j in (array-dimensions array) + unless (< -1 i j) + return nil + finally (return (apply #'aref array subscripts)))) \ No newline at end of file -- cgit v1.2.3