Initial commit
This commit is contained in:
commit
f242d2b0df
420 changed files with 62521 additions and 0 deletions
117
2019/day22/day22.rkt
Normal file
117
2019/day22/day22.rkt
Normal file
|
@ -0,0 +1,117 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/string
|
||||
math/number-theory)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(module+ main
|
||||
(displayln "Day 22"))
|
||||
|
||||
(define (read-instructions filename)
|
||||
(with-input-from-file filename
|
||||
(lambda ()
|
||||
(for/list ([line (in-lines)])
|
||||
(cond
|
||||
[(string-prefix? line "deal into new stack") 'deal]
|
||||
[(string-prefix? line "cut") `(cut ,(string->number (last (string-split line " "))))]
|
||||
[(string-prefix? line "deal with increment") `(increment ,(string->number (last (string-split line " "))))]
|
||||
[else 'other])))))
|
||||
|
||||
(define (deal deck)
|
||||
(reverse deck))
|
||||
|
||||
(define (cut deck n)
|
||||
(define split-fn (if (> n 0) split-at split-at-right))
|
||||
(define-values (a b) (split-fn deck (abs n)))
|
||||
(append b a))
|
||||
|
||||
(define (increment deck n)
|
||||
(for/list ([i (in-range (length deck))])
|
||||
(list-ref deck
|
||||
(remainder (* i (modular-inverse n (length deck))) (length deck)))))
|
||||
|
||||
(define (execute instruction deck)
|
||||
(match instruction
|
||||
['deal (deal deck)]
|
||||
[(list 'cut n) (cut deck n)]
|
||||
[(list 'increment n) (increment deck n)]))
|
||||
|
||||
(define (shuffle deck instructions)
|
||||
(for/fold ([d deck]) ([i instructions])
|
||||
(execute i d)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (shuffle (range 10) (read-instructions "test1")) '(0 3 6 9 2 5 8 1 4 7))
|
||||
(check-equal? (shuffle (range 10) (read-instructions "test2")) '(3 0 7 4 1 8 5 2 9 6))
|
||||
(check-equal? (shuffle (range 10) (read-instructions "test3")) '(6 3 0 7 4 1 8 5 2 9))
|
||||
(check-equal? (shuffle (range 10) (read-instructions "test4")) '(9 2 5 8 1 4 7 0 3 6)))
|
||||
|
||||
(module+ main
|
||||
(displayln "Part 1:")
|
||||
(define instructions (read-instructions "input"))
|
||||
(define deck (range 10007))
|
||||
(time (index-of (shuffle deck instructions) 2019)))
|
||||
|
||||
(define (deal-card deck-size card)
|
||||
(- (sub1 deck-size) card))
|
||||
|
||||
(define (cut-card deck-size n card)
|
||||
(modulo (- card n) deck-size))
|
||||
|
||||
(define (increment-card deck-size n card)
|
||||
(modulo (* n card) deck-size))
|
||||
|
||||
(define (execute-card deck-size instruction card)
|
||||
(match instruction
|
||||
['deal (deal-card deck-size card)]
|
||||
[(list 'cut n) (cut-card deck-size n card)]
|
||||
[(list 'increment n) (increment-card deck-size n card)]))
|
||||
|
||||
(define (shuffle-card deck-size instructions card)
|
||||
(for/fold ([c card]) ([i instructions])
|
||||
(execute-card deck-size i c)))
|
||||
|
||||
(module+ main
|
||||
(displayln "Part 1 (better):")
|
||||
(time (shuffle-card 10007 instructions 2019)))
|
||||
|
||||
(define (deal-card-inv deck-size card)
|
||||
(- (sub1 deck-size) card))
|
||||
|
||||
(define (cut-card-inv deck-size n card)
|
||||
(modulo (+ card n) deck-size))
|
||||
|
||||
(define (increment-card-inv deck-size n card)
|
||||
(remainder (* card (modular-inverse n deck-size)) deck-size))
|
||||
|
||||
(define (execute-card-inv deck-size instruction card)
|
||||
(match instruction
|
||||
['deal (deal-card-inv deck-size card)]
|
||||
[(list 'cut n) (cut-card-inv deck-size n card)]
|
||||
[(list 'increment n) (increment-card-inv deck-size n card)]))
|
||||
|
||||
(define (shuffle-card-inv deck-size reversed-instructions card)
|
||||
(for/fold ([c card]) ([i reversed-instructions])
|
||||
(execute-card-inv deck-size i c)))
|
||||
|
||||
(module+ main
|
||||
(displayln "Part 2:")
|
||||
(define deck-size 119315717514047)
|
||||
(define iterations 101741582076661)
|
||||
|
||||
;; Operations are linear, we find the coefficients and apply them directly
|
||||
(define x 2020)
|
||||
(define y (shuffle-card-inv deck-size (reverse instructions) x))
|
||||
(define z (shuffle-card-inv deck-size (reverse instructions) y))
|
||||
|
||||
(define a (modulo (* (- z y) (modular-inverse (- y x) deck-size)) deck-size))
|
||||
(define b (modulo (- y (* a x)) deck-size))
|
||||
|
||||
(modulo (+ (* (modular-expt a iterations deck-size)
|
||||
x)
|
||||
(* (sub1 (modular-expt a iterations deck-size))
|
||||
(modular-inverse (sub1 a) deck-size)
|
||||
b))
|
||||
deck-size))
|
Loading…
Add table
Add a link
Reference in a new issue