diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | 2019/02/.gitignore | 1 | ||||
-rw-r--r-- | 2019/02/Makefile | 1 | ||||
-rw-r--r-- | 2019/02/puzzles.lisp | 24 | ||||
-rw-r--r-- | 2019/interpreter.lisp | 56 |
5 files changed, 83 insertions, 0 deletions
@@ -1,4 +1,5 @@ __pycache__/ +*.fasl .clang-format .cookies input diff --git a/2019/02/.gitignore b/2019/02/.gitignore new file mode 100644 index 0000000..5fcaefb --- /dev/null +++ b/2019/02/.gitignore @@ -0,0 +1 @@ +puzzle-[12].lisp
\ No newline at end of file diff --git a/2019/02/Makefile b/2019/02/Makefile new file mode 100644 index 0000000..5a21270 --- /dev/null +++ b/2019/02/Makefile @@ -0,0 +1 @@ +include ../../Makefiles/lisp.mk
\ No newline at end of file diff --git a/2019/02/puzzles.lisp b/2019/02/puzzles.lisp new file mode 100644 index 0000000..9a3acb7 --- /dev/null +++ b/2019/02/puzzles.lisp @@ -0,0 +1,24 @@ +#!/usr/bin/sbcl --script + +(load "../interpreter.lisp") + +(defun run-with-noun-and-verb (noun verb ram) + (setf (aref ram 1) noun + (aref ram 2) verb) + (intcode:run ram) + (aref ram 0)) + +;; START PART 1 +(let ((program (intcode:parse "input"))) + (format t "~d~%" (run-with-noun-and-verb 12 2 program))) +;; END PART 1 START PART 2 +(let* ((program (intcode:parse "input")) + (ram (make-array (length program)))) + (dotimes (noun 100) + (dotimes (verb 100) + (loop for i from 0 below (length program) + do (setf (aref ram i) (aref program i))) + (when (= (run-with-noun-and-verb noun verb ram) 19690720) + (format t "~d~%" (+ (* 100 noun) verb)) + (quit))))) +;; END PART 2
\ No newline at end of file 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 |