(load "../common.scm") ; compute cost of moving all positions to given target ; with a rate linearly proportional to distance to travel (define (fuel-cost-to-constant-rate positions target) (apply + (map (lambda (p) (abs (- p target))) positions))) ; compute cost of moving all positions to given target ; with a growing rate fuel cost with distance (define (fuel-cost-to-growing-rate positions target) (apply + (map (lambda (p) (let [(n (abs (- p target)))] (/ (* n (+ n 1)) 2))) ; fast way of computing 1+2+3+...+n positions))) ; find position to move to from given position to that minimizes cost (define (lowest-fuel-cost-target positions fuel-cost-to) (let [(max-position (+ (apply max positions) 1))] (let loop [(best-cost -1) (best-position 0) (position 0)] (if (<= position max-position) (let [(cost (fuel-cost-to positions position))] (if (or (= best-cost -1) (< cost best-cost)) (loop cost position (+ position 1)) (loop best-cost best-position (+ position 1)))) best-cost)))) (call-with-input-file "input" (lambda (file) (let* [(input (read-comma-separated-numbers file))] (printf "part 1:~% best position to align to: ~a~%" (lowest-fuel-cost-target input fuel-cost-to-constant-rate)) (printf "part 2:~% best position to align to: ~a~%" (lowest-fuel-cost-target input fuel-cost-to-growing-rate)))))