Skip to content

Instantly share code, notes, and snippets.

@joriki
Created June 2, 2016 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joriki/9abf803fa0a2c40b04e216e9bffa0c78 to your computer and use it in GitHub Desktop.
Save joriki/9abf803fa0a2c40b04e216e9bffa0c78 to your computer and use it in GitHub Desktop.
Calculate the probabilities of correctly guessing the suit of the n-th card of a standard deck; see http://math.stackexchange.com/questions/95968.
import java.math.BigInteger;
import java.util.Arrays;
public class Question95968 {
static Rational sum;
static Rational average = Rational.ZERO;
public static void main (String [] args) {
Multiset deck = new Multiset (new int [] {13,13,13,13});
for (int n = 52;n > 0;n--) {
sum = Rational.ZERO;
final int total = n;
deck.traverseSubsets (n,new MultisetHandler() {
public void handle (int [] left,BigInteger multiplicity) {
int max = 0;
for (int l : left)
max = Math.max (max,l);
sum = sum.add (new Rational (max,total).multiply (multiplicity));
}
});
sum = sum.divide (Binomials.binomial (52,n));
System.out.println (" " + (52 - n) + " : " + sum);
average = average.add (sum);
}
average = average.divide (52);
System.out.println ();
System.out.println (average);
}
}
interface MultisetHandler {
void handle (int [] multiset,BigInteger multiplicity);
}
class Multiset {
int [] counts;
public Multiset (int [] counts) {
this.counts = counts;
}
public void traverseSubsets (int n,MultisetHandler handler) {
traverseSubsets (new int [counts.length],BigInteger.ONE,0,n,handler);
}
private void traverseSubsets (int [] multiset,BigInteger multiplicity,int k,int nleft,MultisetHandler handler) {
if (k == counts.length)
handler.handle (multiset,multiplicity);
else
for (multiset [k] = k == counts.length - 1 ? nleft : 0;multiset [k] <= nleft && multiset [k] <= counts [k];multiset [k]++)
traverseSubsets (multiset,multiplicity.multiply (Binomials.binomial (counts [k],multiset [k])),k + 1,nleft - multiset [k],handler);
}
static Multiset getSet (int n) {
int [] counts = new int [n];
Arrays.fill (counts,1);
return new Multiset (counts);
}
}
class Binomials {
static BigInteger [] [] binomials = new BigInteger [0] [0];
static BigInteger binomial (int n,int k) {
if (k < 0 || n < 0)
throw new UnsupportedOperationException ();
if (k > n)
return BigInteger.ZERO;
if (n >= binomials.length) {
BigInteger [] [] old = binomials;
binomials = new BigInteger [n + 1] [];
for (int i = 0;i <= n;i++)
binomials [i] = i < old.length ? old [i] : new BigInteger [i + 1];
}
if (binomials [n] [k] == null) {
binomials [n] [k] = BigInteger.ONE;
for (int i = 0;i < k;i++)
binomials [n] [k] = binomials [n] [k].multiply (BigInteger.valueOf (n - i)).divide (BigInteger.valueOf (i + 1));
}
return binomials [n] [k];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment