"Eugene Kalenkovich" <rubify / softover.com> wrote in message 
news:fnQLi.28752$jC5.1112 / trnddc04...
> My solution. No match counting, + handles 'ruby dice.rb 1000 1'
>
>>---------------------------------------------------
>
> require 'bigdecimal'
> require 'bigdecimal/util'
>
> def f(n) (1..n).inject(1){|a,i|a*=i} end
> def perm(m,n) f(m)/(f(n)*f(m-n)) end


I'd better use google instead of worn memory - though I've managed to do a 
correct formula, name for it was absolutely wrong (perm, for permutations, 
instead of something for combinations). As  a compensation for my 
sloppiness, here is a version of combinations that is almost 3 times faster:

require 'benchmark'

def f(n) (2..n).inject(1){|s,n| s*n } end
def perm(m,n) f(m)/(f(n)*f(m-n)) end  # not pern[utations] at all, 
combinations

def comb(m,n)
  num,denum=m,1;
  (2..n).each{|i| num*=(m-i+1); denum*=i}
  num/denum
end

n=5000;
choices=500;
tests=[]
n.times { a=rand(choices+1); tests<<[a,rand(a)]}

Benchmark.bm do |x|
  x.report("pern") { tests.each{|a| perm(a[0],a[1])} }
  x.report("comb") { tests.each{|a| comb(a[0],a[1])} }
end

__END__

ruby comb_test.rb
      user     system      total        real
perm  6.210000   0.000000   6.210000 (  8.315633)
comb  2.430000   0.000000   2.430000 (  0.332727)

>
> def fives(m,n) (0..m-n).inject(0) {|s,i| s+=5**i * perm(m,i)} end
>
Should read

def fives(m,n) (0..m-n).inject(0) {|s,i| s+=5**i * comb(m,i)} end

[...]