Day 7: Bridge Repair
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
You are viewing a single thread.
View all comments 2 points
Lisp
Could probably go much faster if I kept track of calculations to not repeat, but 4 seconds for part 2 on my old laptop is good enough for me. Also, not really a big change from part 1 to part 2.
Part 1 and 2
(defstruct calibration result inputs)
(defun p1-process-line (line)
(let ((parts (str:words line)))
(make-calibration :result (parse-integer (car parts) :junk-allowed t)
:inputs (mapcar #'parse-integer (cdr parts)))))
(defun apply-opperators (c opps)
(let ((accum (car (calibration-inputs c))))
(loop for o in opps
for v in (cdr (calibration-inputs c))
until (> accum (calibration-result c))
if (eql o 'ADD)
do (setf accum (+ accum v))
else if (eql o 'MUL)
do (setf accum (* accum v))
else
do (setf accum (+ v (* accum (expt 10 (1+ (floor (log v 10)))))))
finally (return accum)
)))
(defun generate-operators (item-count)
(labels ((g-rec (c results)
(if (< c 1)
results
(g-rec (1- c) (loop for r in results
collect (cons 'ADD r)
collect (cons 'MUL r))))))
(g-rec (1- item-count) '((ADD) (MUL)))))
(defun generate-ops-hash (c gen-ops)
(let ((h (make-hash-table)))
(dotimes (x c)
(setf (gethash (+ 2 x) h) (funcall gen-ops (+ 1 x))))
h))
(defun validate-calibration (c ops-h)
(let ((r (calibration-result c))
(ops (gethash (length (calibration-inputs c)) ops-h)))
(loop for o in ops
for v = (apply-opperators c o)
when (= v r)
return t)))
(defun run-p1 (file)
(let ((calibrations (read-file file #'p1-process-line))
(ops (generate-ops-hash 13 #'generate-operators)))
(loop for c in calibrations
when (validate-calibration c ops)
sum (calibration-result c))))
(defun generate-operators-p2 (item-count)
(labels ((g-rec (c results)
(if (< c 1)
results
(g-rec (1- c) (loop for r in results
collect (cons 'ADD r)
collect (cons 'MUL r)
collect (cons 'CAT r))))))
(g-rec (1- item-count) '((ADD) (MUL) (CAT)))))
(defun run-p2 (file)
(let ((calibrations (read-file file #'p1-process-line))
(ops (generate-ops-hash 13 #'generate-operators-p2)))
(loop for c in calibrations
when (validate-calibration c ops)
sum (calibration-result c))))