aboutsummaryrefslogtreecommitdiff
path: root/2019
diff options
context:
space:
mode:
Diffstat (limited to '2019')
-rw-r--r--2019/02/.gitignore1
-rw-r--r--2019/02/Makefile1
-rw-r--r--2019/02/puzzles.lisp24
-rw-r--r--2019/interpreter.lisp56
4 files changed, 82 insertions, 0 deletions
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