Day 12: Part 2.
This commit is contained in:
parent
ad4c28e091
commit
a25122da57
122
src/12.rkt
122
src/12.rkt
|
@ -4,24 +4,18 @@
|
|||
"../lib.rkt")
|
||||
|
||||
(define moons-pos
|
||||
'((-9 -1 -1)
|
||||
( 2 9 5)
|
||||
(10 18 -12)
|
||||
(-6 15 -7)))
|
||||
'((-9 -1 -1) ;; moon 1
|
||||
( 2 9 5) ;; moon 2
|
||||
(10 18 -12) ;; moon 3
|
||||
(-6 15 -7))) ;; moon 4
|
||||
;; x y z
|
||||
|
||||
(define moons-vel
|
||||
'((0 0 0)
|
||||
(0 0 0)
|
||||
(0 0 0)
|
||||
(0 0 0)))
|
||||
|
||||
(define example
|
||||
'((-1 0 2)
|
||||
( 2 -10 -7)
|
||||
( 4 -8 8)
|
||||
( 3 5 -1)))
|
||||
|
||||
(define positions (mutable-set))
|
||||
'((0 0 0) ;; moon 1
|
||||
(0 0 0) ;; moon 2
|
||||
(0 0 0) ;; moon 3
|
||||
(0 0 0))) ;; moon 4
|
||||
;; vx vy vz
|
||||
|
||||
(define (less-than->number n1 n2)
|
||||
(cond
|
||||
|
@ -29,56 +23,68 @@
|
|||
[(= n1 n2) 0]
|
||||
[(> n1 n2) -1]))
|
||||
|
||||
;; Calculate the velocity on the first moon
|
||||
;; caused by the second moon
|
||||
(define (velocity moon-on moon-by)
|
||||
(list (less-than->number (first moon-on) (first moon-by))
|
||||
(less-than->number (second moon-on) (second moon-by))
|
||||
(less-than->number (third moon-on) (third moon-by))))
|
||||
|
||||
(define (<+> v1 v2)
|
||||
(zip + v1 v2))
|
||||
;; velocity-1D : (listof pos) -> pos -> vel -> vel
|
||||
;; Calculate the final velocity on the given moon
|
||||
;; due to all other moons
|
||||
(define (velocity-1D moons moon vel)
|
||||
(+ vel (sum (map (∂ less-than->number moon) moons))))
|
||||
|
||||
;; velocities-1D : (listof pos) -> (listof vel) -> (listof vel)
|
||||
;; Calculate velocities for all moons
|
||||
(define (velocities moons vels)
|
||||
(zip <+> vels
|
||||
(map (λ (moon)
|
||||
(foldl (λ (other v)
|
||||
(<+> v (velocity moon other)))
|
||||
'(0 0 0) moons))
|
||||
moons)))
|
||||
(define (velocities-1D moons vels)
|
||||
(map (∂ velocity-1D moons) moons vels))
|
||||
|
||||
;; step-1D : (listof pos) -> (listof vel) -> (values (listof pos) (listof vel))
|
||||
;; Step moon trajectories once
|
||||
(define (step-1D moons vels)
|
||||
(let* ([vels (velocities-1D moons vels)]
|
||||
[moons (zip + moons vels)])
|
||||
(values moons vels)))
|
||||
|
||||
;; step-n-1D : number -> (listof pos) -> (listof vel) -> (values (listof pos) (listof vel))
|
||||
;; Step moon trajectories n times
|
||||
(define (step-n-1D n moons vels)
|
||||
(if (zero? n)
|
||||
(values moons vels)
|
||||
(let-values ([(moons vels) (step-1D moons vels)])
|
||||
(step-n-1D (sub1 n) moons vels))))
|
||||
|
||||
;; loop-steps-1D : (listof pos) -> (listof vel) -> number
|
||||
;; Calculate steps to loop back to original position
|
||||
(define (loop-steps-1D moons* vels*)
|
||||
(let loop ([steps 1]
|
||||
[moons moons*]
|
||||
[vels vels*])
|
||||
(if (and (> steps 1) (equal? moons moons*))
|
||||
steps
|
||||
(let*-values ([(moons* vels*)
|
||||
(step-1D moons vels)])
|
||||
(loop (add1 steps) moons* vels*)))))
|
||||
|
||||
;; energy : (listof (list xpos ypos zpos)) -> (listof (list xvel yvel zvel)) -> number
|
||||
;; Calculate total energy (in three dimensions)
|
||||
(define (energy moons vels)
|
||||
(sum (zip (λ (moon vel)
|
||||
(sum (map (λ (moon vel)
|
||||
(* (sum (map abs moon))
|
||||
(sum (map abs vel))))
|
||||
moons vels)))
|
||||
|
||||
(define (step moons vels)
|
||||
(let* ([vels (velocities moons vels)]
|
||||
[moons (zip <+> moons vels)])
|
||||
(values moons vels)))
|
||||
|
||||
(define (step-n n moons vels)
|
||||
(if (zero? n)
|
||||
(values moons vels)
|
||||
(let-values ([(moons vels) (step moons vels)])
|
||||
(step-n (sub1 n) moons vels))))
|
||||
|
||||
(define part1
|
||||
(let-values ([(moons vels)
|
||||
(step-n 1000 moons-pos moons-vel)])
|
||||
(energy moons vels)))
|
||||
(let* ([moons (transpose moons-pos)] ;; moons : (list (listof xpos) (listof ypos) (listof zpos))
|
||||
[vels (transpose moons-vel)]) ;; vels : (list (listof xvel) (listof yvel) (listof zvel))
|
||||
(let*-values ([(moons-x vels-x) (step-n-1D 1000 (first moons) (first vels))]
|
||||
[(moons-y vels-y) (step-n-1D 1000 (second moons) (second vels))]
|
||||
[(moons-z vels-z) (step-n-1D 1000 (third moons) (third vels))])
|
||||
(let ([moonsT (transpose (list moons-x moons-y moons-z))]
|
||||
[velsT (transpose (list vels-x vels-y vels-z))])
|
||||
(energy moonsT velsT)))))
|
||||
|
||||
(define (part2-nogood)
|
||||
(let loop ([steps 0]
|
||||
[moons moons-pos]
|
||||
[vels moons-vel])
|
||||
(if (set-member? positions moons)
|
||||
steps
|
||||
(let*-values ([(moons* vels*)
|
||||
(step moons vels)])
|
||||
(set-add! positions moons)
|
||||
(loop (add1 steps) moons* vels*)))))
|
||||
(define part2
|
||||
(let* ([moons (transpose moons-pos)] ;; moons : (list (listof xpos) (listof ypos) (listof zpos))
|
||||
[vels (transpose moons-vel)] ;; vels : (list (listof xvel) (listof yvel) (listof zvel))
|
||||
[steps-x (loop-steps-1D (first moons) (first vels))]
|
||||
[steps-y (loop-steps-1D (second moons) (second vels))]
|
||||
[steps-z (loop-steps-1D (third moons) (third vels))])
|
||||
(lcm steps-x steps-y steps-z)))
|
||||
|
||||
(show-solution part1 #f)
|
||||
(show-solution part1 part2)
|
Loading…
Reference in New Issue