Last active
December 12, 2019 11:45
-
-
Save sotolf2/b3ead8a6a4f28b1ceabb928a8e2d27ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
(require threading) | |
(require racket/set) | |
(struct point (x y z) #:transparent) | |
(struct velocity (x y z) #:transparent) | |
(struct moon (position velocity) #:transparent) | |
(define (get-input) | |
(file->lines "day12.txt")) | |
(define (get-test) | |
(file->lines "day12-test.txt")) | |
(define (parse points) | |
(define (parse-line point-string) | |
(~> point-string | |
(string-replace "<" "") | |
(string-replace ">" "") | |
(string-split ",") | |
(map (λ (part) (string->number (cadr (string-split part "=")))) _) | |
(apply point _) | |
(moon (velocity 0 0 0)))) | |
(map parse-line points)) | |
(define (velocity-add a b) | |
(velocity (+ (velocity-x a) (velocity-x b)) | |
(+ (velocity-y a) (velocity-y b)) | |
(+ (velocity-z a) (velocity-z b)))) | |
(define (velocity-add-deltas a deltas) | |
(foldl velocity-add a deltas)) | |
(define (positions->velocity-change a b) | |
(define (delta->change delta) | |
(cond [(zero? delta) 0] | |
[(negative? delta) 1] | |
[(positive? delta) -1])) | |
(let* ([dx (- (point-x a) (point-x b))] | |
[dy (- (point-y a) (point-y b))] | |
[dz (- (point-z a) (point-z b))]) | |
(velocity (delta->change dx) (delta->change dy) (delta->change dz)))) | |
(define (get-new-velocity mn mns) | |
(~>> mns | |
(map (λ (x) (positions->velocity-change (moon-position mn) (moon-position x)))) | |
(velocity-add-deltas (moon-velocity mn)))) | |
(define (update-velocities mns) | |
(define (loop mns all res) | |
(if (empty? mns) | |
(reverse res) | |
(loop | |
(cdr mns) | |
all | |
(cons (moon (moon-position (car mns)) (get-new-velocity (car mns) all)) res)))) | |
(loop mns mns '())) | |
(define (apply-velocity mn) | |
(let ([pos (moon-position mn)] | |
[vel (moon-velocity mn)]) | |
(moon | |
(point | |
(+ (point-x pos) (velocity-x vel)) | |
(+ (point-y pos) (velocity-y vel)) | |
(+ (point-z pos) (velocity-z vel))) | |
vel))) | |
(define (apply-velocities mns) | |
(define (loop mns res) | |
(if (empty? mns) | |
(reverse res) | |
(loop | |
(cdr mns) | |
(cons (apply-velocity (car mns)) res)))) | |
(loop mns '())) | |
(define (simulate-step mns) | |
(~> mns | |
(update-velocities) | |
(apply-velocities))) | |
(define (simulate-steps num mns) | |
(if (zero? num) | |
mns | |
(simulate-steps (- num 1) (simulate-step mns)))) | |
(define (moon-energy mn) | |
(let ([pos (moon-position mn)] | |
[vel (moon-velocity mn)]) | |
(* | |
(+ (abs (point-x pos)) (abs (point-y pos)) (abs (point-z pos))) | |
(+ (abs (velocity-x vel)) (abs (velocity-y vel)) (abs (velocity-z vel)))))) | |
(define (system-energy mns) | |
(~>> mns | |
(map moon-energy) | |
(apply +))) | |
(define (part1) | |
(~>> | |
(get-input) | |
(parse) | |
(simulate-steps 1000) | |
(system-energy))) | |
(define (point-by dim) | |
(cond [(equal? 'x dim) point-x] | |
[(equal? 'y dim) point-y] | |
[(equal? 'z dim) point-z])) | |
(define (velocity-by dim) | |
(cond [(equal? 'x dim) velocity-x] | |
[(equal? 'y dim) velocity-y] | |
[(equal? 'z dim) velocity-z])) | |
(define (moon-dim-equal? dim a b) | |
(let ([apx ((point-by dim) (moon-position a))] | |
[bpx ((point-by dim) (moon-position b))] | |
[avx ((velocity-by dim) (moon-velocity a))] | |
[bvx ((velocity-by dim) (moon-velocity b))]) | |
(and (= apx bpx) (= avx bvx)))) | |
(define (system-equal-by cmpf a b) | |
(andmap cmpf a b)) | |
(define (find-repeating cmp mns) | |
(define (loop mns init steps) | |
(if (system-equal-by cmp mns init) | |
steps | |
(loop | |
(simulate-step mns) | |
init | |
(+ 1 steps)))) | |
(loop (simulate-step mns) mns 1)) | |
(define (part2) | |
(let ([mns (parse (get-input))]) | |
(lcm (find-repeating (curry moon-dim-equal? 'x) mns) (find-repeating (curry moon-dim-equal? 'y) mns) (find-repeating (curry moon-dim-equal? 'z) mns)))) | |
(part1) | |
(part2) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment