On Sep 28, 8:21 am, Ruby Quiz <ja... / grayproductions.net> wrote: > The three rules of RubyQuiz: > > 1. Please do not post any solutions or spoiler discussion for thisquizuntil > 48 hours have passed from the time on this message. > > 2. Support RubyQuizby submitting ideas as often as you can: > > http://www.rubyquiz.com/ > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone > on Ruby Talk follow the discussion. Please reply to the originalquizmessage, > if you can. > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= > > by Kenneth Kin Lum > > You just did some probability calculations, and don't know if the answers are > correct. So you write a program to verify the results. If you have eight dice, > and throw them all at once, what is the probability that there are AT LEAST > three fives? Try to write a program that find out the "number of desirable > outcomes" / "number of possible outcomes" by iterating through all the possible > outcomes of the dice throw. > > It has a verbose mode to see that the program is running correctly (for the case > 2 dice, at least 1 five): > > C:\rails\depot>ruby dice.rb -v 2 1 > 1 [1,1] > 2 [2,1] > 3 [3,1] > 4 [4,1] > 5 [5,1] <== > 6 [6,1] > 7 [1,2] > 8 [2,2] > 9 [3,2] > 10 [4,2] > 11 [5,2] <== > 12 [6,2] > 13 [1,3] > 14 [2,3] > 15 [3,3] > 16 [4,3] > 17 [5,3] <== > 18 [6,3] > 19 [1,4] > 20 [2,4] > 21 [3,4] > 22 [4,4] > 23 [5,4] <== > 24 [6,4] > 25 [1,5] <== > 26 [2,5] <== > 27 [3,5] <== > 28 [4,5] <== > 29 [5,5] <== > 30 [6,5] <== > 31 [1,6] > 32 [2,6] > 33 [3,6] > 34 [4,6] > 35 [5,6] <== > 36 [6,6] > > Number of desirable outcomes is 11 > Number of possible outcomes is 36 > > Probability is 0.3055555555555556 > > C:\rails\depot>ruby dice.rb 8 3 > > Number of desirable outcomes is 226491 > Number of possible outcomes is 1679616 > > Probability is 0.1348468935756745 > > It also has a "sample mode" to print out the samples every 50,000 times in the > loop: > > C:\rails\depot>ruby dice.rb -s 8 3 > 1 [1,1,1,1,1,1,1,1] > 50001 [3,6,3,4,3,1,2,1] > 100001 [5,5,6,1,6,1,3,1] > 150001 [1,5,3,5,2,2,4,1] > 200001 [3,4,6,2,5,2,5,1] > 250001 [5,3,3,6,1,3,6,1] > 300001 [1,3,6,3,4,3,1,2] > 350001 [3,2,3,1,1,4,2,2] > 400001 [5,1,6,4,3,4,3,2] > 450001 [1,1,3,2,6,4,4,2] > 500001 [3,6,5,5,2,5,5,2] <== > 550001 [5,5,2,3,5,5,6,2] <== > 600001 [1,5,5,6,1,6,1,3] > 650001 [3,4,2,4,4,6,2,3] > 700001 [5,3,5,1,1,1,4,3] > 750001 [1,3,2,5,3,1,5,3] > 800001 [3,2,5,2,6,1,6,3] > 850001 [5,1,2,6,2,2,1,4] > 900001 [1,1,5,3,5,2,2,4] > 950001 [3,6,1,1,2,3,3,4] > 1000001 [5,5,4,4,4,3,4,4] > 1050001 [1,5,1,2,1,4,5,4] > 1100001 [3,4,4,5,3,4,6,4] > 1150001 [5,3,1,3,6,4,1,5] > 1200001 [1,3,4,6,2,5,2,5] > 1250001 [3,2,1,4,5,5,3,5] <== > 1300001 [5,1,4,1,2,6,4,5] > 1350001 [1,1,1,5,4,6,5,5] <== > 1400001 [3,6,3,2,1,1,1,6] > 1450001 [5,5,6,5,3,1,2,6] <== > 1500001 [1,5,3,3,6,1,3,6] > 1550001 [3,4,6,6,2,2,4,6] > 1600001 [5,3,3,4,5,2,5,6] <== > 1650001 [1,3,6,1,2,3,6,6] > > Number of desirable outcomes is 226491 > Number of possible outcomes is 1679616 > > Probability is 0.1348468935756745 My thrown-together solution: #!/usr/bin/env ruby require 'optparse' verbose = false check = false dice = 1 wanted = 1 SIDES = 6 CHECK_FREQUENCY = 50000 OptionParser.new do |opts| opts.on('-d', '--dice [DICE]', Integer, 'The number of dice to roll') do |dice_opt| dice = dice_opt.to_i end opts.on('-w', '--wanted [WANTED]', Integer, 'The number of 5s to check for') do |wanted_opt| wanted = wanted_opt.to_i end opts.on('-c', '--check', 'Turn on check mode') do |check_opt| check = check_opt verbose = false end opts.on('-v', '--verbose', 'Turn on verbose mode') do |verbose_opt| verbose = verbose_opt check = false end opts.parse!(ARGV) end CONFIG = { :dice => dice, :wanted => wanted, :verbose => verbose, :check => check } if CONFIG[:verbose] or CONFIG[:check] puts 'Outcomes:' puts end @wanted = 0 @outcomes = SIDES ** dice @number = 0 def generate_outcomes(num_dice, *previous_rolls) if num_dice == 0 num_wanted = previous_rolls.select { |x| x == 5 }.length wanted = num_wanted >= CONFIG[:wanted] if wanted @wanted += 1 end display = CONFIG[:verbose] || (CONFIG[:check] && (@number % CHECK_FREQUENCY).zero?) if display print " %#{@outcomes.to_s.length}d" % (@number + 1) print ' ' print previous_rolls.inspect print ' <=' if wanted puts end @number += 1 elsif num_dice > 0 1.upto(SIDES) do |x| generate_outcomes(num_dice - 1, *(previous_rolls + [x])) end end end generate_outcomes(dice) puts if CONFIG[:verbose] or CONFIG[:check] puts "Possible outcomes: #{@outcomes}" puts "Desired outcomes: #{@wanted}" puts "Probability: #{@wanted.to_f/@outcomes.to_f}" -- -yossef