#!/usr/bin/perl -w # #Suit Split Calculator # #Calculates the probability of suit splits based on #a given number of known cards outside the suit. # #Based on an algorithm provided by Marvin L. French #(mlfrench@writeme.com) # #Send me email if you like it or have any bugs to #report. # #Darin Takemoto #takemoto@xtal0.harvard.edu #takemoto@thecia.net # START: $known1 = &entry("known cards", "Hand 1"); $known2 = &entry("known cards", "Hand 2"); $testtotal = &entry("cards", "test suit"); if (($known1 + $known2 + $testtotal) > 26) { printf "Too many cards.\n"; goto START }; $maxtest1 = $maxtest2 = $testtotal; if (($known1 + $testtotal) > 13) { $maxtest1 = 13 - $known1 }; if (($known2 + $testtotal) > 13) { $maxtest2 = 13 - $known2 }; $num = &fact(13 - $known1) * &fact(13 - $known2) * &fact($testtotal) * &fact(26 - $known1 - $known2 - $testtotal); for ($i = $maxtest1; $i ge ($testtotal - $maxtest2); $i--) { $j = $testtotal - $i; $dem = &fact($i) * &fact($j) * &fact(13 - $known1 - $i) * &fact(13 - $known2 - $j) * &fact(26 - $known1 - $known2); $prob = $num/$dem; $prob = (int(($prob * 1000) + 0.5))/1000; #round to 3 sig figs if ($prob == 0) {$prob = "< 0.0005"}; #even 0 means there is a small chance printf "Probability of $i cards in Hand 1 and $j cards in Hand 2: $prob\n"; } AGAIN: printf "Try again? (yn): "; $again = ; chop($again); if ($again !~ /^(n|y)/i) { printf "Very funny.\n"; goto AGAIN }; if ($again =~ /^y/i) { goto START }; printf "Bye bye!\n"; exit 0; #Subroutine to handle data entry # sub entry { $known = shift; $name = shift; SSUB: printf "Enter number of $known in $name: "; $data = ; chop($data); if ($data !~ /^\d+$/) { printf "Integers only, please.\n"; goto SSUB }; if (($data < 0) || ($data > 13)) { printf "Invalid number of cards in $name.\n"; goto SSUB }; return $data; } #Factorial function # sub fact { $val = shift; if ($val < 0) { die "Invalid value for factorial:" }; if ($val < 2) { return 1 }; $temp = 1; for ($k = $val; $k > 1; $k--) { $temp *= $k; } return $temp; }