aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2023/day05/solver.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'AoC2023/day05/solver.lisp')
-rw-r--r--AoC2023/day05/solver.lisp117
1 files changed, 117 insertions, 0 deletions
diff --git a/AoC2023/day05/solver.lisp b/AoC2023/day05/solver.lisp
new file mode 100644
index 0000000..be9008e
--- /dev/null
+++ b/AoC2023/day05/solver.lisp
@@ -0,0 +1,117 @@
+(ql:quickload '(fiveam str))
+
+(defparameter eg-input "seeds: 79 14 55 13
+
+seed-to-soil map:
+50 98 2
+52 50 48
+
+soil-to-fertilizer map:
+0 15 37
+37 52 2
+39 0 15
+
+fertilizer-to-water map:
+49 53 8
+0 11 42
+42 0 7
+57 7 4
+
+water-to-light map:
+88 18 7
+18 25 70
+
+light-to-temperature map:
+45 77 23
+81 45 19
+68 64 13
+
+temperature-to-humidity map:
+0 69 1
+1 0 69
+
+humidity-to-location map:
+60 56 37
+56 93 4")
+
+
+(defun translate (rules value)
+ (dolist (rule rules)
+ (destructuring-bind (dest source span) rule
+ (when (<= source value (+ source (1- span)))
+ (return-from translate (+ (- value source) dest)))))
+ value)
+
+(defun segment-translate (rules segments)
+ (let ((sorted-rules (sort rules #'< :key #'cadr)))
+ (mapcan
+ (lambda (segment)
+ (destructuring-bind (start . end) segment
+ (loop for (dest-start source-start span) in sorted-rules
+
+ )))
+ segments)))
+
+(sort '((50 98 2) (52 50 48)) #'< :key #'cadr)
+
+(fiveam:test parts
+ (let ((rules '((50 98 2) (52 50 48))))
+ (fiveam:is (= 9 (translate rules 9)))
+ (fiveam:is (= 61 (translate rules 59)))
+ (fiveam:is (= 51 (translate rules 99)))))
+
+(defun translator (translate-chain translator-rules)
+ (lambda (value)
+ (reduce
+ (lambda (acc fn)
+ (translate (gethash fn translator-rules) acc))
+ translate-chain
+ :initial-value value)))
+
+(defun parser (lines)
+ (let (seeds
+ maps-stack
+ (translators (make-hash-table)))
+ (dolist (line lines)
+ (cond
+ ((str:emptyp line))
+ ((str:starts-with? "seeds:" line)
+ (setf seeds
+ (mapcar #'parse-integer (cdr (str:split-omit-nulls #\Space line)))))
+ ((str:ends-with-p "map:" line)
+ (push (read-from-string line) maps-stack))
+ ((push (mapcar #'parse-integer (str:split-omit-nulls #\Space line))
+ (gethash (car maps-stack) translators)))))
+ (values (translator
+ (nreverse maps-stack)
+ translators)
+ seeds)))
+
+(defun solver1 (lines)
+ (multiple-value-bind (translator seeds) (parser lines)
+ (apply #'min (mapcar translator seeds))))
+
+
+(defun solver2 (lines)
+ (multiple-value-bind (translator seeds) (parser lines)
+ (loop for (start span) on seeds by #'cddr
+ minimize (loop for i from start below (+ start span)
+ minimize (funcall translator i)))))
+
+(fiveam:test solutions
+ (fiveam:is
+ (= 35
+ (solver1
+ (uiop:split-string eg-input :separator '(#\Newline)))))
+ (fiveam:is
+ (= 46
+ (solver2
+ (uiop:split-string eg-input :separator '(#\Newline)))))
+ (fiveam:is
+ (= 662197086
+ (solver1
+ (uiop:read-file-lines "input"))))
+ (fiveam:is
+ (= 52510809
+ (solver2
+ (uiop:read-file-lines "input")))))