advent-of-code-2024

My solutions to AoC 2024
Log | Files | Refs

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))))