Overview
Comment: | Add first and second tries at Day 9 solutions — too slow! |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
711f70fcf589408957343f260fd24008 |
User & Date: | joel on 2018-12-13 19:01:52 |
Original Comment: | Add first and second tries at Day 9 solutions -- too slow! |
Other Links: | manifest | tags |
Context
2018-12-14
| ||
04:46 | Add Day 9 solution finally! check-in: 3893cb user: joel tags: trunk | |
2018-12-13
| ||
19:01 | Add first and second tries at Day 9 solutions — too slow! check-in: 711f70 user: joel tags: trunk | |
2018-12-10
| ||
01:05 | Add Day 9 input check-in: 404a9b user: joel tags: trunk | |
Changes
Added day09-try1.rkt version [f8315f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #lang racket (require sugar rackunit) (define input (map string->number (rest (regexp-match #px"(\\d+) players; last marble is worth (\\d+) points" (file->string "day09-input.txt"))))) (match-define (list num-players last-marble-pts) input) (define circle (list 0)) ;; Note these number refers to the “nth“ spots in their lists; ;; they are not zero-based! (define cur-marble 1) (define cur-player 1) (define players (make-list num-players 0)) (define (set-next-player!) (define n (add1 cur-player)) (set! cur-player (if (> n (length players)) (- n (length players)) n))) (define (add-to-current-player-score! score) (define new-score (+ score (list-ref players (sub1 cur-player)))) (set! players (list-set players (sub1 cur-player) new-score))) ;; Inserts an item into the `circle` list after the element specified (define (insert-into-circle! val after-nth) (set! circle (append (take circle after-nth) (list val) (drop circle after-nth))) (set! cur-marble (add1 after-nth))) ;; Returns the count of the element in `circle` after which the ;; next marble should be placed (define (next-marble-after-nth) (define n (add1 cur-marble)) (cond [(> n (length circle)) (- n (length circle))] [else n])) (define (remove-nth-marble! n) (set! circle (append (take circle (sub1 n)) (drop circle n))) (set! cur-marble n)) (define (score! marble-val) (define 7th-marble-clockwise (cond [(> cur-marble 7) (- cur-marble 7)] [else (+ (length circle) (- cur-marble 7))])) (define 7th-marble-value (list-ref circle (sub1 7th-marble-clockwise))) (define turn-score (+ marble-val 7th-marble-value)) (add-to-current-player-score! turn-score) (set-next-player!) (remove-nth-marble! 7th-marble-clockwise)) ;; Place a marble in the correct spot (define (place-marble! new-marble-val) (cond [(zero? (modulo new-marble-val 23)) (score! new-marble-val)] [else (define after-nth (next-marble-after-nth)) (insert-into-circle! new-marble-val after-nth)])) (define (test n) (for ([i (in-range n)]) (place-marble! (add1 i)))) ;; Gets me the correct answer (374287) (define (day09-part1) (for ([i (in-range last-marble-pts)]) (place-marble! (add1 i))) (apply max players)) ;; I left this running overnight and it did not finish! (define (day09-part2) (set! last-marble-pts (* 100 last-marble-pts)) (day09-part1)) |
Added day09-try2.rkt version [7a2374].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #lang racket (require rackunit) (define input (map string->number (rest (regexp-match #px"(\\d+) players; last marble is worth (\\d+) points" (file->string "day09-input.txt"))))) (match-define (list num-players last-marble-pts) input) ;; In this variation, the circle is stored as a list. The “current” ;; marble is always the first item in the list. (define (insert-and-rotate circle val after-nth) (values (append (list val) (drop circle (min after-nth (length circle))) (take circle (min after-nth (length circle)))) 0)) ;; Remove the marble in the Nth slot, rotating the “circle” so the marble ;; to the right of the removed one is now in the front. ;; Returns both the rotated list and the value of the removed marble (define (remove-and-rotate circle nth) (values (append (drop circle nth) (take circle (sub1 nth))) (list-ref circle (sub1 nth)))) (define (add-to-spot lst pos val) (append (take lst pos) (list (+ val (list-ref lst pos))) (drop lst (add1 pos)))) (define (play-game num-players until-marble) (for/fold ([scores (make-list num-players 0)] [circle (list 0)]) ([player (in-cycle (range num-players))] [cur-marble (in-naturals 1)]) #:final (equal? cur-marble until-marble) (define-values (result-circle turn-score) (cond [(zero? (modulo cur-marble 23)) (remove-and-rotate circle (- (length circle) 6))] [else (insert-and-rotate circle cur-marble 2)])) (values (add-to-spot scores player (* (+ cur-marble turn-score) (sgn turn-score))) result-circle))) (define (high-score num-players until-marble) (let-values ([(scores _) (play-game num-players until-marble)]) (apply max scores))) ; Finishes in 78 seconds on a 2015 Apple rMBP (define (day09-part1) (high-score num-players last-marble-pts)) (module+ test ;(check-equal? (high-score 10 1618) 8317) ;(check-equal? (high-score 13 7999) 146373) ;(check-equal? (high-score 17 1104) 2764) ;(check-equal? (high-score 21 6111) 54718) ;(check-equal? (high-score 30 5807) 37305) (check-equal? (time (day09-part1)) 374287)) ; Correct answer for part 1 ; Ran overnight — still didn’t finish! (define (day09-part2) (high-score num-players (* 100 last-marble-pts))) |