Skip to content

Instantly share code, notes, and snippets.

@angus-g
Created December 12, 2019 07:33
Show Gist options
  • Save angus-g/1221d64e430ce1d63cc045eb0a80105c to your computer and use it in GitHub Desktop.
Save angus-g/1221d64e430ce1d63cc045eb0a80105c to your computer and use it in GitHub Desktop.
advent of code day 12 (partial)
#lang racket
;(define moons-pos (vector '(17 5 1) '(-2 -8 8) '(7 -6 14) '(1 -10 4)))
(define moons-pos (vector '(-8 -10 0) '(5 5 10) '(2 -7 3) '(9 -8 -3)))
;(define moons-pos (vector '(-1 0 2) '(2 -10 -7) '(4 -8 8) '(3 5 -1)))
(define moons-vel (vector '(0 0 0) '(0 0 0) '(0 0 0) '(0 0 0)))
; update velocities
(define (gravity a-pos b-pos a-vel b-vel)
(values (map (lambda (aa bb v) (if (< aa bb) (add1 v) (if (> aa bb) (sub1 v) v))) a-pos b-pos a-vel)
(map (lambda (aa bb v) (if (< bb aa) (add1 v) (if (> bb aa) (sub1 v) v))) a-pos b-pos b-vel)))
(define (energy)
(for/fold ([energy 0])
([pos (in-vector moons-pos)]
[vel (in-vector moons-vel)])
(+ energy (* (apply + (map abs pos)) (apply + (map abs vel))))))
(define (update-forwards)
(for* ([i (in-range 4)]
[j (in-range (add1 i) 4)])
; update velocities by applying gravity
(let-values ([(vel-a vel-b)
(gravity
(vector-ref moons-pos i)
(vector-ref moons-pos j)
(vector-ref moons-vel i)
(vector-ref moons-vel j))])
(vector-set! moons-vel i vel-a)
(vector-set! moons-vel j vel-b)))
(for ([i (in-range 4)])
(vector-set! moons-pos i (map + (vector-ref moons-pos i) (vector-ref moons-vel i)))))
(define (update-backwards)
; first subtract velocity
(for ([i (in-range 4)])
(vector-set! moons-pos i (map - (vector-ref moons-pos i) (vector-ref moons-vel i))))
(for* ([i (in-range 4)]
[j (in-range (add1 i) 4)])
; update velocities by applying gravity to new positions
(let-values ([(vel-a vel-b)
(gravity
(vector-ref moons-pos j)
(vector-ref moons-pos i)
(vector-ref moons-vel i)
(vector-ref moons-vel j))])
(vector-set! moons-vel i vel-a)
(vector-set! moons-vel j vel-b))))
; part 1
;(for ([i (in-range 1000)])
; (update-forwards))
;(energy)
; part 2
; observation: total cycle length is lcm of cycle length across coordinates
; subproblem: cycle length for a single coordinate
(define (cycle-len l)
(for/first ([i (in-range 2 (add1 (length l)))]
#:when (let ([s (take l i)]) (equal? s (reverse s))))
i))
(define reps
(for/list ([i (in-range 10000)])
(begin0 (vector-map first moons-vel)
(update-forwards))))
(for/list ([i (in-range 4)])
(cycle-len (map (lambda (v) (vector-ref v i)) reps)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment