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

  • wer2@lemm.ee
    link
    fedilink
    arrow-up
    2
    ·
    19 days ago

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