Created
June 2, 2016 22:19
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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