def howMany(n) : try : return manies[n] except : sum = 0 i = n manies[n]=0 while n : sum += fact(n%10) n /= 10 manies[i] = 1 + howMany(sum) return manies[i]
from useful import PrimeSet, choose, fact numDiscs = 100 outOfOrder = 22 primes = PrimeSet(numDiscs) numPrimes = len(primes) numComps = numDiscs - numPrimes def recurse(num,total) : if num == 0 : return (0,1) else : val = recurse(num-1,total) first = (num-1) * val[0] second = (val[1] - first) return (second, first*(total-num+1) + second*(total-num)) def ways(num,total) : return recurse(num,total)[1] top = choose(numPrimes,outOfOrder) * ways(outOfOrder,numDiscs-numPrimes+outOfOrder) * fact(numComps) bottom = fact(numDiscs) print float(top)/bottom
# Find the number of ways that twenty 12-sided die can be rolled so the top ten dice sum to 70 from useful import allSums, choose, multinom, fact topNum = 10 totalNum = 20 diceLeft = totalNum-topNum diceVal = 12 sumTo = 70 allWays = 0 for sum in allSums(topNum,sumTo,1,diceVal) : counts = [0] * diceVal for dig in sum : counts[dig-1] += 1 upperBound = sum[0] thisManyWays = 0 for reps in xrange(diceLeft+1) : counts[upperBound-1] += reps thisManyWays += multinom(totalNum, *(counts)) * (upperBound-1)**(diceLeft-reps) / fact(diceLeft-reps) counts[upperBound-1] -= reps allWays += thisManyWays print allWays