You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
2.0 KiB
Racket
55 lines
2.0 KiB
Racket
#lang br/quicklang
|
|
(module+ reader
|
|
(provide read-syntax)
|
|
(define (read-syntax path port)
|
|
(define turn-strings (string-split (port->string port) ","))
|
|
(define turn-pattern #px"^([LR])(\\d+)$")
|
|
(define turn-datums
|
|
(for*/list ([tstr (in-list turn-strings)])
|
|
(define match-result (regexp-match turn-pattern (string-trim tstr)))
|
|
`(turn ,@(cdr (or match-result empty)))))
|
|
(strip-bindings
|
|
#`(module day01-mod "day01.rkt"
|
|
#,@turn-datums))))
|
|
|
|
(define-macro (mb . TURNS)
|
|
#'(#%module-begin
|
|
(solve . TURNS)))
|
|
(provide (rename-out [mb #%module-begin]))
|
|
|
|
(define (loc-dist loc)
|
|
(+ (abs (imag-part loc)) (abs (real-part loc))))
|
|
|
|
(struct $turn (rot dist) #:transparent)
|
|
(define rotate-left +i)
|
|
(define rotate-right -i)
|
|
(define same-dir 1)
|
|
|
|
(define (solve . turns)
|
|
(define found-twice-visited-loc #f)
|
|
(define north 0+1i)
|
|
(define starting-loc 0+0i)
|
|
(let loop ([locs (list starting-loc)] [dir north] [turns turns])
|
|
(cond
|
|
[(empty? turns)
|
|
(displayln (format "part 1 (dist of final location): ~a" (loc-dist (car locs))))]
|
|
[(zero? ($turn-dist (car turns))) (loop locs dir (cdr turns))]
|
|
[else
|
|
(define new-dir (* dir ($turn-rot (car turns))))
|
|
(define one-step 1)
|
|
(define new-loc (+ (car locs) (* new-dir one-step)))
|
|
(when (and (not found-twice-visited-loc) (member new-loc locs))
|
|
(set! found-twice-visited-loc new-loc)
|
|
(displayln (format "part 2 (dist of first twice-visited location): ~a"
|
|
(loc-dist new-loc))))
|
|
(define decremented-turn ($turn same-dir (sub1 ($turn-dist (car turns)))))
|
|
(loop (cons new-loc locs) new-dir (cons decremented-turn (cdr turns)))])))
|
|
|
|
(define-macro-cases turn
|
|
[(_ DIR DIST)
|
|
(with-pattern ([ENCODED-DIR (syntax-case #'DIR ()
|
|
["L" #'rotate-left]
|
|
["R" #'rotate-right])])
|
|
#'($turn ENCODED-DIR (string->number DIST)))]
|
|
[else #'(void)])
|
|
(provide turn) |