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