aboutsummaryrefslogtreecommitdiff
path: root/racket/aoc2022/day-09/day-09.rkt
diff options
context:
space:
mode:
Diffstat (limited to 'racket/aoc2022/day-09/day-09.rkt')
-rw-r--r--racket/aoc2022/day-09/day-09.rkt76
1 files changed, 76 insertions, 0 deletions
diff --git a/racket/aoc2022/day-09/day-09.rkt b/racket/aoc2022/day-09/day-09.rkt
new file mode 100644
index 0000000..0390d2e
--- /dev/null
+++ b/racket/aoc2022/day-09/day-09.rkt
@@ -0,0 +1,76 @@
+#lang racket
+(require advent-of-code
+ threading)
+
+(struct cmd (dir amt))
+(struct posn (x y) #:transparent)
+
+(define moves
+ (~> (fetch-aoc-input (find-session) 2022 9)
+ (string-split "\n")
+ (map (λ~> (string-split _)
+ (match _
+ [(list dir amt) (cmd (string->symbol dir) (string->number amt))]))
+ _)))
+
+(define (move-head p dir)
+ (match-define (posn x y) p)
+ (match dir
+ ['U (posn x (add1 y))]
+ ['D (posn x (sub1 y))]
+ ['R (posn (add1 x) y)]
+ ['L (posn (sub1 x) y)]))
+
+(define (avg n m)
+ (/ (+ n m) 2))
+
+(define (manhattan-distance p1 p2)
+ (match-define (posn x1 y1) p1)
+ (match-define (posn x2 y2) p2)
+ (+ (abs (- x2 x1)) (abs (- y2 y1))))
+
+(define (follow-head head tail)
+ (match-define (posn hx hy) head)
+ (match-define (posn tx ty) tail)
+
+ (case (manhattan-distance head tail)
+ [(0 1) tail]
+ [(2 4)
+ (cond
+ [(and (= 1 (abs (- hx tx)) (abs (- hy ty)))) tail]
+ [else (posn (avg hx tx) (avg hy ty))])]
+ [(3)
+ (cond
+ [(= 2 (abs (- hx tx))) (posn (avg hx tx) hy)]
+ [(= 2 (abs (- hy ty))) (posn hx (avg hy ty))])]))
+
+;; part 1
+(for*/fold ([head (posn 0 0)] [tail (posn 0 0)] [tail-posns (set)] #:result (set-count tail-posns))
+ ([move (in-list moves)] #:do [(match-define (cmd dir amt) move)] [_ (in-range amt)])
+ (define new-head (move-head head dir))
+ (define new-tail (follow-head new-head tail))
+ (values new-head new-tail (set-add tail-posns new-tail)))
+
+;; part 2
+(for*/fold ([knots (make-list 10 (posn 0 0))] [tail-posns (set)] #:result (set-count tail-posns))
+ ([move (in-list moves)] #:do [(match-define (cmd dir amt) move)] [_ (in-range amt)])
+ (define updated-knots
+ (for/fold ([knots-list (list (move-head (first knots) dir))])
+ ([following-knot (in-list (rest knots))])
+ (cons (follow-head (car knots-list) following-knot) knots-list)))
+ (values (reverse updated-knots) (set-add tail-posns (first updated-knots))))
+
+;; refactor: part 1 and 2 combined
+(define (follow-tail move-list rope-length)
+ (for*/fold ([knots (make-list rope-length (posn 0 0))]
+ [tail-posns (set)]
+ #:result (set-count tail-posns))
+ ([move (in-list move-list)] #:do [(match-define (cmd dir amt) move)] [_ (in-range amt)])
+ (define updated-knots
+ (for/fold ([knots-list (list (move-head (first knots) dir))])
+ ([following-knot (in-list (rest knots))])
+ (cons (follow-head (car knots-list) following-knot) knots-list)))
+ (values (reverse updated-knots) (set-add tail-posns (first updated-knots)))))
+
+(time (follow-tail moves 2))
+(time (follow-tail moves 10))