Advent of Code '23 - day 6
An easier puzzle this time! This time I was able to solve it with pure math, with the only loop involved being in the input parser for part 1.
Input
Example
Time: 7 15 30 Distance: 9 40 200
Part 1
I was able to reduce the calculation into a single formula without loops, except for input parsing and adding everything together of course. I've split the formula into several methods as I expected a twist for part two.
The complete formula for the answer is as follows:
\begin{equation} answer(t,d)=t-\left(\lfloor \left(\frac{t}{2}- \sqrt{\left(\frac{t}{2}\right)^2 - d}\right) +1 \rfloor *2\right)+1 \end{equation}I'm no mathematician so it might be optimized somehow, but I don't know.
(defun aoc23/parse-input (string) (let* ((lines (string-split (string-trim string) "\n")) (times (car lines)) (times (string-trim (cadr (string-split times ":")))) (times (string-split times " +")) (times (mapcar 'string-to-number times)) (dists (cadr lines)) (dists (string-trim (cadr (string-split dists ":")))) (dists (string-split dists " +")) (dists (mapcar 'string-to-number dists)) (output '())) (while times (setq output (append output `((,(car times) . ,(car dists))))) (setq times (cdr times)) (setq dists (cdr dists))) output)) (defun aoc23/calc-dist (time-pressed time-available) (* time-pressed (- time-available time-pressed)) ) (defun aoc23/calc-max-dist (time-available) (* (/ time-available 2.0) (/ time-available 2.0))) (defun aoc23/calc-min-time (time-available min-distance) (floor (1+ (- (/ time-available 2.0) (sqrt (- (aoc23/calc-max-dist time-available) min-distance)))))) (defun aoc23/calc-number-options (time-available min-distance) (1+ (- time-available (* 2 (aoc23/calc-min-time time-available min-distance))))) (defun aoc23/get-answer (input) (apply '* (mapcar (lambda (c) (aoc23/calc-number-options (car c) (cdr c))) (aoc23/parse-input input)))) (aoc23/get-answer input)
Part 2
This part only required a different input-parser, yay!
(defun aoc23/parse-input (string) (let* ((lines (string-split (string-trim string) "\n")) (parse (lambda (input) (let* ((output input) (output (string-trim (cadr (string-split output ":")))) (output (string-split output " +")) (output (apply 'concat output))) (string-to-number output)))) (times (funcall parse (car lines))) (dists (funcall parse (cadr lines)))) `((,times . ,dists)))) (aoc23/get-answer input)