aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-12-13 13:29:26 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-12-13 13:29:26 +0100
commit2564751363804f38200eab42fcb43fa77c690ec0 (patch)
tree0638adf10d13a980d01d374655da7bba74c1b8b1
parent561c001a0ac0435cc7514b956d2abbb514e01609 (diff)
Add 2024 day 13 solutions
-rw-r--r--2024/13/.gitignore1
-rw-r--r--2024/13/Makefile1
-rw-r--r--2024/13/puzzles.lisp60
3 files changed, 62 insertions, 0 deletions
diff --git a/2024/13/.gitignore b/2024/13/.gitignore
new file mode 100644
index 0000000..5fcaefb
--- /dev/null
+++ b/2024/13/.gitignore
@@ -0,0 +1 @@
+puzzle-[12].lisp \ No newline at end of file
diff --git a/2024/13/Makefile b/2024/13/Makefile
new file mode 100644
index 0000000..5a21270
--- /dev/null
+++ b/2024/13/Makefile
@@ -0,0 +1 @@
+include ../../Makefiles/lisp.mk \ No newline at end of file
diff --git a/2024/13/puzzles.lisp b/2024/13/puzzles.lisp
new file mode 100644
index 0000000..bec30f4
--- /dev/null
+++ b/2024/13/puzzles.lisp
@@ -0,0 +1,60 @@
+#!/usr/bin/sbcl --script
+
+(defun main (filename)
+ (loop for numbers in (parse-input filename)
+ sum (solve numbers)))
+
+(defun parse-input (filename)
+ (with-open-file (stream filename)
+ (let ((contents (make-string (file-length stream))))
+ (read-sequence contents stream)
+ (loop for paragraph in (split-string contents (format nil "~%~%"))
+ collect (extract-numbers-from-string paragraph)))))
+
+(defun extract-numbers-from-string (string)
+ (loop with number-count = 6
+ with numbers = (make-array number-count)
+ for i from 0 below number-count
+ for start = (position-if #'digit-char-p string)
+ for end = (position-if-not #'digit-char-p string :start start)
+ do (setf (aref numbers i) (parse-integer (subseq string start end))
+ string (subseq string (or end 0)))
+ finally (return numbers)))
+
+(defun split-string (string delimiter)
+ (loop with delimiter-length = (length delimiter)
+ for end = (search delimiter string)
+ unless (eq end 0)
+ collect (subseq string 0 end) into parts
+ unless end
+ return parts
+ do (setq string (subseq string (+ end delimiter-length)))))
+
+(defun solve (numbers)
+ ;; ⎡ a0 b0 ⎢ c0 ⎤
+ ;; ⎣ a1 b1 ⎢ c1 ⎦
+ (let* ((a0 (aref numbers 0))
+ (a1 (aref numbers 1))
+ (b0 (aref numbers 2))
+ (b1 (aref numbers 3))
+ (c0 (aref numbers 4))
+ (c1 (aref numbers 5))
+ ;; START PART 2
+ (c0 (+ 10000000000000 c0))
+ (c1 (+ 10000000000000 c1))
+ ;; END PART 2
+ (D-bar (determinant a0 b0 a1 b1))
+ (Dx-bar (determinant c0 b0 c1 b1))
+ (Dy-bar (determinant a0 c0 a1 c1))
+ (x (/ Dx-bar D-bar))
+ (y (/ Dy-bar D-bar)))
+ (if (and (integerp x)
+ (integerp y))
+ (+ (* x 3) y)
+ 0)))
+
+(defun determinant (a b c d)
+ (- (* a d)
+ (* b c)))
+
+(format t "~d~%" (main "input")) \ No newline at end of file