Created
November 6, 2025 20:05
-
-
Save Stevie-O/6f73423ce1b425a7bbb61c951e7884d8 to your computer and use it in GitHub Desktop.
Boy born on Tuesday problem
This file contains hidden or 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
| void Main() | |
| { | |
| var r = new Random(); | |
| var boy_tue_counts = new Dictionary<InfoSource, Counter>() { | |
| { InfoSource.Ask, new Counter() }, | |
| { InfoSource.Volunteer, new Counter() }, | |
| }; | |
| var boy_counts = new Dictionary<InfoSource, Counter>() { | |
| { InfoSource.Ask, new Counter() }, | |
| { InfoSource.Volunteer, new Counter() }, | |
| }; | |
| const int TOTAL_TRIALS = 500_000_000; | |
| for (int i = 0; i < TOTAL_TRIALS; i++) | |
| { | |
| var kids = new[] { | |
| RandomChild(r), | |
| RandomChild(r), | |
| }; | |
| for (InfoSource src = InfoSource.Ask; src < InfoSource.Max; src++) | |
| { | |
| bool boy, boy_on_tuesday, other_is_girl; | |
| (boy_on_tuesday, other_is_girl) = IsOtherGirl(r, kids, src, k => k.gender == Gender.Boy && k.dayBorn == DayOfWeek.Tuesday); | |
| if (boy_on_tuesday) | |
| { | |
| boy_tue_counts[src].Sample(other_is_girl); | |
| } | |
| (boy, other_is_girl) = IsOtherGirl(r, kids, src, k => k.gender == Gender.Boy); | |
| if (boy) | |
| { | |
| boy_counts[src].Sample(other_is_girl); | |
| } | |
| } | |
| } | |
| var lst = boy_tue_counts.Select(kvp => new { Predicate = "Boy on Tuesday", Mode = kvp.Key, kvp.Value.Hits, kvp.Value.Samples, kvp.Value.Ratio }) | |
| .Concat( | |
| boy_counts.Select(kvp => new { Predicate = "Boy", Mode = kvp.Key, kvp.Value.Hits, kvp.Value.Samples, kvp.Value.Ratio }) | |
| ) | |
| .ToList() | |
| .Dump(); | |
| } | |
| (bool match, bool other_girl) IsOtherGirl(Random r, Child[] kids, InfoSource mode, Predicate<Child> a_priori) | |
| { | |
| int match_index; | |
| if (mode == InfoSource.Volunteer) | |
| { | |
| // pick a kid at random and volunteer whether or not they match the predicate | |
| match_index = r.Next(0, 1); | |
| var matched = a_priori(kids[match_index]); | |
| if (!matched) { return (false, false); } | |
| } | |
| else | |
| { | |
| // asked if any child matches the predicate | |
| if (a_priori(kids[0])) { match_index = 0; } | |
| else if (a_priori(kids[1])) { match_index = 1; } | |
| else { return (false, false); } | |
| } | |
| bool other_is_girl = (kids[match_index ^ 1].gender == Gender.Girl); | |
| return (true, other_is_girl); | |
| } | |
| class Counter | |
| { | |
| public int Samples; | |
| public int Hits; | |
| public double Ratio => (double)Hits / (double)Samples; | |
| public void Sample(bool isHit) | |
| { | |
| Samples++; | |
| if (isHit) Hits++; | |
| } | |
| } | |
| public enum InfoSource { Ask, Volunteer, Max } | |
| public enum Gender { Boy, Girl } | |
| public record struct Child(Gender gender, DayOfWeek dayBorn); | |
| static Gender RandomGender(Random r) | |
| { | |
| if (r.NextDouble() < 0.5) return Gender.Boy; | |
| else return Gender.Girl; | |
| } | |
| static Child RandomChild(Random r) | |
| { | |
| var gender = RandomGender(r); | |
| var dayOfWeek = (DayOfWeek)r.Next(0, 7); | |
| return new Child(gender, dayOfWeek); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment