From 3bd4194aa19fde6c671356e4a99532342573becb Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Wed, 19 Dec 2018 08:39:55 -0800 Subject: [PATCH] d09 p1 (faster) --- 2018/09.rkt | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/2018/09.rkt b/2018/09.rkt index 5aeb6e7..b630af8 100644 --- a/2018/09.rkt +++ b/2018/09.rkt @@ -1,24 +1,41 @@ #lang debug br (require racket/file) +(define (mlength mprs [acc 0]) + (if (null? mprs) + acc + (mlength (mcdr mprs) (add1 acc)))) + +(define (nth-mpr mprs n) + (for/fold ([mprs mprs]) + ([i (in-range n)]) + (mcdr mprs))) + (define (★) (match-define (list player-count marble-count) (map string->number (regexp-match* #px"\\d+" (file->string "09.txt")))) (define scores (make-hasheqv)) - (let loop ([marble 1] [pos 0] [circle (list 0)]) + (define circle (mcons #f (mcons 0 null))) + (let loop ([marble 1] [pos 0]) (cond [(> marble marble-count) (argmax cdr (hash->list scores))] - [(zero? (modulo marble 23)) - (define len (length circle)) - (define deletion-pos (modulo (+ (- pos 7) len) len)) - (define-values (head tail) (split-at circle deletion-pos)) + [(zero? (modulo marble 23)) + (define marble-count (sub1 (mlength circle))) + (define deletion-pos (modulo (+ (- pos 7) marble-count) marble-count)) + (define last-left-mpr (nth-mpr circle deletion-pos)) + (define removed-marble (mcar (mcdr last-left-mpr))) + (set-mcdr! last-left-mpr (mcdr (mcdr last-left-mpr))) (define player (modulo marble player-count)) - (hash-update! scores player (λ (sc) (+ marble (car tail) sc)) 0) - (loop (add1 marble) deletion-pos (append head (cdr tail)))] + (hash-update! scores player (λ (sc) (+ removed-marble marble sc)) 0) + (loop (add1 marble) deletion-pos)] [else - (define next-pos (add1 (modulo (add1 pos) (length circle)))) - (define-values (head tail) (split-at circle next-pos)) - (loop (add1 marble) next-pos (append head (list marble) tail))]))) + (define marble-count (sub1 (mlength circle))) + (define next-pos (add1 (modulo (add1 pos) marble-count))) + (define last-left-mpr (nth-mpr circle next-pos)) + (set-mcdr! last-left-mpr (mcons marble (mcdr last-left-mpr))) + (loop (add1 marble) next-pos)]))) + +(time (★)) #;(define (★★) )