1
0
Fork 0

Day 22: Part 1 complete, part 2... still running?

This commit is contained in:
Jonathan Chan 2019-12-22 00:50:36 -08:00
parent e197679510
commit d1c8482e7d
2 changed files with 192 additions and 0 deletions

100
input/22.txt Normal file
View File

@ -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

92
src/22.rkt Normal file
View File

@ -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)