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.
62 lines
2.1 KiB
Racket
62 lines
2.1 KiB
Racket
7 years ago
|
#lang reader "../aoc-lang.rkt"
|
||
|
(provide (rename-out [#%mb #%module-begin]) ★ ★★)
|
||
|
|
||
|
(define-macro (#%mb (STARS SIZE) (MOVE ...) ...)
|
||
|
#`(#%module-begin
|
||
|
(time (STARS SIZE '(MOVE ...)) ...)))
|
||
|
|
||
|
(define (spin ps num)
|
||
|
(define ps-len (vector-length ps))
|
||
|
(for/vector ([idx (in-range ps-len)])
|
||
|
(vector-ref ps (modulo (- idx num) ps-len))))
|
||
|
|
||
|
(define (exchange ps left right)
|
||
|
(define new-vec (vector-copy ps))
|
||
|
(vector-set*! new-vec
|
||
|
left (vector-ref ps right)
|
||
|
right (vector-ref ps left))
|
||
|
new-vec)
|
||
|
|
||
|
(define (partner ps left right)
|
||
|
(exchange ps (vector-member left ps) (vector-member right ps)))
|
||
|
|
||
|
(define (starting-vec size)
|
||
|
(list->vector (take '(a b c d e f g h i j k l m n o p q r s t) size)))
|
||
|
|
||
|
(define (thunkify move)
|
||
|
(define move-str (symbol->string move))
|
||
|
(cond
|
||
|
[(regexp-match #px"(?<=^s)\\d+(?=$)" move-str)
|
||
|
=> (λ (m)
|
||
|
(define num (string->number (car m)))
|
||
|
(λ (ps) (spin ps num)))]
|
||
|
[(regexp-match #px"(?<=^x)\\d+/\\d+(?=$)" move-str)
|
||
|
=> (λ (m)
|
||
|
(define nums (map string->number (string-split (car m) "/")))
|
||
|
(λ (ps) (apply exchange ps nums)))]
|
||
|
[(regexp-match #px"(?<=^p)\\w/\\w(?=$)" move-str)
|
||
|
=> (λ (m)
|
||
|
(define syms (map string->symbol (string-split (car m) "/")))
|
||
|
(λ (ps) (apply partner ps syms)))]
|
||
|
[else (error move-str)]))
|
||
|
|
||
|
(define (dance vec moves [rounds 1])
|
||
|
(for*/fold ([vec vec])
|
||
|
([round (in-range rounds)]
|
||
|
[move-thunk (in-list (map thunkify moves))])
|
||
|
(move-thunk vec)))
|
||
|
|
||
|
(define (★ size moves [rounds 1])
|
||
|
(string-append* (map ~a (vector->list (dance (starting-vec size) moves rounds)))))
|
||
|
|
||
|
(define (★★ size moves)
|
||
|
(define cycle-length (for/fold ([vecs (list (starting-vec size))]
|
||
|
#:result (length (cdr vecs)))
|
||
|
([i (in-naturals)]
|
||
|
#:break (member (car vecs) (cdr vecs)))
|
||
|
(cons (dance (car vecs) moves) vecs)))
|
||
|
(define one-billion (expt 10 9))
|
||
|
(define iterations-needed (modulo one-billion cycle-length))
|
||
|
(★ size moves iterations-needed))
|
||
|
|