> 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. Hi, I wanted to look a little into parsing command line options and arguments, so I took the opportunity to try Ara's "main" gem (gem install main). I have a question about the usage of main at the end of the post, if somebody can help me out, that'd be great. In addition to the requirements I also added the possibility to pass another option (--type or -t) with the type of comparison you want to perform: at_least, exactly, no_more_than, less_than or more_than. It defaults to at_least. Here it is: # quiz141.rb # 29 September 2007 # require 'main' $compare_types = {"at_least" => :>=, "exactly" => :==, "no_more_than" => :<=, "more_than" => :>, "less_than" => :<} main { argument('dice') { cast :int description "number of dice to throw" } argument('num') { cast :int description "number of fives to count in each throw" } option('verbose', 'v') { description "verbose mode: will show all combinations" } option('samples', 's') { description "sample mode: will show 1 combination every 50000" } option('type', 't') { argument :required defaults "at_least" validate {|type| $compare_types.keys.include?(type)} description "Type of comparison. Possible values: " + $compare_types.keys.join(",") } def run verbose = params[:verbose].given? samples = params[:samples].given? dice = params[:dice].value num = params[:num].value type = params[:type].value method = $compare_types[type] puts "Checking #{type} #{num} fives throwing #{dice} dice" puts "Verbose mode" if verbose puts "Samples mode" if samples current = Array.new(dice) {1} current[0] = 0 # to start the loop incrementing the first element total_matches = 0 total_iter = 0 begin total_iter += 1 (0...dice).each do |i| if (current[i] < 6) current[i] += 1 break else current[i] = 1 end end match = current.select {|x| x == 5}.size.send(method, num) total_matches += 1 if match if (verbose || (samples && total_iter%50000 == 1)) print total_iter, " ", current.inspect puts "#{match ?'<==':''}" end end while current.any?{|x|x != 6} puts "Number of desirable outcomes: #{total_matches}" puts "Number of possible outcomes: #{total_iter}" puts "Probabilty is #{total_matches.to_f/total_iter.to_f}" end } Here's the output with 2 1 for each type of comparison. $ ruby -rubygems quiz141.rb --type less_than 2 1 Checking less_than 1 fives throwing 2 dice Number of desirable outcomes: 25 Number of possible outcomes: 36 Probabilty is 0.694444444444444 $ ruby -rubygems quiz141.rb --type at_least 2 1 Checking at_least 1 fives throwing 2 dice Number of desirable outcomes: 11 Number of possible outcomes: 36 Probabilty is 0.305555555555556 $ ruby -rubygems quiz141.rb --type exactly 2 1 Checking exactly 1 fives throwing 2 dice Number of desirable outcomes: 10 Number of possible outcomes: 36 Probabilty is 0.277777777777778 $ ruby -rubygems quiz141.rb --type no_more_than 2 1 Checking no_more_than 1 fives throwing 2 dice Number of desirable outcomes: 35 Number of possible outcomes: 36 Probabilty is 0.972222222222222 $ ruby -rubygems quiz141.rb --type more_than 2 1 Checking more_than 1 fives throwing 2 dice Number of desirable outcomes: 1 Number of possible outcomes: 36 Probabilty is 0.0277777777777778 My question about main is the following: if you check my code, I have a variable ($compare_types) I need to use both in the validate block for an option and in the run method. Is there a better way to achieve this than a global variable? Regards, Jesus.