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