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); }
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); } }