aoc2022/9.rkt

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"))