Birthday problem: Difference between revisions

Content added Content deleted
m (added whitespace to the task's preamble, added text description to the (;See also) link.)
m (→‎version 1: added/changed comments and whitespace, used a template for the output section. optimized parts of the code.)
Line 1,265: Line 1,265:
=={{header|REXX}}==
=={{header|REXX}}==
===version 1===
===version 1===
The method used is to find the average number of people to share a common birthday,   and then use the '''floor''' of
The method used is to find the average number of people to share a birthday,   and then use the   '''floor'''   of that
<br>that value &nbsp; (less the group size) &nbsp; as a starting point to find a new group size with an expected size that exceeds
<br>value &nbsp; (less the group size) &nbsp; as a starting point to find a new group size with an expected size that exceeds
<br>50% common birthdays of the required size.
<br>50% &nbsp; duplicate birthdays of the required size.
<lang rexx>/*REXX program examines the birthday problem via random number simulation. */
<lang rexx>/*REXX pgm examines the birthday problem via random # simulation (with specifable parms)*/
parse arg grps samp seed . /*get optional arguments from the CL. */
parse arg dups samp seed . /*get optional arguments from the CL. */
if grps=='' | grps==',' then grps=5 /*Not specified? Then use the default.*/
if dups=='' | dups=="," then dups= 10 /*Not specified? Then use the default.*/
if samp=='' | samp==',' then samp=100000 /* " " " " " " */
if samp=='' | samp=="," then samp= 10000 /* " " " " " " */
if datatype(seed,'W') then call random ,,seed /*RANDOM seed given for repeatability ?*/
if datatype(seed, 'W') then call random ,,seed /*RANDOM seed given for repeatability ?*/
diy =365 /*or: diy=365.25*/ /*the number of Days In a Year. */
diy =365 /*or: diy=365.25 */ /*the number of Days In a Year. */
diyM=diy*100 /*this expands the RANDOM (BIF) range.*/
diyM=diy*100 /*this expands the RANDOM (BIF) range.*/
/* [↓] get a rough estimate for %. */
do g=2 to dups; s=0 /*perform through 2 ──► duplicate size*/
do g=2 to grps; s=0 /*perform through 2 ──► group size. */
do samp; @.=0 /*perform some number of trials. */
do samp; @.=0 /*perform some number of trials. */
do j=0 until @.day==g /*perform until G dup. birthdays found.*/
do j=1 until @.day==g /*perform until G dup. birthdays found.*/
day=random(1, diyM) % 100 /*expand range RANDOM number generation*/
day=random(1,diyM) % 100 /*expand range RANDOM number generation*/
@.day=@.day + 1 /*record the number of common birthdays*/
@.day=@.day+1 /*record the number of common birthdays*/
end /*j*/ /* [↓] adjust for the DO loop index.*/
end /*j*/ /* [↓] adjust for the DO loop index.*/
s=s + j /*add number of birthday hits to sum. */
s=s+j-1 /*add number of birthday hits to sum. */
end /*samp*/ /* [↓] % 1 rounds down the division.*/
end /*samp*/
start.g= s/samp % 1 - g /*define where the try─outs start. */
end /*g*/ /* [] get a rough estimate for %. */

say right('sample size is ' samp, 40); say /*display this run's sample size. */
start.g=s/samp%1-g /*define where the try-outs start. */
end /*g*/
say ' required trial % with required'
say ' duplicates size common birthdays'
say
say ' ──────────── ─────── ──────────────────'
say right('sample size is ' samp,40); say /*display this run's sample size. */
say ' required group % with required'
do g=2 to dups /*perform through 2 ──► duplicate size*/
say ' common size common birthdays'
do try=start.g until s/samp>=.5; s=0 /* " try─outs until average 50%.*/
say ' ──────── ───── ────────────────'
do samp; @.=0 /* " some number of trials. */
/* [↓] where the try-outs happen. */
do try; day=random(1, diyM) % 100 /* " until G dup. birthdays found.*/
do g=2 to grps /*perform through 2 ──► group size. */
@.day=@.day + 1 /*record the number of common birthdays*/
do try=start.g; s=0 /*perform try-outs until average > 50%.*/
if @.day==g then do; s=s+1; leave; end /*found enough G (birthday) hits ? */
end /*try;*/
do samp; @.=0 /*perform some number of trials. */
end /*samp*/
do try /*perform until G dup. birthdays found.*/
day=random(1,diyM) % 100 /*expand range RANDOM number generation*/
end /*try=start.g*/ /* [↑] where the try─outs happen. */
say right(g, 15) right(try, 15) center( format( s / samp * 100, , 4)'%', 30)
@.day=@.day+1 /*record the number of common birthdays*/
if @.day\==g then iterate /*not enough G (birthday) hits found ? */
end /*g*/ /*stick a fork in it, we're all done. */</lang>
{{out|output|text= &nbsp; when using the default inputs:}}
s=s+1 /*another common birthday found. */
leave /* ··· and stop looking for more. */
end /*try;*/ /* [] bump the counter for Bday hits.*/
end /*samp*/
if s/samp>.5 then leave /*if the average is > 50%, then stop. */
end /*try=start.g*/

say right(g, 15) right(try, 15) center( format(s/samp*100,,5)'%', 30)
end /*g*/ /*stick a fork in it, we're all done. */</lang>
'''output''' &nbsp; when using the input of: &nbsp; <tt> 10 </tt>
<pre>
<pre>
sample size is 100000
sample size is 10000


required group % with required
required trial % with required
common size common birthdays
duplicates size common birthdays
──────────── ─────── ──────────────────
──────── ───── ────────────────
2 23 50.70900%
2 23 50.2300%
3 88 51.23200%
3 87 50.2400%
4 187 50.15100%
4 187 50.3800%
5 314 50.77800%
5 312 50.0100%
6 460 50.00600%
6 458 50.5200%
7 623 50.64800%
7 622 50.3900%
8 798 50.00700%
8 798 50.1700%
9 985 50.13400%
9 984 50.5700%
10 1181 50.22200%
10 1182 51.4000%
</pre>
</pre>