IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New And a better answer and algorithm improvements
The answer for 5 really is 313. The probability of not having any group of 5 with 313 people is 0.499972.

I'm including a program with a different algorithm that can answer that. It scales worse than the previous one for up to 3 people on the same birthday, but better for 4 or more after that. It takes leap years into account. It does not take into account the 3 missing leap days every 400 years, but there aren't many people around who are 104 (and even fewer who are 204) so I think that is a reasonable omission.

\n#! /usr/bin/ruby -w\n\n# With one argument, the product 1*2*..*n\n# With two arguments with m <= n, the product m*(m+1)*..*n\n# With two arguments with n < m, 1.\ndef factorial(n, m=1)\n  n = n.to_i;\n  m = m.to_i;\n  product = 1;\n  (m..n).each {|i| product *= i}\n  product\nend\n\n# Sums an array.\ndef sum(numbers)\n  ans = 0;\n  numbers.each{|i| ans += i}\n  ans\nend\n\n# The number of ways to find m things in n.\n@choose_cache = Hash.new\ndef choose(n, m)\n  key = "#{n} #{m}";\n  unless @choose_cache.has_key?(key)\n    if (m > n/2)\n      m = n - m;\n    end\n    @choose_cache[key] = factorial(n, n + 1 - m) / factorial(m);\n  end\n  return @choose_cache[key]\nend\n\n# Calculate the number of possible birthday assignments to some number of\n# people using some number of days with a given maximimum number of people\n# getting the same day.\n@birthday_assignments = Hash.new();\ndef possible_birthday_assignments(people, days, max_one_day)\n  if (people > days*max_one_day)\n    return 0;\n  elsif days < 2\n    return 1;\n  else \n    key = "#{people}|#{days}|#{max_one_day}";\n    ans = 0;\n    unless @birthday_assignments.has_key?(key)\n      if (days/2*2 == days)\n        # Divide the days in half\n        (0..people).each {|people_in_first|\n          ans += possible_birthday_assignments(\n              people_in_first,\n              days/2,\n              max_one_day\n            ) * possible_birthday_assignments(\n              people - people_in_first,\n              days/2,\n              max_one_day\n            ) * choose(people, people_in_first);\n        }\n      else\n        # Divide people in 1 day, people in the rest\n        limit = people < max_one_day ? people : max_one_day\n        (0..limit).each{ |people_in_first|\n          ans += possible_birthday_assignments(\n            people - people_in_first,\n            days - 1,\n            max_one_day\n          ) * choose(people, people_in_first)\n        }\n      end\n      @birthday_assignments[key] = ans;\n    end\n    return @birthday_assignments[key];\n  end\nend\n\ndef fraction_to_float(a, b)\n  precision = 100_000_000;\n  return ( (a * precision + a/2)/b ).to_f / precision;\nend\n\n# Calculate birthday probability but ignore leap day.\ndef basic_birthday_probability(people, max_one_day)\n  count = possible_birthday_assignments(people.to_i, 365, max_one_day.to_i)\n  return fraction_to_float(count, 365**(people.to_i));\nend\n\n# Calculate birthday probability and include leap day.\ndef birthday_probability(people, max_one_day)\n  people = people.to_i;\n  max_one_day = max_one_day.to_i;\n  limit = people < max_one_day ? people : max_one_day;\n  ans = 0;\n  (0..limit).each {|i|\n    ans += basic_birthday_probability(\n        people - i, max_one_day\n      ) * fraction_to_float(\n        choose(people, i) * (365*4)**(people-i),\n        (365*4 + 1)**people\n      );\n  }\n  return ans;\nend\n\nprob = birthday_probability(*ARGV);\nputs "Odds #{prob} that #{ARGV[0]} people have at most #{ARGV[1]} birthdays together";\n


Cheers,
Ben
To deny the indirect purchaser, who in this case is the ultimate purchaser, the right to seek relief from unlawful conduct, would essentially remove the word consumer from the Consumer Protection Act
- [link|http://www.techworld.com/opsys/news/index.cfm?NewsID=1246&Page=1&pagePos=20|Nebraska Supreme Court]
New It's nice to see there's at least one person in the world...
... with a more keenly-developed distaste for not-quite-rightness than me.
===

Implicitly condoning stupidity since 2001.
     Happy birthday deSitter! - (a6l6e6x) - (23)
         WOW. - (mmoffitt) - (16)
             Geez - had I known - (imric) - (1)
                 Re: Geez - had I known - (deSitter)
             Re: applied math guy - (a6l6e6x) - (3)
                 But we have 2 pairs. - (mmoffitt) - (2)
                     2 pairs are at least one pair! :) -NT - (a6l6e6x)
                     I'm not about to do a "odds of n people the same" program - (ben_tilly)
             Here's a program which SHOULD be correct - (ben_tilly) - (9)
                 Neato. I'll have to find Ruby for Win32. Thanks. - (Another Scott) - (2)
                     Cygwin is your friend - (jb4) - (1)
                         I've got Cygwin. I'll track down Ruby. Thanks, jb. -NT - (Another Scott)
                 And with minor optimizations - (ben_tilly)
                 "If I'm still interested in the morning ... " - (drewk) - (4)
                     I knew he couldn't resist ;-) -NT - (mmoffitt)
                     Well, it is not so technically morning now... - (ben_tilly) - (2)
                         And a better answer and algorithm improvements - (ben_tilly) - (1)
                             It's nice to see there's at least one person in the world... - (drewk)
         Re: Happy birthday deSitter! - (Nightowl)
         Why.. it's.. almost a Leo-nid Shower___Congrats all - - (Ashton)
         hey, happy belated... -NT - (cforde)
         Best wishes. - (Silverlock)
         Happy belated! -NT - (inthane-chan)
         ObAOLMeThree! -NT - (CRConrad)

There are perhaps no more tragic creatures than middle-aged, middle-class tourists, unused to traveling in unfamiliar places, on a lifetime dream vacation.
99 ms