Dice - Chance of 5 Twos

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math topics]   [Library]   [Utilities]




Search WWW

Search DelphiForFun.org

As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.


Support DFF - Shop

 If you shop at Amazon anyway,  consider using this link. 


We receive a few cents from each purchase.  Thanks


Support DFF - Donate

 If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

Mensa Daily Puzzlers

For over 15 years Mensa Page-A-Day calendars have provided several puzzles a year for my programming pleasure.  Coding "solvers" is most fun, but many programs also allow user solving, convenient for "fill in the blanks" type.  Below are Amazon  links to the two most recent years.

Mensa 365 Puzzlers  Calendar 2017

Mensa 365 Puzzlers Calendar 2018

(Hint: If you can wait, current year calendars are usually on sale in January.)


Feedback:  Send an e-mail with your comments about this program (or anything else).

Search DelphiForFun.org only




Problem Description

Today's program was prompted by this recent feedback email to DFF:

My local bar has a game. 5 dice in a cup. You have to roll 5 Two's in two shakes and you
can "farm". i.e. Roll the first time, save any two's, pick up the remaining dice and roll
them.  What are the odds that five two's will be rolled this way? The bet is $2 and the pot is
currently over $2,800.00

Just curious. Thanks.

Background & Techniques

This was just the right size problem to provide a week's worth of entertainment figuring out how to solve and in  writing the code.  I ended up with 3 different approaches which all give the same answer, so there's some degree of confidence in the results.  Here's a summary:

Method 1:  A mathematical representation of the problem.  We'll assume two rolls; the first of all 5 dice and a second roll of those which did not show a "2" on the first.  I defined a a function P(M,N) to evaluate the probability that a roll of N dice with produce M "2"s.  More about defining P later. Since the two rolls are independent,  the probability of winning a game can be represented as the product of the two individual probabilities.   If we roll A twos on the first roll, the probability of winning that game is P(A,5) x P(5-A,5-A).   The total probability of winning is the sum of the probabilities for all possible A's (0 through 5).   The probability seemed surprisingly high to me, about 1 in 375 games. 

Method 2:  It took a night's worth of insomnia to come up a way to check the results from Method 1.  I reformulated the problem as a series of individual rolls.  A version of the game which should produce the same results as the original has us roll each die two times and score it as a success if either roll (or both rolls) for each die shows a two.  Using the definition of probability (successful outcomes divided by total possible outcomes), we have 36 possible outcomes ( [1,1] though [6,6]),  of which 11 are successful outcomes (6 outcomes for the first roll when the 2nd roll is a two plus 6 outcomes for 2nd roll when the 1st roll is a two minus the [2,2] outcome which would otherwise be counted twice).  So each die has a 11/36 or 0.30555 chance of success and the chance that all 5 dice scored a "2" is the product of the 5 individual probabilities = (0.30555) 5 = 0.002663.    This agrees with the result from Method 1.

Method 3: The implementation of Method 2 in the program is slightly different than described above.  Since P(M,N) returns the probability of M twos in N rolls, I used P(1,2) + P(2,2) as the probability that the two rolls of a die produces 1 or 2 twos.   Because I like simulations, I decided to simulate a million games at a time and see how the result compared .  The answer is "quite well" as you be able to see from the program (.0026x typically after 1 million games and .0266x after 30 to 50 million games).

The P(M,N) probability function:  The probability that exactly M twos occur when N dice are rolled depends on occurrence of M twos (each having a 1/6 probability) and N-M non-twos (each with a 5/6 probability).  The product of these two probabilities describes a particular arrangement of the outcomes, for example M twos followed by the (N-M) non-twos if the dice were numbered or a single die was rolled N times.  Specifically Q=(1/6)M x (5/6)(N-M).  This probability applies to all other arrangements as well which means that we must multiply Q by the number of ways that the M twos could be placed in the N locations.  That is the number of ways that M items can be selected from N things or the number of combinations for N things taken M at a time.  Mathematicians like to denote this as C(N,M). (Or more "standardly" as C(n,k) and read as "n choose k").    So our definition of P(M,N)  is P(M.N) =  (1/6)M x (5/6)(N-M) x C(N,M)

Non-programmers are welcome to read on, but may want to skip to the bottom of this page to download executable version of the program.

Notes for programmers

All of the code is fairly straightforward implementation of what is described above.  A TPageControl with Tabsheets is used to display the original problem and each of the result types.

The "Combination count" function required to calculate P(M,N) was initially implemented using our TComboset class from the UComboV2 unit in the DFF Library which is fast and reliable.  To eliminate the need to download the library file for first time users,  I wrote a simple C(N,M) function to compute the definition of combinations: C(N,M)=N!/((N-M)!*M!).   There is no error checking, but it works fine for small integers with valid inputs.

There were a few "tricks" used here that I'll mention in case you haven't run across them before:

bulletTo force a multi-page TMemo display back to line 1:
bulletWith Memo1 do begin selstart:=0; selLength:=0; end;
bulletTo display an integer field with thousands separators (i.e. commas) :
bulletformat('%d with commas ==> %.0n',[n,0.0+n]);
bulletUsing good grammar in output displays
bulletIf n=1 then w1:='time' else w1='times';
format('N occurs %d %s',[n.w1]);
bulletAdding lines at the end of a TStrings list using Append method: (This may just be a Delphi 5 bug, but the first line added with Add method to a TMemo with design time lines defined is inserted at line 0.  Append works OK.)
bulletmemo1.lines.append('New line');

The number of little problems like these may not be infinite, but I keep finding new ones to solve.  And each solution gives one just a pleasant little jolt of adrenaline!   

 Running/Exploring the Program 

bullet Download source
bullet Download  executable

Suggestions for Further Explorations



Original Date: January 6, 2008 

Modified: May 11, 2018


  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright 2000-2018, Gary Darby    All rights reserved.