summary refs log tree commit diff
path: root/2024/d02.lisp
diff options
context:
space:
mode:
Diffstat (limited to '2024/d02.lisp')
-rw-r--r--2024/d02.lisp48
1 files changed, 48 insertions, 0 deletions
diff --git a/2024/d02.lisp b/2024/d02.lisp
new file mode 100644
index 0000000..96817a7
--- /dev/null
+++ b/2024/d02.lisp
@@ -0,0 +1,48 @@
+(in-package :aoc/2024)
+
+(defparameter *input/d2*
+  (asdf:system-relative-pathname :advent "2024/d02.input"))
+
+(defun split-by-one-space (string)
+  "Splits the string at spaces and parses the values as ints"
+  (loop for i = 0 then (1+ j)
+        as j = (position #\Space string :start i)
+        collect (parse-integer (subseq string i j))
+        while j))
+
+(defun readlists (filename)
+  "Reads the given file into a list of reports containing levels"
+  (let ((reports '()))
+    (with-open-file (stream filename :direction :input)
+                    (loop for line = (read-line stream nil nil)
+                          while line
+                          do (push (split-by-one-space line) reports)))
+    (nreverse reports)))
+
+(defun diff-safe-p (a b)
+  "Checks if the given two numbers are within of 3 of each other"
+  (<= (abs (- a b)) 3))
+
+(defun ordered-p (lst)
+  "Checks if all conditions apply"
+  (and (or (apply #'< lst) (apply #'> lst))
+       (every #'diff-safe-p lst (rest lst))))
+
+(print (count-if #'ordered-p (readlists *input/d2*)))
+; 287
+
+(defun remove-nth (n lst)
+  "Remove the nth value from the given list"
+  (remove-if (constantly t) lst :start n :count 1))
+
+(defun fixable (lst)
+  "Check if the given list if fixable when removing a value"
+  (loop for i from 0 below (length lst)
+        thereis (ordered-p (remove-nth i lst))))
+
+(defun part-2 (lst)
+  "The conditions for the second part"
+  (or (ordered-p lst) (fixable lst)))
+
+(print (count-if #'part-2 (readlists *input/d2*)))
+; 354