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.
47 lines
1.7 KiB
Racket
47 lines
1.7 KiB
Racket
8 years ago
|
#lang racket
|
||
|
(require rackunit)
|
||
|
(provide read-syntax)
|
||
|
|
||
|
(define (str->visits str)
|
||
|
(define start '(0 0))
|
||
|
(define moves (map (λ(move) (case move
|
||
|
[("^") '(0 1)]
|
||
|
[("v") '(0 -1)]
|
||
|
[("<") '(-1 0)]
|
||
|
[(">") '(1 0)]))
|
||
|
(regexp-match* #rx"." str)))
|
||
|
(reverse (for/fold ([visit-acc (list start)])
|
||
|
([move (in-list moves)])
|
||
|
(cons (map + move (car visit-acc)) visit-acc))))
|
||
|
|
||
|
(define (str->unique-visits str)
|
||
|
(define visits (str->visits str))
|
||
|
(length (remove-duplicates visits)))
|
||
|
|
||
|
(define (str->robosanta str)
|
||
|
(define-values (reversed-santa-path reversed-robo-path)
|
||
|
(for/fold ([santa-acc empty][robo-acc empty])
|
||
|
([c (in-string str)][pos (in-naturals)])
|
||
|
(if (even? pos)
|
||
|
(values (cons c santa-acc) robo-acc)
|
||
|
(values santa-acc (cons c robo-acc)))))
|
||
|
(define santa-str (string-append* (map ~a (reverse reversed-santa-path))))
|
||
|
(define robo-str (string-append* (map ~a (reverse reversed-robo-path))))
|
||
|
(length (remove-duplicates (append (str->visits santa-str) (str->visits robo-str)))))
|
||
|
|
||
|
|
||
|
(check-equal? (str->unique-visits ">") 2)
|
||
|
(check-equal? (str->unique-visits "^>v<") 4)
|
||
|
|
||
|
(check-equal? (str->robosanta "^v") 3)
|
||
|
(check-equal? (str->robosanta "^>v<") 3)
|
||
|
(check-equal? (str->robosanta "^v^v^v^v^v") 11)
|
||
|
|
||
|
|
||
|
(define (read-syntax source-path-string in-port)
|
||
|
(with-syntax ([source-str (string-trim (port->string in-port))]
|
||
|
[str->unique-visits str->unique-visits]
|
||
|
[str->robosanta str->robosanta])
|
||
|
#'(module _ racket
|
||
|
(str->unique-visits source-str)
|
||
|
(str->robosanta source-str))))
|