[Edu-sig] Speaking of factorials...

Kirby Urner pdx4d@teleport.com
Mon, 28 May 2001 17:44:53 -0700


>Oh, Kirby, you have got to get over your unhealthy fascination with reduce
><wink>.  

It's a phase, like puberty.

>Seriously, this code is unreadable.  Python is supposed to be
>pretty!  Here's a tease:

>goodcombo 1.506
>badcombo 1.659
>shortcomb 0.615

>timing(goodcombo, 5000, 11, 6)
>timing(badcombo, 5000, 11, 6)
>timing(shortcomb, 5000, 11, 6)

Oooo, fast machine.  Tomorrow I upgrade from this AMD 400 Mhz 
to a 1.2 Mhz AMD Thunderbird -- will retest for kicks.  But then,
this is Windows.  Don't tell me you're on a 386.

> Given the way goodcombo and badcombo work, passing 10,6 to 
> goodcombo but 11,6 to badcombo gave goodcombo an unfair advantage. 

That was an error, to stack the deck like that.  goodcombo is
still faster than badcombo though.

Here's another version of goodcombo:

   def goodcombo(n,k):
       """
       Returns n!/k!(n-k)! where n>=k
       """
       numer = reduce(mul,[1L]+range(n-k+1,n+1))
       return numer/reduce(mul,[1L]+range(2,k+1))

Works with long ints, but still slower than yours, and no 
parameter checking.  I see now that ending with that fatso
division is less efficient than your "divide as you go"
strategy.

   >>> timing(goodchoice2,5000,52,7)
   goodchoice2 7.037
   >>> timing(comb,5000,52,7)
   comb 5.699

comb is well-designed.  Like your _chop method too -- great stuff!

Thank you Guru Peters.

Kirby