function that counts...
Lie Ryan
lie.1296 at gmail.com
Fri May 28 20:23:41 EDT 2010
On 05/26/10 11:04, Bryan wrote:
> Jean-Michel Pichavant wrote:
>> I still don't see "how many positive integers less than n have digits
>> that sum up to m" makes it a "partition" though if that what prttn
>> means. Surely because I miss the context.
>
> A partition of a positive integer m is an unordered collection of
> positive integers that sum to m. [1, 1, 2, 5] is a partition of 9. The
> problem at issue here is not that of counting partitions.
>
> My algorithm for our prttn separated out the 'ndsums' sub-problem:
> Count d-digit ints with digits summing to m. I found a generalization
> of that problem stated in the /CRC Handbook of Discrete and
> Combinatorial Mathematics/ (2000 edition, section 2.1) among "counting
> problems" as:
>
> Solutions to x_1 + ... x_n = k
> 0 <= x_i <= a_i for one or more i
>
> Alas, the handbook does not provide a formula or algorithm. It refers
> to the inclusion/exclusion principle, which I did not see how to turn
> into an efficient algorithm.
superpollo posted this question in comp.programming
(http://groups.google.com/group/comp.programming/browse_thread/thread/e3b10346db8ebd0a/579ca67f8b9b5a8c;
http://groups.google.com/group/comp.programming/msg/f7323d6e6942e883;
http://groups.google.com/group/comp.programming/browse_thread/thread/e3b10346db8ebd0a/dc4cd1e2feb89500
)
I went through the mathematical foundation of using
partition/distribution and inclusion-exclusion, and have written some
code that solves a subset of the problem, feel free if you or superpollo
are interested in continuing my answer (I won't be able to continue it
until next week, have been a little bit busy here)
copying the code here for convenience:
# memoization would be very useful here
def fact(n):
""" factorial function (i.e. n! = n * (n-1) * ... * 2 * 1) """
return n * fact(n - 1) if n != 0 else 1
def C(n, r):
""" regular Combination (nCr) """
return fact(n) / (fact(n - r) * fact(r))
def D(M, N):
""" Distribution aka Partitioning """
return C(M + N - 1, M)
def partition10(M, i):
""" Count how many integer < N sums to M where N = 10**int(i) """
s = 0
sign = 1
for j in range(i + 1):
s += sign * D(M, i) * C(i, j)
# flip the sign for inclusion-exclusion
sign *= -1
# if M = 32, then 32, 22, 12, 2, -8
M -= 10
return s
# still need to write:
# def partitionN10(...): -- applies a "restriction"/"boundary" to
# the most significant digit
# then make it recurse.
# assuming factorials calculation is constant time (hint: memoization)
# the resulting code should work in O(n**2)
# an improvement over the naive method which is O(10**n)
# where n is the number of digits in N
# DISCLAIMER: the big-O is a quick guess, not really calculated
More information about the Python-list
mailing list