|
| 1 | +(defpackage :aoc/2025/10 #.cl-user::*aoc-use*) |
| 2 | +(in-package :aoc/2025/10) |
| 3 | + |
| 4 | +(defun read-input (&optional (strings (uiop:read-file-lines #P"src/2025/day10.txt"))) |
| 5 | + (looping |
| 6 | + (dolist (s strings) |
| 7 | + (destructuring-bind (indicator wirings joltage) |
| 8 | + (split-sequence:split-sequence-if [find _ "]{"] s) |
| 9 | + (collect! (list (map 'list [char= #\# _] (subseq indicator 1)) |
| 10 | + (looping |
| 11 | + (dolist (s2 (split-sequence:split-sequence #\Space (string-trim " " wirings))) |
| 12 | + (collect! (extract-integers s2)))) |
| 13 | + (extract-integers joltage))))))) |
| 14 | +#+#:excluded (read-input) |
| 15 | + |
| 16 | +(defun press (state wiring) |
| 17 | + (prog1-let state2 (copy-seq state) |
| 18 | + (dolist (i wiring) |
| 19 | + (setf (nth i state2) (not (nth i state2)))))) |
| 20 | + |
| 21 | +(defun configure (problem) |
| 22 | + (destructuring-bind (goal wirings) (butlast problem) |
| 23 | + (search-cost |
| 24 | + (bfs (make-list (length goal)) |
| 25 | + :test 'equal |
| 26 | + :goal-state goal |
| 27 | + :neighbors (fn (state) |
| 28 | + (looping |
| 29 | + (dolist (w wirings) |
| 30 | + (collect! (press state w))))))))) |
| 31 | +#+#:excluded (configure (car (read-input))) |
| 32 | +#+#:excluded (reduce #'+ (read-input) :key #'configure) |
| 33 | +; 432 |
| 34 | + |
| 35 | +(defun best-index (state) |
| 36 | + (looping |
| 37 | + (doseq ((i c) (enumerate state)) |
| 38 | + (when (plusp c) |
| 39 | + (minimize! i :key (constantly c)))))) |
| 40 | + |
| 41 | +(defun wirings-for-counter (i wirings) |
| 42 | + "Returns all the wirins that touch counter `i`" |
| 43 | + (keep-if [member i _] wirings)) |
| 44 | + |
| 45 | +(defun unpress (state wiring) |
| 46 | + (prog1-let state2 (copy-seq state) |
| 47 | + (dolist (i wiring) |
| 48 | + (decf (nth i state2))))) |
| 49 | + |
| 50 | +(defun configure2 (problem) |
| 51 | + (dbgl problem) |
| 52 | + (destructuring-bind (wirings goal) (cdr problem) |
| 53 | + (let1 memo (make-hash-table :test 'equal) |
| 54 | + (recursively ((state goal)) |
| 55 | + (memoizing (memo state) |
| 56 | + (dbgl state) |
| 57 | + (break) |
| 58 | + (cond ((every 'zerop state) 0) |
| 59 | + ((some 'minusp state) nil) |
| 60 | + (t (let1 i (best-index state) |
| 61 | + (when i |
| 62 | + (looping |
| 63 | + (dolist (w (wirings-for-counter i wirings)) |
| 64 | + (aif (recur (unpress state w)) |
| 65 | + (minimize! (1+ it)))))))))))))) |
| 66 | + |
| 67 | +#+#:excluded (configure2 (first (read-input))) |
| 68 | +#+#:excluded (configure2 (second (read-input))) |
| 69 | +#+#:excluded (configure2 (third (read-input))) |
| 70 | +#+#:excluded (configure2 (fourth (read-input))) |
| 71 | +#+#:excluded (reduce #'+ (read-input) :key #'configure2) |
| 72 | +; 17995 too low |
| 73 | +; 18011 |
| 74 | + |
| 75 | + |
| 76 | +#+#:excluded (ql:quickload :linear-programming) |
| 77 | +#+#:excluded (ql:quickload :linear-programming-glpk) |
| 78 | +(defun var-name (j) |
| 79 | + (symb (code-char (+ (char-code #\A) j)))) |
| 80 | + |
| 81 | +(defun configure2 (problem) |
| 82 | + (destructuring-bind (wirings goal) (cdr problem) |
| 83 | + (dbgl wirings goal) |
| 84 | + (let ((objective-exp (list 'min (list* '+ |
| 85 | + (looping |
| 86 | + (dotimes (j (length wirings)) |
| 87 | + (collect! (var-name j))))))) |
| 88 | + (constraints (looping |
| 89 | + (doseq ((i c) (enumerate goal)) |
| 90 | + (collect! (list '= |
| 91 | + (list* '+ |
| 92 | + (looping |
| 93 | + (doseq ((j w) (enumerate wirings)) |
| 94 | + (when (member i w) |
| 95 | + (collect! (var-name j)))))) |
| 96 | + c))) |
| 97 | + #+#:excluded (doseq ((j w) (enumerate wirings)) |
| 98 | + (collect! (list '>= (var-name j) 0))) |
| 99 | + (collect! (list* 'integer (looping |
| 100 | + (dotimes (j (length wirings)) |
| 101 | + (collect! (var-name j))))))))) |
| 102 | + #+#:excluded (dbgl objective-exp constraints) |
| 103 | + (setf linear-programming:*solver* linear-programming-glpk:glpk-solver) |
| 104 | + #+#:excluded (setf linear-programming:*solver* linear-programming::'simplex-solver) |
| 105 | + |
| 106 | + |
| 107 | + (let1 lin-prob (linear-programming:parse-linear-problem objective-exp |
| 108 | + constraints) |
| 109 | + (let1 solution (linear-programming:solve-problem lin-prob) |
| 110 | + (linear-programming:solution-objective-value solution)))))) |
| 111 | + |
| 112 | + |
| 113 | +#; |
| 114 | + |
| 115 | + b0 b1 b2 b3 b4 b5 c0 c1 c2, c3 |
| 116 | +[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3, 5, 4, 7} |
| 117 | + |
| 118 | +b4 + b5 = 3 |
| 119 | +b1 + b5 = 5 |
| 120 | +b2 + b3 + b4 = 4 |
| 121 | +b0 + b1 + b3 = 7 |
| 122 | + |
| 123 | +e + f = 3 |
| 124 | +b + f = 5 |
| 125 | +c + d + e = 4 |
| 126 | +a + b + d = 7 |
| 127 | + |
| 128 | + |
0 commit comments