From a99887954590dddced0c6110f360e11040c7a641 Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:28:19 +0100 Subject: [PATCH 1/5] Fixes to concept tree --- misc/concept_tree.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/concept_tree.md b/misc/concept_tree.md index b89d34b2..ff207ae8 100644 --- a/misc/concept_tree.md +++ b/misc/concept_tree.md @@ -1,7 +1,7 @@ # Concept Tree This is a concept tree for the Crystal Syllabus. -It is a work in progress, it was last updated on 2024-01-13. +It is a work in progress, it was last updated on 2024-12-06. Each concept with an exercise around it has been implemented, the rest is still to be implemented. @@ -16,7 +16,7 @@ graph TD b(bools) end - subgraph J [Number Types] + subgraph J [Navigation Computer] ac(Number Types) end @@ -48,7 +48,7 @@ graph TD h(conditionals) end - subgraph I [Interest is intresting] + subgraph I [Interest is interesting] i(return) j(while) end From 89ffdb7d1e9a36f21df3baccc6d5e19a31e3b185 Mon Sep 17 00:00:00 2001 From: meatball Date: Fri, 2 Jan 2026 19:19:47 +0100 Subject: [PATCH 2/5] Add Baffling Birthdays exercise with instructions, example, and tests --- config.json | 8 ++ .../baffling-birthdays/.docs/instructions.md | 23 +++++ .../baffling-birthdays/.docs/introduction.md | 25 +++++ .../baffling-birthdays/.meta/config.json | 19 ++++ .../baffling-birthdays/.meta/src/example.cr | 29 ++++++ .../.meta/test_template.ecr | 31 ++++++ .../baffling-birthdays/.meta/tests.toml | 61 ++++++++++++ .../spec/baffling_birthdays_spec.cr | 96 +++++++++++++++++++ .../src/baffling_birthdays.cr | 12 +++ 9 files changed, 304 insertions(+) create mode 100644 exercises/practice/baffling-birthdays/.docs/instructions.md create mode 100644 exercises/practice/baffling-birthdays/.docs/introduction.md create mode 100644 exercises/practice/baffling-birthdays/.meta/config.json create mode 100644 exercises/practice/baffling-birthdays/.meta/src/example.cr create mode 100644 exercises/practice/baffling-birthdays/.meta/test_template.ecr create mode 100644 exercises/practice/baffling-birthdays/.meta/tests.toml create mode 100644 exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr create mode 100644 exercises/practice/baffling-birthdays/src/baffling_birthdays.cr diff --git a/config.json b/config.json index 4a708598..0d736d20 100644 --- a/config.json +++ b/config.json @@ -1036,6 +1036,14 @@ "prerequisites": [], "difficulty": 3 }, + { + "slug": "baffling-birthdays", + "name": "Baffling Birthdays", + "uuid": "232e58b6-06ca-4401-b4ba-2e16e59902c3", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, { "slug": "food-chain", "name": "Food Chain", diff --git a/exercises/practice/baffling-birthdays/.docs/instructions.md b/exercises/practice/baffling-birthdays/.docs/instructions.md new file mode 100644 index 00000000..a01ec867 --- /dev/null +++ b/exercises/practice/baffling-birthdays/.docs/instructions.md @@ -0,0 +1,23 @@ +# Instructions + +Your task is to estimate the birthday paradox's probabilities. + +To do this, you need to: + +- Generate random birthdates. +- Check if a collection of randomly generated birthdates contains at least two with the same birthday. +- Estimate the probability that at least two people in a group share the same birthday for different group sizes. + +~~~~exercism/note +A birthdate includes the full date of birth (year, month, and day), whereas a birthday refers only to the month and day, which repeat each year. +Two birthdates with the same month and day correspond to the same birthday. +~~~~ + +~~~~exercism/caution +The birthday paradox assumes that: + +- There are 365 possible birthdays (no leap years). +- Each birthday is equally likely (uniform distribution). + +Your implementation must follow these assumptions. +~~~~ diff --git a/exercises/practice/baffling-birthdays/.docs/introduction.md b/exercises/practice/baffling-birthdays/.docs/introduction.md new file mode 100644 index 00000000..97dabd1e --- /dev/null +++ b/exercises/practice/baffling-birthdays/.docs/introduction.md @@ -0,0 +1,25 @@ +# Introduction + +Fresh out of college, you're throwing a huge party to celebrate with friends and family. +Over 70 people have shown up, including your mildly eccentric Uncle Ted. + +In one of his usual antics, he bets you £100 that at least two people in the room share the same birthday. +That sounds ridiculous — there are many more possible birthdays than there are guests, so you confidently accept. + +To your astonishment, after collecting the birthdays of just 32 guests, you've already found two guests that share the same birthday. +Accepting your loss, you hand Uncle Ted his £100, but something feels off. + +The next day, curiosity gets the better of you. +A quick web search leads you to the [birthday paradox][birthday-problem], which reveals that with just 23 people, the probability of a shared birthday exceeds 50%. + +Ah. So _that's_ why Uncle Ted was so confident. + +Determined to turn the tables, you start looking up other paradoxes; next time, _you'll_ be the one making the bets. + +~~~~exercism/note +The birthday paradox is a [veridical paradox][veridical-paradox]: even though it feels wrong, it is actually true. + +[veridical-paradox]: https://en.wikipedia.org/wiki/Paradox#Quine's_classification +~~~~ + +[birthday-problem]: https://en.wikipedia.org/wiki/Birthday_problem diff --git a/exercises/practice/baffling-birthdays/.meta/config.json b/exercises/practice/baffling-birthdays/.meta/config.json new file mode 100644 index 00000000..f8be9d4e --- /dev/null +++ b/exercises/practice/baffling-birthdays/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "meatball133" + ], + "files": { + "solution": [ + "src/baffling_birthdays.cr" + ], + "test": [ + "spec/baffling_birthdays_spec.cr" + ], + "example": [ + ".meta/src/example.cr" + ] + }, + "blurb": "Estimate the birthday paradox's probabilities.", + "source": "Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/pull/2539" +} diff --git a/exercises/practice/baffling-birthdays/.meta/src/example.cr b/exercises/practice/baffling-birthdays/.meta/src/example.cr new file mode 100644 index 00000000..a7bceb6d --- /dev/null +++ b/exercises/practice/baffling-birthdays/.meta/src/example.cr @@ -0,0 +1,29 @@ +class BafflingBirthdays + def self.shared_birthday(birthdates : Array(Time)) : Bool + birthdates.each_with_index do |date, idx| + birthdates.each_with_index do |date_2, idx_2| + if idx == idx_2 + next + end + if date.month == date_2.month && date.day == date_2.day + return true + end + end + end + return false + end + + def self.random_birthdates(size : Int) : Array(Time) + result = [] of Time + size.times do |_| + time = Time.utc(2025, 1, 1).shift days: Random.rand(356) + result << time + end + + return result + end + + def self.estimated_probability_of_shared_birthday(size : Int) : Float + return (1..10000).sum {|_| shared_birthday(random_birthdates(size)) ? 1 : 0} / 100.0 + end +end diff --git a/exercises/practice/baffling-birthdays/.meta/test_template.ecr b/exercises/practice/baffling-birthdays/.meta/test_template.ecr new file mode 100644 index 00000000..59612a17 --- /dev/null +++ b/exercises/practice/baffling-birthdays/.meta/test_template.ecr @@ -0,0 +1,31 @@ +require "spec" +require "../src/*" + +describe "<%-= to_capitalized(@json["exercise"].to_s) %>" do +<%- @json["cases"].as_a.each do |cases| %> + <%- cases["cases"].as_a.each do |sub_case| %> + <%= status()%> "<%-= sub_case["description"] %>" do + <%- if sub_case["property"] == "sharedBirthday" -%> + birthdays = [<%= sub_case["input"]["birthdates"].as_a.map {|date| "Time.parse_utc(\"#{date}\", \"%Y-%m-%d\")" }.join(", ") %>] + <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(birthdays).should be_<%= sub_case["expected"] %> + <%- elsif sub_case["property"] == "estimatedProbabilityOfSharedBirthday" -%> + <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(<%= sub_case["input"]["groupSize"] %>).should be_close <%= (sub_case["expected"]) %>, <%= sub_case["input"]["groupSize"].as_i == 23 ? 1.5 : sub_case["input"]["groupSize"].as_i == 1 ? 0.01 : 1 %> + <%- elsif sub_case["expected"] == "length == groupsize" -%> + (1..10).each do |size| + result = <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(size) + result.size.should eq(size) + end + <%- elsif (sub_case["expected"]["years"]? || {} of String => Bool)["leapYear"]? -%> + result = <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(50) + result.all? { |date| Time.leap_year?(date.year) }.should be_false + <%- elsif (sub_case["expected"]["months"]? || {} of String => Bool)["random"]? -%> + result = <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(100) + result.to_set { |date| date.month }.size.should eq(12) + <%- elsif (sub_case["expected"]["days"]? || {} of String => Bool)["random"]? -%> + result = <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(300) + result.to_set { |date| date.day }.size.should eq(31) + <% end %> + end + <% end %> +<% end %> +end diff --git a/exercises/practice/baffling-birthdays/.meta/tests.toml b/exercises/practice/baffling-birthdays/.meta/tests.toml new file mode 100644 index 00000000..c76afb46 --- /dev/null +++ b/exercises/practice/baffling-birthdays/.meta/tests.toml @@ -0,0 +1,61 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[716dcc2b-8fe4-4fc9-8c48-cbe70d8e6b67] +description = "shared birthday -> one birthdate" + +[f7b3eb26-bcfc-4c1e-a2de-af07afc33f45] +description = "shared birthday -> two birthdates with same year, month, and day" + +[7193409a-6e16-4bcb-b4cc-9ffe55f79b25] +description = "shared birthday -> two birthdates with same year and month, but different day" + +[d04db648-121b-4b72-93e8-d7d2dced4495] +description = "shared birthday -> two birthdates with same month and day, but different year" + +[3c8bd0f0-14c6-4d4c-975a-4c636bfdc233] +description = "shared birthday -> two birthdates with same year, but different month and day" + +[df5daba6-0879-4480-883c-e855c99cdaa3] +description = "shared birthday -> two birthdates with different year, month, and day" + +[0c17b220-cbb9-4bd7-872f-373044c7b406] +description = "shared birthday -> multiple birthdates without shared birthday" + +[966d6b0b-5c0a-4b8c-bc2d-64939ada49f8] +description = "shared birthday -> multiple birthdates with one shared birthday" + +[b7937d28-403b-4500-acce-4d9fe3a9620d] +description = "shared birthday -> multiple birthdates with more than one shared birthday" + +[70b38cea-d234-4697-b146-7d130cd4ee12] +description = "random birthdates -> generate requested number of birthdates" + +[d9d5b7d3-5fea-4752-b9c1-3fcd176d1b03] +description = "random birthdates -> years are not leap years" + +[d1074327-f68c-4c8a-b0ff-e3730d0f0521] +description = "random birthdates -> months are random" + +[7df706b3-c3f5-471d-9563-23a4d0577940] +description = "random birthdates -> days are random" + +[89a462a4-4265-4912-9506-fb027913f221] +description = "estimated probability of at least one shared birthday -> for one person" + +[ec31c787-0ebb-4548-970c-5dcb4eadfb5f] +description = "estimated probability of at least one shared birthday -> among ten people" + +[b548afac-a451-46a3-9bb0-cb1f60c48e2f] +description = "estimated probability of at least one shared birthday -> among twenty-three people" + +[e43e6b9d-d77b-4f6c-a960-0fc0129a0bc5] +description = "estimated probability of at least one shared birthday -> among seventy people" diff --git a/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr b/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr new file mode 100644 index 00000000..45ffc50f --- /dev/null +++ b/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr @@ -0,0 +1,96 @@ +require "spec" +require "../src/*" + +describe "BafflingBirthdays" do + it "one birthdate" do + birthdays = [Time.parse_utc("2000-01-01", "%Y-%m-%d")] + BafflingBirthdays.shared_birthday(birthdays).should be_false + end + + pending "two birthdates with same year, month, and day" do + birthdays = [Time.parse_utc("2000-01-01", "%Y-%m-%d"), Time.parse_utc("2000-01-01", "%Y-%m-%d")] + BafflingBirthdays.shared_birthday(birthdays).should be_true + end + + pending "two birthdates with same year and month, but different day" do + birthdays = [Time.parse_utc("2012-05-09", "%Y-%m-%d"), Time.parse_utc("2012-05-17", "%Y-%m-%d")] + BafflingBirthdays.shared_birthday(birthdays).should be_false + end + + pending "two birthdates with same month and day, but different year" do + birthdays = [Time.parse_utc("1999-10-23", "%Y-%m-%d"), Time.parse_utc("1988-10-23", "%Y-%m-%d")] + BafflingBirthdays.shared_birthday(birthdays).should be_true + end + + pending "two birthdates with same year, but different month and day" do + birthdays = [Time.parse_utc("2007-12-19", "%Y-%m-%d"), Time.parse_utc("2007-04-27", "%Y-%m-%d")] + BafflingBirthdays.shared_birthday(birthdays).should be_false + end + + pending "two birthdates with different year, month, and day" do + birthdays = [Time.parse_utc("1997-08-04", "%Y-%m-%d"), Time.parse_utc("1963-11-23", "%Y-%m-%d")] + BafflingBirthdays.shared_birthday(birthdays).should be_false + end + + pending "multiple birthdates without shared birthday" do + birthdays = [ + Time.parse_utc("1966-07-29", "%Y-%m-%d"), Time.parse_utc("1977-02-12", "%Y-%m-%d"), Time.parse_utc("2001-12-25", "%Y-%m-%d"), + Time.parse_utc("1980-11-10", "%Y-%m-%d"), + ] + BafflingBirthdays.shared_birthday(birthdays).should be_false + end + + pending "multiple birthdates with one shared birthday" do + birthdays = [ + Time.parse_utc("1966-07-29", "%Y-%m-%d"), Time.parse_utc("1977-02-12", "%Y-%m-%d"), Time.parse_utc("2001-07-29", "%Y-%m-%d"), + Time.parse_utc("1980-11-10", "%Y-%m-%d"), + ] + BafflingBirthdays.shared_birthday(birthdays).should be_true + end + + pending "multiple birthdates with more than one shared birthday" do + birthdays = [ + Time.parse_utc("1966-07-29", "%Y-%m-%d"), Time.parse_utc("1977-02-12", "%Y-%m-%d"), Time.parse_utc("2001-12-25", "%Y-%m-%d"), + Time.parse_utc("1980-07-29", "%Y-%m-%d"), Time.parse_utc("2019-02-12", "%Y-%m-%d"), + ] + BafflingBirthdays.shared_birthday(birthdays).should be_true + end + + pending "generate requested number of birthdates" do + (1..10).each do |size| + result = BafflingBirthdays.random_birthdates(size) + result.size.should eq(size) + end + end + + pending "years are not leap years" do + result = BafflingBirthdays.random_birthdates(50) + result.all? { |date| Time.leap_year?(date.year) }.should be_false + end + + pending "months are random" do + result = BafflingBirthdays.random_birthdates(100) + result.to_set { |date| date.month }.size.should eq(12) + end + + pending "days are random" do + result = BafflingBirthdays.random_birthdates(300) + result.to_set { |date| date.day }.size.should eq(31) + end + + pending "for one person" do + BafflingBirthdays.estimated_probability_of_shared_birthday(1).should be_close 0.0, 0.01 + end + + pending "among ten people" do + BafflingBirthdays.estimated_probability_of_shared_birthday(10).should be_close 11.694818, 1 + end + + pending "among twenty-three people" do + BafflingBirthdays.estimated_probability_of_shared_birthday(23).should be_close 50.729723, 1.5 + end + + pending "among seventy people" do + BafflingBirthdays.estimated_probability_of_shared_birthday(70).should be_close 99.915958, 1 + end +end diff --git a/exercises/practice/baffling-birthdays/src/baffling_birthdays.cr b/exercises/practice/baffling-birthdays/src/baffling_birthdays.cr new file mode 100644 index 00000000..cec8ad6c --- /dev/null +++ b/exercises/practice/baffling-birthdays/src/baffling_birthdays.cr @@ -0,0 +1,12 @@ +class BafflingBirthdays + # Write your code for the 'BafflingBirthdays' exercise in this file. + + def self.shared_birthday(birthdates : Array(Time)) : Bool + end + + def self.random_birthdates(size : Int) : Array(Time) + end + + def self.estimated_probability_of_shared_birthday(size : Int) : Float + end +end From 6d949ffd0f2af9b23f8ef3281e7978e2fdb114a7 Mon Sep 17 00:00:00 2001 From: meatball Date: Fri, 2 Jan 2026 19:22:01 +0100 Subject: [PATCH 3/5] Format files --- exercises/practice/baffling-birthdays/.meta/src/example.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/baffling-birthdays/.meta/src/example.cr b/exercises/practice/baffling-birthdays/.meta/src/example.cr index a7bceb6d..4c75decc 100644 --- a/exercises/practice/baffling-birthdays/.meta/src/example.cr +++ b/exercises/practice/baffling-birthdays/.meta/src/example.cr @@ -24,6 +24,6 @@ class BafflingBirthdays end def self.estimated_probability_of_shared_birthday(size : Int) : Float - return (1..10000).sum {|_| shared_birthday(random_birthdates(size)) ? 1 : 0} / 100.0 + return (1..10000).sum { |_| shared_birthday(random_birthdates(size)) ? 1 : 0 } / 100.0 end end From f77c54f7fea2dce4004543a415627d5bbf9945bd Mon Sep 17 00:00:00 2001 From: meatball Date: Fri, 2 Jan 2026 19:52:10 +0100 Subject: [PATCH 4/5] Fix when suppose to generate for 23 people --- exercises/practice/baffling-birthdays/.meta/src/example.cr | 2 +- exercises/practice/baffling-birthdays/.meta/test_template.ecr | 2 +- .../baffling-birthdays/spec/baffling_birthdays_spec.cr | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/practice/baffling-birthdays/.meta/src/example.cr b/exercises/practice/baffling-birthdays/.meta/src/example.cr index 4c75decc..629ea271 100644 --- a/exercises/practice/baffling-birthdays/.meta/src/example.cr +++ b/exercises/practice/baffling-birthdays/.meta/src/example.cr @@ -16,7 +16,7 @@ class BafflingBirthdays def self.random_birthdates(size : Int) : Array(Time) result = [] of Time size.times do |_| - time = Time.utc(2025, 1, 1).shift days: Random.rand(356) + time = Time.utc(2025, 1, 1).shift days: Random.rand(364) result << time end diff --git a/exercises/practice/baffling-birthdays/.meta/test_template.ecr b/exercises/practice/baffling-birthdays/.meta/test_template.ecr index 59612a17..84f3d62e 100644 --- a/exercises/practice/baffling-birthdays/.meta/test_template.ecr +++ b/exercises/practice/baffling-birthdays/.meta/test_template.ecr @@ -9,7 +9,7 @@ describe "<%-= to_capitalized(@json["exercise"].to_s) %>" do birthdays = [<%= sub_case["input"]["birthdates"].as_a.map {|date| "Time.parse_utc(\"#{date}\", \"%Y-%m-%d\")" }.join(", ") %>] <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(birthdays).should be_<%= sub_case["expected"] %> <%- elsif sub_case["property"] == "estimatedProbabilityOfSharedBirthday" -%> - <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(<%= sub_case["input"]["groupSize"] %>).should be_close <%= (sub_case["expected"]) %>, <%= sub_case["input"]["groupSize"].as_i == 23 ? 1.5 : sub_case["input"]["groupSize"].as_i == 1 ? 0.01 : 1 %> + <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(<%= sub_case["input"]["groupSize"] %>).should be_close <%= (sub_case["expected"]) %>, <%= sub_case["input"]["groupSize"].as_i == 1 ? 0.01 : 1 %> <%- elsif sub_case["expected"] == "length == groupsize" -%> (1..10).each do |size| result = <%= to_capitalized(@json["exercise"].to_s) %>.<%= sub_case["property"].to_s.underscore %>(size) diff --git a/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr b/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr index 45ffc50f..ae858cf0 100644 --- a/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr +++ b/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr @@ -86,8 +86,8 @@ describe "BafflingBirthdays" do BafflingBirthdays.estimated_probability_of_shared_birthday(10).should be_close 11.694818, 1 end - pending "among twenty-three people" do - BafflingBirthdays.estimated_probability_of_shared_birthday(23).should be_close 50.729723, 1.5 + it "among twenty-three people" do + BafflingBirthdays.estimated_probability_of_shared_birthday(23).should be_close 50.729723, 1 end pending "among seventy people" do From dff34d2bb73c9b58bfd4c3c9e2dee878e928f745 Mon Sep 17 00:00:00 2001 From: meatball Date: Fri, 2 Jan 2026 19:57:03 +0100 Subject: [PATCH 5/5] 2nd attempt --- exercises/practice/baffling-birthdays/.meta/src/example.cr | 2 +- .../practice/baffling-birthdays/spec/baffling_birthdays_spec.cr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/practice/baffling-birthdays/.meta/src/example.cr b/exercises/practice/baffling-birthdays/.meta/src/example.cr index 629ea271..f8dd98f8 100644 --- a/exercises/practice/baffling-birthdays/.meta/src/example.cr +++ b/exercises/practice/baffling-birthdays/.meta/src/example.cr @@ -16,7 +16,7 @@ class BafflingBirthdays def self.random_birthdates(size : Int) : Array(Time) result = [] of Time size.times do |_| - time = Time.utc(2025, 1, 1).shift days: Random.rand(364) + time = Time.utc(2025, 1, 1).shift days: Random.rand(365) result << time end diff --git a/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr b/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr index ae858cf0..64b57264 100644 --- a/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr +++ b/exercises/practice/baffling-birthdays/spec/baffling_birthdays_spec.cr @@ -86,7 +86,7 @@ describe "BafflingBirthdays" do BafflingBirthdays.estimated_probability_of_shared_birthday(10).should be_close 11.694818, 1 end - it "among twenty-three people" do + pending "among twenty-three people" do BafflingBirthdays.estimated_probability_of_shared_birthday(23).should be_close 50.729723, 1 end