Hi,
I doubt my method of finding the iterations is particularly efficient:

I just have a function, nextLogicalRoll, which returns the next
"logical" set of dice, when you give it a set of dice, so it'll return
[1,2,1], if given [1,1,3]. I give it the first logical set, an array
of as-many-dice-as-we're-using 1s, and then watch for when it returns
as-many-dice-as-we're-using 6s.

The function has a "seek" pointer that points at the end of the array,
and if the number at that index isn't 6, it increases it by one, and
returns that array. Else it changes the 6 to a 1, and the pointer
moves one position towards the start of the array, this is repeated
until a number that isn't 6 is found at the array, this number is
increased by one, and the array is returned.

I quite like the way I do array finding, and although it's no doubt a
computational nightmare, on the order of O(n^10000) or something, it's
quite pretty. It just creates a string representing what we're looking
for; for instance, if we're looking for two fives, it'll be "55", and
then we sort the array representing the dice roll, convert it to a
string, and see if our "desired" string is a subset of the string.

That's all from me, this is my first time, be kind. :P

- Steve

Code:

$desired_count = 0
$possible_count = 0

# argument "parsing" fun, delicate
verbose = true if ARGV[0] == "-v"
sample = true if ARGV[0] == "-s"
if sample or verbose
        dice = ARGV[1] if ARGV[1] =~ /\d+/
        desired = ARGV[2] if ARGV[2] =~ /\d+/
        hunted = ARGV[3] if ARGV[3] =~ /\d+/
else
        dice = ARGV[0] if ARGV[0] =~ /\d+/
        desired = ARGV[1] if ARGV[1] =~ /\d+/
        hunted = ARGV[2] if ARGV[2] =~ /\d+/
end
dice = dice.to_i
desired = desired.to_i

def nextLogicalRoll(array) # find the next "logical" set of dice
        seek = (array.length-1)
        if array[seek] != 6
                array[seek] += 1
        else
                while array[seek] == 6 do
                        array[seek] = 1
                        seek -= 1
                end
                array[seek] += 1
        end
        return array
end

def printArray(array) # reinventing the wheel, no doubt.
        print "["
        values = array * ","
        print values
        print "]"
end

def check(array,desired,hunted)
        match = hunted.to_s * desired
        return array.sort.to_s.include?(match)
end

set = Array.new(dice).fill(1)
finale = Array.new(dice).fill(6)
loop do
        $possible_count += 1
        print "#{$possible_count}. " if verbose or (sample and
$possible_count % 50000 == 1)
        printArray(set) if verbose or (sample and $possible_count % 50000 == 1)
        if check(set,desired,hunted)
                $desired_count += 1
                print " <==" if verbose or (sample and $possible_count
% 50000 == 1)
        end
        puts if verbose or (sample and $possible_count % 50000 == 1)
        break unless set != finale
        nextLogicalRoll(set)
end

puts
puts "Number of desirable outcomes is #{$desired_count}"
puts "Number of possible outcomes is #{$possible_count}"
puts
probability = $desired_count.to_f / $possible_count.to_f
puts "Probability is #{probability}"


On 28/09/2007, Ruby Quiz <james / grayproductions.net> wrote:
> The three rules of Ruby Quiz:
>
> 1.  Please do not post any solutions or spoiler discussion for this quiz until
> 48 hours have passed from the time on this message.
>
> 2.  Support Ruby Quiz by 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 original quiz message,
> 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
>
>