Question
Even only 52 cards, the
permutationIndexwhere I describe in Explanations section, would be a huge number; it is a number in one of52!, and need 29 bytes to store.Thus I don't know a simple way to calculate the
permutationIndexof a huge range, and store the index with a mininal cost, or maybe it can also be calculated. I'm thinking solution of this question would be three algorithms:An algorithm which compute the correct
permutationIndexto implement theDealingmethodAn algorithm which compute the correct
permutationIndexto implement theCollectmethodAn algorithm which stores(or computes)
permutationIndexwith a minimal cost
Explanations
I originally try to implement a integer handle generator of a range from
int.MinValetoint.MaxValueusing permutation.Because the range is really huge for that, thus I start from implement a
Dealerclass with 52 cards which doesn't really store a deck of cards like hashset or array, and even don't want random(except initial).With a given range of ordinal numbers, I consider every sequence of one of full permutations has a index, and named it
permutationIndex. I use the index to remember which permutation it is and don't really store a sequence. The sequence is one of the possible order of the deck of card.And here is an example of emulation in animated graphics to show what I thought of.
Everytime I dealt a card, I change the
permutationIndexanddealt(count of dealt cards), that I know which cards are those dealt, and which are still in hand. When I collect a dealt card back, I'll know the card number, and put it on the top, it's also become the card for next time to deal. In the animation,colletedis the card number.
For more information, as follows.
Description of code
A conceptual sample
Dealerclass for only three 3 is as following. The code is written in c#, and I'm also considering any language-agnostic solutions.Here're some descriptions of the sample code
With the method
Dealing(), we get a number of the card which treat as dealt. It always returns the right most number (relevant to the array) and then rolls the number left from it (say the next available) to the right most position by changingpermutationIndex.The method
Collect(int)is for collecting and put the dealt cards back into the deck. It would changepermutationIndexalso, according to what the number of card was returned back to the dealer.The integer
dealttells how many cards we've dealt; from the left most to the count stored indealtare dealt cards. WithpermutationIndex, we know the sequence of cards.The
int[,]array in the sample code is not used, just for helping imagine the permutations. The switch statements are considered to be implemented with algorithms which compute for thepermutationIndex.The
permutationIndexis the same thing described in this answer of
Fast permutation -> number -> permutation mapping algorithms
Sample code
public static class Dealer { public static void Collect(int number) { if(1>dealt) throw new IndexOutOfRangeException(); switch(permutationIndex) { case 5: case 0: switch(number) { case 3: break; case 2: permutationIndex=1; break; case 1: permutationIndex=4; break; } break; case 4: case 3: switch(number) { case 3: permutationIndex=5; break; case 2: permutationIndex=2; break; case 1: break; } break; case 2: case 1: switch(number) { case 3: permutationIndex=0; break; case 2: break; case 1: permutationIndex=3; break; } break; } --dealt; } public static int Dealing() { if(dealt>2) throw new IndexOutOfRangeException(); var number=0; switch(permutationIndex) { case 5: permutationIndex=3; number=3; break; case 4: permutationIndex=0; number=1; break; case 3: permutationIndex=1; number=1; break; case 2: permutationIndex=4; number=2; break; case 1: permutationIndex=5; number=2; break; case 0: permutationIndex=2; number=3; break; } ++dealt; return number; } static int[,] sample= new[,] { { 1, 2, 3 }, // 0 { 1, 3, 2 }, // 1 { 3, 1, 2 }, // 2 { 3, 2, 1 }, // 3 { 2, 3, 1 }, // 4 { 2, 1, 3 }, // 5 }; static int permutationIndex; static int dealt; }