day-7.lisp (1736B)
1 (defpackage #:aoc/day-7 2 (:use #:cl #:aoc/utils) 3 (:export #:day-7)) 4 (in-package #:aoc/day-7) 5 6 (declaim (inline number-digits combine) 7 (ftype (function (fixnum) fixnum) number-digits) 8 (ftype (function (fixnum fixnum) fixnum) combine)) 9 10 (defun number-digits (number) 11 (if (zerop number) 12 1 13 (1+ (floor (log number 10))))) 14 15 (defun combine (num-1 num-2) 16 (+ (the fixnum (* num-1 17 (the fixnum (expt 10 (number-digits num-2))))) 18 num-2)) 19 20 (defun test-value-valid-p (test-value numbers &optional combine-op) 21 (labels ((%solve (test-value numbers combine-op current) 22 (declare (type fixnum current test-value)) 23 (if (null numbers) 24 (= current test-value) 25 (if (> current test-value) 26 nil 27 (or (%solve test-value (cdr numbers) combine-op 28 (+ current (the fixnum (car numbers)))) 29 (%solve test-value (cdr numbers) combine-op 30 (* current (the fixnum (car numbers)))) 31 (and combine-op 32 (%solve test-value (cdr numbers) combine-op 33 (combine current (car numbers))))))))) 34 (%solve test-value (cdr numbers) combine-op (car numbers)))) 35 36 (defun day-7 (input) 37 (loop for line = (read-line input nil) 38 until (null line) 39 for (test-value . numbers) = (read-number-list line) 40 when (test-value-valid-p test-value numbers) 41 sum test-value into task-1 42 when (test-value-valid-p test-value numbers t) 43 sum test-value into task-2 44 finally (return (values task-1 task-2))))