Day 22: Part 1 complete, part 2... still running?
This commit is contained in:
parent
e197679510
commit
d1c8482e7d
|
@ -0,0 +1,100 @@
|
||||||
|
deal with increment 31
|
||||||
|
deal into new stack
|
||||||
|
cut -7558
|
||||||
|
deal with increment 49
|
||||||
|
cut 194
|
||||||
|
deal with increment 23
|
||||||
|
cut -4891
|
||||||
|
deal with increment 53
|
||||||
|
cut 5938
|
||||||
|
deal with increment 61
|
||||||
|
cut 7454
|
||||||
|
deal into new stack
|
||||||
|
deal with increment 31
|
||||||
|
cut 3138
|
||||||
|
deal with increment 53
|
||||||
|
cut 3553
|
||||||
|
deal with increment 61
|
||||||
|
cut -5824
|
||||||
|
deal with increment 42
|
||||||
|
cut -889
|
||||||
|
deal with increment 34
|
||||||
|
cut 7128
|
||||||
|
deal with increment 42
|
||||||
|
cut -9003
|
||||||
|
deal with increment 75
|
||||||
|
cut 13
|
||||||
|
deal with increment 75
|
||||||
|
cut -3065
|
||||||
|
deal with increment 74
|
||||||
|
cut -8156
|
||||||
|
deal with increment 39
|
||||||
|
cut 4242
|
||||||
|
deal with increment 24
|
||||||
|
cut -405
|
||||||
|
deal with increment 27
|
||||||
|
cut 6273
|
||||||
|
deal with increment 19
|
||||||
|
cut -9826
|
||||||
|
deal with increment 58
|
||||||
|
deal into new stack
|
||||||
|
cut -6927
|
||||||
|
deal with increment 65
|
||||||
|
cut -9906
|
||||||
|
deal with increment 31
|
||||||
|
deal into new stack
|
||||||
|
deal with increment 42
|
||||||
|
deal into new stack
|
||||||
|
deal with increment 39
|
||||||
|
cut -4271
|
||||||
|
deal into new stack
|
||||||
|
deal with increment 32
|
||||||
|
cut -8799
|
||||||
|
deal with increment 69
|
||||||
|
cut 2277
|
||||||
|
deal with increment 55
|
||||||
|
cut 2871
|
||||||
|
deal with increment 54
|
||||||
|
cut -2118
|
||||||
|
deal with increment 15
|
||||||
|
cut 1529
|
||||||
|
deal with increment 57
|
||||||
|
cut -4745
|
||||||
|
deal with increment 23
|
||||||
|
cut -5959
|
||||||
|
deal with increment 58
|
||||||
|
deal into new stack
|
||||||
|
deal with increment 48
|
||||||
|
deal into new stack
|
||||||
|
cut 2501
|
||||||
|
deal into new stack
|
||||||
|
deal with increment 42
|
||||||
|
deal into new stack
|
||||||
|
cut 831
|
||||||
|
deal with increment 74
|
||||||
|
cut -3119
|
||||||
|
deal with increment 33
|
||||||
|
cut 967
|
||||||
|
deal with increment 69
|
||||||
|
cut 9191
|
||||||
|
deal with increment 9
|
||||||
|
cut 5489
|
||||||
|
deal with increment 62
|
||||||
|
cut -9107
|
||||||
|
deal with increment 14
|
||||||
|
cut -7717
|
||||||
|
deal with increment 56
|
||||||
|
cut 7900
|
||||||
|
deal with increment 49
|
||||||
|
cut 631
|
||||||
|
deal with increment 14
|
||||||
|
deal into new stack
|
||||||
|
deal with increment 58
|
||||||
|
cut -9978
|
||||||
|
deal with increment 48
|
||||||
|
deal into new stack
|
||||||
|
deal with increment 66
|
||||||
|
cut -1554
|
||||||
|
deal into new stack
|
||||||
|
cut 897
|
||||||
|
deal with increment 36
|
|
@ -0,0 +1,92 @@
|
||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require match-string
|
||||||
|
"../lib.rkt")
|
||||||
|
|
||||||
|
(define input
|
||||||
|
(problem-input 22))
|
||||||
|
|
||||||
|
(define (parse-technique technique)
|
||||||
|
(match technique
|
||||||
|
["deal into new stack" deal-into-new-stack]
|
||||||
|
[(string-append "cut " s) (∂ cut-N-cards (string->number s))]
|
||||||
|
[(string-append "deal with increment " s) (∂ deal-with-increment-N (string->number s))]))
|
||||||
|
|
||||||
|
(define (deal-into-new-stack cards)
|
||||||
|
(reverse cards))
|
||||||
|
|
||||||
|
(define (cut-N-cards n cards)
|
||||||
|
(if (negative? n)
|
||||||
|
(cut-N-cards (+ (length cards) n) cards)
|
||||||
|
(append (drop cards n) (take cards n))))
|
||||||
|
|
||||||
|
(define (deal-with-increment-N n cards)
|
||||||
|
(let* ([len (length cards)]
|
||||||
|
[vec (make-vector len)])
|
||||||
|
(for ([index (range 0 len)]
|
||||||
|
[card cards])
|
||||||
|
(vector-set! vec (modulo (* index n) len) card))
|
||||||
|
(vector->list vec)))
|
||||||
|
|
||||||
|
(define part1
|
||||||
|
(let loop ([cards (range 0 10007)]
|
||||||
|
[shuffle input])
|
||||||
|
(if (empty? shuffle)
|
||||||
|
(index-of cards 2019)
|
||||||
|
(loop ((parse-technique (first shuffle)) cards) (rest shuffle)))))
|
||||||
|
|
||||||
|
;; egcd : number -> number -> (list number number number)
|
||||||
|
;; Extended Euclidean algorithm for computing GCD
|
||||||
|
;; Given integers a and b, return gcd(a, b), x, and y, where
|
||||||
|
;; ax + by = gcd(a, b).
|
||||||
|
(define (egcd a b)
|
||||||
|
(if (zero? a)
|
||||||
|
(list b 0 1)
|
||||||
|
(match-let ([(list g x y) (egcd (remainder b a) a)])
|
||||||
|
(list g (- y (* x (quotient b a))) x))))
|
||||||
|
|
||||||
|
;; mmi : number -> number -> number
|
||||||
|
;; Modular multiplicative inverse
|
||||||
|
;; Given an integer n and a modulus m, return x such that
|
||||||
|
;; nx ≡ 1 (mod m), i.e. nx + my = 1 for some x, y.
|
||||||
|
;; We therefore require that n and m are coprime.
|
||||||
|
(define (mmi n m)
|
||||||
|
(match-let ([(list g x y) (egcd n m)])
|
||||||
|
x))
|
||||||
|
|
||||||
|
;; The following functions are inverse to those from part 1
|
||||||
|
;; with respect to the card indices.
|
||||||
|
;; That is, if some shuffling technique s takes a card at index i
|
||||||
|
;; and moves it to index s(i) = j, then s^-1(j) = i.
|
||||||
|
;; Therefore, if after applying a series of shuffling techniques,
|
||||||
|
;; we want to know what card is at position p,
|
||||||
|
;; we apply the inverse functions in reverse order to find its original index.
|
||||||
|
|
||||||
|
(define (inverse-DINS len i)
|
||||||
|
(sub1 (- len i)))
|
||||||
|
|
||||||
|
(define (inverse-CNC len n i)
|
||||||
|
(if (positive? n)
|
||||||
|
(modulo (+ n i) len)
|
||||||
|
(modulo (+ n i len) len)))
|
||||||
|
|
||||||
|
(define (inverse-DWIN len n i)
|
||||||
|
(modulo (* (mmi n len) i) len))
|
||||||
|
|
||||||
|
(define (inverse-parse len technique)
|
||||||
|
(match technique
|
||||||
|
["deal into new stack" (∂ inverse-DINS len)]
|
||||||
|
[(string-append "cut " s) (∂ inverse-CNC len (string->number s))]
|
||||||
|
[(string-append "deal with increment " s) (∂ inverse-DWIN len (string->number s))]))
|
||||||
|
|
||||||
|
(define (inverse-shuffle len)
|
||||||
|
(apply compose (map (∂ inverse-parse len) input)))
|
||||||
|
|
||||||
|
(define (part2)
|
||||||
|
(let loop ([count 101741582076661]
|
||||||
|
[index 2020])
|
||||||
|
(if (zero? count)
|
||||||
|
index
|
||||||
|
(loop (sub1 count) ((inverse-shuffle 119315717514047) index)))))
|
||||||
|
|
||||||
|
(show-solution part1 #f)
|
Loading…
Reference in New Issue