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.
64 lines
2.2 KiB
Racket
64 lines
2.2 KiB
Racket
#lang br/quicklang
|
|
(require "../helper.rkt")
|
|
(provide read-syntax (rename-out [#%mb #%module-begin]) ★ ★★)
|
|
|
|
(define (read-syntax path port)
|
|
(define lines (port->lines port))
|
|
(strip-context #`(module mod "main.rkt"
|
|
#,@(for/list ([datum (in-port read (open-input-string (car lines)))])
|
|
datum)
|
|
#,@(cdr lines))))
|
|
|
|
(define-macro (#%mb STARS LINE ...)
|
|
#'(#%module-begin
|
|
(time (STARS (list LINE ...)))))
|
|
|
|
(define (infect lines bursts #:weak-mode [weak-mode? #f])
|
|
(define chars (make-hasheqv))
|
|
(define origin-adjust (/ (sub1 (string-length (car lines))) 2))
|
|
(for* ([(line lidx) (in-indexed lines)]
|
|
[(c cidx) (in-indexed (string->list line))])
|
|
(define key (+ (- lidx origin-adjust) (* +i (- cidx origin-adjust))))
|
|
(hash-set! chars key c))
|
|
|
|
(define turn-left +i) (define turn-right -i)
|
|
|
|
(define-macro (define-state ID CHAR)
|
|
(with-pattern ([ID? (suffix-id #'ID "?")]
|
|
[SET-ID (prefix-id "set-" #'ID)])
|
|
#'(begin (define ID CHAR)
|
|
(define (SET-ID x) (hash-set! chars x ID))
|
|
(define (ID? x) (eqv? (hash-ref! chars x #\.) ID)))))
|
|
(define-state clean #\.)
|
|
(define-state infected #\#)
|
|
(define-state weakened #\W)
|
|
(define-state flagged #\F)
|
|
|
|
(for/fold ([here 0]
|
|
[dir -1]
|
|
[infections 0]
|
|
#:result infections)
|
|
([burst (in-range bursts)])
|
|
(match here
|
|
[(? infected?)
|
|
(define next-dir (* dir turn-right))
|
|
((if weak-mode? set-flagged set-clean) here)
|
|
(values (+ here next-dir) next-dir infections)]
|
|
[(? clean?)
|
|
(define next-dir (* dir turn-left))
|
|
((if weak-mode? set-weakened set-infected) here)
|
|
(values (+ here next-dir) next-dir ((if weak-mode? values add1) infections))]
|
|
[(? weakened?)
|
|
(define next-dir dir)
|
|
(set-infected here)
|
|
(values (+ here next-dir) next-dir (add1 infections))]
|
|
[(? flagged?)
|
|
(define next-dir (- dir))
|
|
(set-clean here)
|
|
(values (+ here next-dir) next-dir infections)])))
|
|
|
|
(define (★ lines) (infect lines 10000))
|
|
|
|
(define (★★ lines) (infect lines 10000000 #:weak-mode #t))
|
|
|