Birthday problem: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 21: Line 21:
REAL desired probability := 0.5; # 50% #
REAL desired probability := 0.5; # 50% #


REAL upb year = 365 + 1/4 - 3/400,
REAL upb year = 365 + 1/4 # - 3/400 but alive, ignore >113yo #,
INT upb sample size = 10000,
INT upb sample size = 10000,
upb repeat = 5 ;
upb common = 5;


FORMAT name int fmt = $g": "g(-0)"; "$,
INT required repeat := 2;
name real fmt = $g": "g(-0,4)"; "$,

FORMAT var int fmt = $g": "g(-0)"; "$;
name percent fmt = $g": "g(-0,2)"%; "$;


printf((
printf((
var int fmt,
name real fmt,
"upb year",upb year,
"upb year",upb year,
name int fmt,
"upb repeat",upb repeat,
"upb common",upb common,
"upb sample size",upb sample size,
"upb sample size",upb sample size,
$l$
$l$
));
));


FOR group size FROM required repeat WHILE required repeat <= upb repeat DO
INT required common := 1; # initial value #
INT sample with no required repeat := 0;
FOR group size FROM required common WHILE required common <= upb common DO
INT sample with no required common := 0;
TO upb sample size DO
TO upb sample size DO
# generate sample #
# generate sample #
[group size]INT sample;
[group size]INT sample;
FOR i TO UPB sample DO sample[i] := ENTIER(random * 365) + 1 OD;
FOR i TO UPB sample DO sample[i] := ENTIER(random * upb year) + 1 OD;
FOR birthday i TO UPB sample DO
FOR birthday i TO UPB sample DO
INT birthday = sample[birthday i];
INT birthday = sample[birthday i];
INT number of celebrants := 1;
INT number in common := 1;
# special case = 1 #
IF number in common >= required common THEN
found required common
FI;
FOR birthday j FROM birthday i + 1 TO UPB sample DO
FOR birthday j FROM birthday i + 1 TO UPB sample DO
IF birthday = sample[birthday j] THEN
IF birthday = sample[birthday j] THEN
number of celebrants +:= 1;
number in common +:= 1;
IF number of celebrants = required repeat THEN
IF number in common >= required common THEN
found required repeat
found required common
FI
FI
FI
FI
OD
OD
OD # days in year #;
OD # days in year #;
sample with no required repeat +:= 1;
sample with no required common +:= 1;
found required repeat: SKIP
found required common: SKIP
OD # sample size #;
OD # sample size #;
REAL portion of years with required repeat birthdays =
REAL portion of years with required common birthdays =
(upb sample size - sample with no required repeat) / upb sample size;
(upb sample size - sample with no required common) / upb sample size;
print(".");
print(".");
IF portion of years with required repeat birthdays > desired probability THEN
IF portion of years with required common birthdays > desired probability THEN
printf((
printf((
$l$,
$l$,
var int fmt,
name int fmt,
"required repeat",required repeat,
"required common",required common,
"group size",group size,
"group size",group size,
# "sample with no required repeat",sample with no required repeat, #
# "sample with no required common",sample with no required common, #
$g": "g(-0,2)"%; "$,
name percent fmt,
"%age of years with required repeat birthdays",portion of years with required repeat birthdays*100,
"%age of years with required common birthdays",portion of years with required common birthdays*100,
$l$
$l$
));
));
required repeat +:= 1
required common +:= 1
FI
FI
OD # group size #</lang>'''Output:'''
OD # group size #</lang>'''Output:'''
<pre>
<pre>
upb year: 365; upb repeat: 5; upb sample size: 10000;
upb year: 365.2500; upb common: 2; upb sample size: 10000;
.
required common: 1; group size: 1; %age of years with required common birthdays: 100.00%;
......................
......................
required repeat: 2; group size: 23; %age of years with required repeat birthdays: 51.69%;
required common: 2; group size: 23; %age of years with required common birthdays: 50.09%;
................................................................
................................................................
required repeat: 3; group size: 87; %age of years with required repeat birthdays: 50.37%;
required repeat: 3; group size: 87; %age of years with required repeat birthdays: 50.37%;

Revision as of 07:00, 4 June 2013

This page uses content from Wikipedia. The current wikipedia article is at Birthday Problem. The original RosettaCode article was extracted from the wikipedia article № 296054030 of 21:44, 12 June 2009 . The list of authors can be seen in the page history. As with Rosetta Code, the pre 5 June 2009 text of Wikipedia is available under the GNU FDL. (See links for details on variance)

Birthday problem is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Birthday problem is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

In probability theory, the birthday problem, or birthday paradox This is not a paradox in the sense of leading to a logical contradiction, but is called a paradox because the mathematical truth contradicts naïve intuition: most people estimate that the chance is much lower than 50%. pertains to the probability that in a set of randomly chosen people some pair of them will have the same birthday. In a group of at least 23 randomly chosen people, there is more than 50% probability that some pair of them will both have been born on the same day. For 57 or more people, the probability is more than 99%, and it reaches 100% when the number of people reaches 366 (by the pigeon hole principle, ignoring leap years). The mathematics behind this problem leads to a well-known cryptographic attack called the birthday attack.

Task:

Using simulation, estimate the number of independent people required in a groups before we can expect a better then even chance that at least 2 independent people in a group share a common birthday. Furthermore: Simulate and thus estimate when we can expect a better then even chance that at least 3, 4 & 5 independent people of the group share a common birthday. For simplicity assume that all of the people are alive...

Kudos (κῦδος) for estimating the error in the estimate to help ensure the estimate is accurate to 4 decimal places.

See also:

ALGOL 68

Works with: ALGOL 68 version Revision 1
Works with: ALGOL 68G version Any - tested with release algol68g-2.6.

File: Birthday_problem.a68<lang algol68>#!/usr/bin/a68g --script #

  1. -*- coding: utf-8 -*- #

REAL desired probability := 0.5; # 50% #

REAL upb year = 365 + 1/4 # - 3/400 but alive, ignore >113yo #, INT upb sample size = 10000,

   upb common = 5;

FORMAT name int fmt = $g": "g(-0)"; "$,

      name real fmt = $g": "g(-0,4)"; "$,
      name percent fmt = $g": "g(-0,2)"%; "$;

printf((

 name real fmt,
 "upb year",upb year,
 name int fmt,
 "upb common",upb common,
 "upb sample size",upb sample size,
 $l$

));

INT required common := 1; # initial value # FOR group size FROM required common WHILE required common <= upb common DO

 INT sample with no required common := 0;
 TO upb sample size DO
 # generate sample #
   [group size]INT sample;
   FOR i TO UPB sample DO sample[i] := ENTIER(random * upb year) + 1 OD;
   FOR birthday i TO UPB sample DO
     INT birthday = sample[birthday i];
     INT number in common := 1;
   # special case = 1 #
     IF number in common >= required common THEN
       found required common
     FI;
     FOR birthday j FROM birthday i + 1 TO UPB sample DO
       IF birthday = sample[birthday j] THEN
         number in common +:= 1;
         IF number in common >= required common THEN
           found required common
         FI
       FI
     OD
   OD  # days in year #;
   sample with no required common +:= 1;
   found required common: SKIP
 OD # sample size #;
 REAL portion of years with required common birthdays = 
   (upb sample size - sample with no required common) / upb sample size;
 print(".");
 IF portion of years with required common birthdays > desired probability THEN
   printf((
     $l$,
     name int fmt,
     "required common",required common,
     "group size",group size,
     # "sample with no required common",sample with no required common, #
     name percent fmt,
     "%age of years with required common birthdays",portion of years with required common birthdays*100,
     $l$
   ));
   required common +:= 1
 FI

OD # group size #</lang>Output:

upb year: 365.2500; upb common: 2; upb sample size: 10000; 
.
required common: 1; group size: 1; %age of years with required common birthdays: 100.00%; 
......................
required common: 2; group size: 23; %age of years with required common birthdays: 50.09%; 
................................................................
required repeat: 3; group size: 87; %age of years with required repeat birthdays: 50.37%; 
...................................................................................................
required repeat: 4; group size: 186; %age of years with required repeat birthdays: 50.70%; 
...............................................................................................................................
required repeat: 5; group size: 313; %age of years with required repeat birthdays: 50.92%;