Ejemplo n.º 1
0
        public static LCG GetShuffleFunction(
            BigInteger deckSize,
            IList <ShuffleInstruction> shuffleInstructions)
        {
            // Combine all shuffle instructions into one LCG
            var result           = LCG.GetIdentity(deckSize);
            var dealIntoNewStack = GetShuffleFunctionDealIntoNewStack(deckSize);

            foreach (var shuffleInstruction in shuffleInstructions)
            {
                if (ShuffleTechnique.DealIntoNewStack.Equals(shuffleInstruction.Technique))
                {
                    result = LCG.Compose(result, dealIntoNewStack);
                }
                else if (ShuffleTechnique.CutNCards.Equals(shuffleInstruction.Technique))
                {
                    var cutNCards = GetShuffleFunctionCutNCards(shuffleInstruction.ShuffleParameter, deckSize);
                    result = LCG.Compose(result, cutNCards);
                }
                else if (ShuffleTechnique.DealWithIncrementN.Equals(shuffleInstruction.Technique))
                {
                    var dealWithIncrementN = GetShuffleFunctionDealWithIncrementN(shuffleInstruction.ShuffleParameter, deckSize);
                    result = LCG.Compose(result, dealWithIncrementN);
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
        public static BigInteger ShuffleCard(
            BigInteger startCardIndex,
            BigInteger deckSize,
            BigInteger numberOfShuffles,
            IList <ShuffleInstruction> shuffleInstructions,
            bool runBackwards)
        {
            var shuffleFunction = GetShuffleFunction(deckSize, shuffleInstructions);

            // Compose the shuffle function into itself once for each shuffle pass
            shuffleFunction = ExponentiationHelper.GetExponentiationByPowers(
                x: shuffleFunction,
                exponent: numberOfShuffles,
                MultiplyFunction: LCG.Compose,
                identity: LCG.GetIdentity(deckSize));
            // If we are running backwards, then use the inverse of the
            // shuffle function
            if (runBackwards)
            {
                shuffleFunction = shuffleFunction.GetInverse();
            }
            var endCardIndex = shuffleFunction.Evaluate(startCardIndex);

            return(endCardIndex);
        }
        public void GetExponentiationByPowersLCFTest()
        {
            var testData = new List <Tuple <LCG, BigInteger, Func <LCG, LCG, LCG>, LCG> >()
            {
                // f(f(f(x))) where f(x) = 2*x + 3 (mod 5)
                // f(f(f(x)))   = f(f(2x + 3))
                //              = f(2*(2x + 3) + 3)
                //              = f(4x + 6 + 3)
                //              = f(4x + 9)
                //              = 2*(4x + 9) + 3
                //              = 8x + 18 + 3
                //              = 8x + 21 (mod 5)
                Tuple.Create(
                    new LCG(2, 3, 5),
                    (BigInteger)0,
                    (Func <LCG, LCG, LCG>)LCG.Compose,
                    LCG.GetIdentity(5)),
                Tuple.Create(
                    new LCG(2, 3, 5),
                    (BigInteger)1,
                    (Func <LCG, LCG, LCG>)LCG.Compose,
                    new LCG(2, 3, 5)),
                Tuple.Create(
                    new LCG(2, 3, 5),
                    (BigInteger)3,
                    (Func <LCG, LCG, LCG>)LCG.Compose,
                    new LCG(8, 21, 5)),
            };

            foreach (var testExample in testData)
            {
                var result = ExponentiationHelper.GetExponentiationByPowers <LCG>(
                    x: testExample.Item1,
                    exponent: testExample.Item2,
                    MultiplyFunction: testExample.Item3,
                    identity: LCG.GetIdentity(testExample.Item1.M));
                Assert.Equal(testExample.Item4, result);
            }
        }