From: Stephen Kyle Date: 2007-10-01T01:45:03+09:00 Subject: Re: [QUIZ] Probable Iterations (#141) 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 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 > >