115 lines
3.9 KiB
Racket
115 lines
3.9 KiB
Racket
#lang curly-fn racket
|
|
|
|
(require "scripts/aoc.rkt")
|
|
|
|
;; solution for day 9
|
|
|
|
(define (cmp a b)
|
|
(cond
|
|
[(< a b) '<]
|
|
[(> a b) '>]
|
|
[else '=]))
|
|
|
|
(define (move1 hx hy tx ty dir)
|
|
(match* (dir (cmp hx tx) (cmp hy ty))
|
|
[("U" _ (not '>)) (values hx (add1 hy) tx ty)]
|
|
[("D" _ (not '<)) (values hx (sub1 hy) tx ty)]
|
|
[("R" (not '>) _) (values (add1 hx) hy tx ty)]
|
|
[("L" (not '<) _) (values (sub1 hx) hy tx ty)]
|
|
|
|
[("U" '= _) (values hx (add1 hy) tx (add1 ty))]
|
|
[("U" '< _) (values hx (add1 hy) (sub1 tx) (add1 ty))]
|
|
[("U" '> _) (values hx (add1 hy) (add1 tx) (add1 ty))]
|
|
|
|
[("D" '= _) (values hx (sub1 hy) tx (sub1 ty))]
|
|
[("D" '< _) (values hx (sub1 hy) (sub1 tx) (sub1 ty))]
|
|
[("D" '> _) (values hx (sub1 hy) (add1 tx) (sub1 ty))]
|
|
|
|
[("R" _ '=) (values (add1 hx) hy (add1 tx) ty)]
|
|
[("R" _ '<) (values (add1 hx) hy (add1 tx) (sub1 ty))]
|
|
[("R" _ '>) (values (add1 hx) hy (add1 tx) (add1 ty))]
|
|
|
|
[("L" _ '=) (values (sub1 hx) hy (sub1 tx) ty)]
|
|
[("L" _ '<) (values (sub1 hx) hy (sub1 tx) (sub1 ty))]
|
|
[("L" _ '>) (values (sub1 hx) hy (sub1 tx) (add1 ty))]))
|
|
|
|
(define (part1 input)
|
|
(for*/fold ([hx 0] [hy 0] [tx 0] [ty 0] [visited (set (cons 0 0))] #:result (set-count visited))
|
|
([inst (in-list input)]
|
|
[dir (in-value (first inst))]
|
|
[_ (in-range (second inst))])
|
|
(define-values [hx* hy* tx* ty*] (move1 hx hy tx ty dir))
|
|
; (printf "DIR: ~a | h: (~a, ~a) t: (~a ~a)\n" dir hx* hy* tx* ty*)
|
|
(values hx* hy* tx* ty* (set-add visited (cons tx* ty*)))))
|
|
|
|
(define (apply-move dir p)
|
|
(match dir
|
|
["U" (cons (car p) (add1 (cdr p)))]
|
|
["D" (cons (car p) (sub1 (cdr p)))]
|
|
["R" (cons (add1 (car p)) (cdr p))]
|
|
["L" (cons (sub1 (car p)) (cdr p))]))
|
|
|
|
(define (catch-up p1 p2)
|
|
(match* ((- (car p1) (car p2)) (- (cdr p1) (cdr p2)))
|
|
[(2 0) (cons (add1 (car p2)) (cdr p2))]
|
|
[(-2 0) (cons (sub1 (car p2)) (cdr p2))]
|
|
[(0 2) (cons (car p2) (add1 (cdr p2)))]
|
|
[(0 -2) (cons (car p2) (sub1 (cdr p2)))]
|
|
[(2 1) (cons (add1 (car p2)) (add1 (cdr p2)))]
|
|
[(2 -1) (cons (add1 (car p2)) (sub1 (cdr p2)))]
|
|
[(-2 1) (cons (sub1 (car p2)) (add1 (cdr p2)))]
|
|
[(-2 -1) (cons (sub1 (car p2)) (sub1 (cdr p2)))]
|
|
[(1 2) (cons (add1 (car p2)) (add1 (cdr p2)))]
|
|
[(-1 2) (cons (sub1 (car p2)) (add1 (cdr p2)))]
|
|
[(1 -2) (cons (add1 (car p2)) (sub1 (cdr p2)))]
|
|
[(-1 -2) (cons (sub1 (car p2)) (sub1 (cdr p2)))]
|
|
[(2 2) (cons (add1 (car p2)) (add1 (cdr p2)))]
|
|
[(2 -2) (cons (add1 (car p2)) (sub1 (cdr p2)))]
|
|
[(-2 2) (cons (sub1 (car p2)) (add1 (cdr p2)))]
|
|
[(-2 -2) (cons (sub1 (car p2)) (sub1 (cdr p2)))]
|
|
[(_ _) p2]))
|
|
|
|
(define (draw state)
|
|
(define lines
|
|
(for/list ([y (in-range 10 -10 -1)])
|
|
(apply string-append
|
|
(for/list ([x (in-range -10 10)])
|
|
(match (index-of state (cons x y))
|
|
[#f "."]
|
|
[0 "H"]
|
|
[i (~a i)])))))
|
|
(string-join lines "\n"))
|
|
|
|
(define (part2 input)
|
|
(define initial-state (build-list 10 (λ (_) (cons 0 0))))
|
|
(for*/fold ([rope initial-state] [visited (set (cons 0 0))] #:result (set-count visited))
|
|
([inst (in-list input)]
|
|
[dir (in-value (first inst))]
|
|
[_ (in-range (second inst))])
|
|
(define new-list (list (apply-move dir (first rope))))
|
|
|
|
(for ([i (in-range 1 10)])
|
|
(define h (list-ref new-list (sub1 i)))
|
|
(define t (list-ref rope i))
|
|
(define t* (catch-up h t))
|
|
(set! new-list (append new-list (list t*))))
|
|
|
|
; (printf "~a ~a\n" dir new-list)
|
|
; (displayln (draw new-list))
|
|
|
|
(values new-list (set-add visited (last new-list)))))
|
|
|
|
(define (parse fname)
|
|
(for/list ([line (in-list (file->lines fname))])
|
|
(match-define (list dir (app string->number num)) (string-split line " "))
|
|
(list dir num)))
|
|
|
|
; (part2 (parse "inputs/9-test2"))
|
|
; (error "x")
|
|
|
|
(module+ main
|
|
(define input (parse "inputs/9"))
|
|
(answer 9 1 (time (part1 input)))
|
|
(answer 9 2 (time (part2 input)))
|
|
(displayln "meow"))
|