Question
Even only 52 cards, the
permutationIndex
where 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
permutationIndex
of 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
permutationIndex
to implement theDealing
methodAn algorithm which compute the correct
permutationIndex
to implement theCollect
methodAn algorithm which stores(or computes)
permutationIndex
with a minimal cost
Explanations
I originally try to implement a integer handle generator of a range from
int.MinVale
toint.MaxValue
using permutation.Because the range is really huge for that, thus I start from implement a
Dealer
class 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
permutationIndex
anddealt
(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,colleted
is the card number.
For more information, as follows.
Description of code
A conceptual sample
Dealer
class 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 changepermutationIndex
also, according to what the number of card was returned back to the dealer.The integer
dealt
tells how many cards we've dealt; from the left most to the count stored indealt
are 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
permutationIndex
is 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; }