Skip to content

Instantly share code, notes, and snippets.

@joriki
Created March 31, 2020 12:02
Show Gist options
  • Save joriki/500226cd6f9a7475cb56e67febdd8553 to your computer and use it in GitHub Desktop.
Save joriki/500226cd6f9a7475cb56e67febdd8553 to your computer and use it in GitHub Desktop.
Calculate the exaxt probability distribution for the number of pairs of consecutive cards with matching suits; see https://math.stackexchange.com/questions/3602087.
package temp;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Question3602087a {
final static int NSUITS = 4;
final static int NRANKS = 13;
final static int NCARDS = NRANKS * NSUITS;
static class DeckState {
int [] ranksLeft;
int previousSuit;
public DeckState() {
ranksLeft = new int [NSUITS];;
Arrays.fill(ranksLeft, NRANKS);
previousSuit = -1;
}
public DeckState (DeckState state) {
ranksLeft = state.ranksLeft.clone();
}
public int hashCode() {
return Arrays.hashCode(ranksLeft) * NSUITS + previousSuit;
}
public boolean equals(Object o) {
DeckState s = (DeckState) o;
return s.previousSuit == previousSuit && Arrays.equals(ranksLeft, s.ranksLeft);
}
}
static class Statistics {
static BigInteger [] zeroCounts = new BigInteger [NCARDS];
static {
Arrays.fill(zeroCounts, BigInteger.ZERO);
}
BigInteger [] counts = zeroCounts.clone();
}
public static void main(String [] args) {
Map<DeckState,Statistics> stateMap = new HashMap<>();
stateMap.put(new DeckState(), new Statistics());
stateMap.values().iterator().next().counts [0] = BigInteger.ONE;
for (int i = 0;i < NCARDS;i++) {
Map<DeckState,Statistics> newStateMap = new HashMap<>();
for (DeckState state : stateMap.keySet()) {
Statistics statistics = stateMap.get(state);
for (int suit = 0;suit < NSUITS;suit++)
if (state.ranksLeft [suit] > 0) {
BigInteger factor = BigInteger.valueOf(state.ranksLeft [suit]);
DeckState newState = new DeckState(state);
newState.ranksLeft [suit]--;
newState.previousSuit = suit;
Statistics newStatistics = newStateMap.get(newState);
if (newStatistics == null) {
newStatistics = new Statistics();
newStateMap.put(newState, newStatistics);
}
int offset = suit == state.previousSuit ? 1 : 0;
for (int j = 0;j + offset < NCARDS;j++)
newStatistics.counts [j + offset] = newStatistics.counts [j + offset].add(statistics.counts [j].multiply(factor));
}
}
stateMap = newStateMap;
}
// there are NSUITS states left, one for each suit of the last card
Statistics total = new Statistics();
BigInteger sum = BigInteger.ZERO;
for (Statistics statistics : stateMap.values())
for (int i = 0;i < NCARDS;i++) {
total.counts [i] = total.counts [i].add(statistics.counts [i]);
sum = sum.add(statistics.counts [i]);
}
for (int i = 0;i < NCARDS;i++)
System.out.println(i + " : " + total.counts [i].doubleValue() / sum.doubleValue());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment