d09 p1 (fasterer)

master
Matthew Butterick 6 years ago
parent 3bd4194aa1
commit 5a2032e734

@ -1,47 +1,38 @@
#lang debug br #lang debug br
(require racket/file) (require racket/file)
(define (mlength mprs [acc 0])
(if (null? mprs)
acc
(mlength (mcdr mprs) (add1 acc))))
(define (nth-mpr mprs n) (define (nth-mpr mprs n)
(for/fold ([mprs mprs]) (for/fold ([mprs mprs])
([i (in-range n)]) ([i (in-range n)])
(mcdr mprs))) (mcdr mprs)))
(define () (define ()
(match-define (list player-count marble-count) (match-define (list player-count max-marbles)
(map string->number (regexp-match* #px"\\d+" (file->string "09.txt")))) (map string->number (regexp-match* #px"\\d+" (file->string "09.txt"))))
(define scores (make-hasheqv)) (define scores (make-hasheqv))
(define circle (mcons #f (mcons 0 null))) (define circle (mcons #f (mcons 0 null)))
(let loop ([marble 1] [pos 0]) (let loop ([marble 1] [marbles-in-circle 1] [pos 0])
(cond (cond
[(> marble marble-count) (argmax cdr (hash->list scores))] [(> marble max-marbles) (cdr (argmax cdr (hash->list scores)))]
[(zero? (modulo marble 23)) [(zero? (modulo marble 23))
(define marble-count (sub1 (mlength circle))) (define deletion-pos (modulo (+ (- pos 7) marbles-in-circle) marbles-in-circle))
(define deletion-pos (modulo (+ (- pos 7) marble-count) marble-count))
(define last-left-mpr (nth-mpr circle deletion-pos)) (define last-left-mpr (nth-mpr circle deletion-pos))
(define removed-marble (mcar (mcdr last-left-mpr))) (define removed-marble (mcar (mcdr last-left-mpr)))
(set-mcdr! last-left-mpr (mcdr (mcdr last-left-mpr))) (set-mcdr! last-left-mpr (mcdr (mcdr last-left-mpr)))
(define player (modulo marble player-count)) (define player (modulo marble player-count))
(hash-update! scores player (λ (sc) (+ removed-marble marble sc)) 0) (hash-update! scores player (λ (sc) (+ removed-marble marble sc)) 0)
(loop (add1 marble) deletion-pos)] (loop (add1 marble) (sub1 marbles-in-circle) deletion-pos)]
[else [else
(define marble-count (sub1 (mlength circle))) (define next-pos (add1 (modulo (add1 pos) marbles-in-circle)))
(define next-pos (add1 (modulo (add1 pos) marble-count)))
(define last-left-mpr (nth-mpr circle next-pos)) (define last-left-mpr (nth-mpr circle next-pos))
(set-mcdr! last-left-mpr (mcons marble (mcdr last-left-mpr))) (set-mcdr! last-left-mpr (mcons marble (mcdr last-left-mpr)))
(loop (add1 marble) next-pos)]))) (loop (add1 marble) (add1 marbles-in-circle) next-pos)])))
(time ())
#;(define (★★) #;(define (★★)
) )
#;(★★) #;(★★)
#;(module+ test (module+ test
(require rackunit) (require rackunit)
(check-equal? (time ()) 437654) (check-equal? (time ()) 437654)
(check-equal? (time (★★)) 566)) #;(check-equal? (time (★★)) 566))