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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/2017/d22/main.rkt

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