[英]Recursively generate all k-digit numbers whose digit-sum is n
I was working on a problem where I'm finding all k-digit numbers whose digits sum up the given n.我正在解决一个问题,我正在查找所有 k 位数字的数字总和给定的 n。
I found how to do this and approach it as Integer Partitioning problem, however I would like to be able to only input n and k numbers (without the max_element) but when I try to delete it from the code it doesn't seem to work anymore.我找到了如何做到这一点并将其作为整数分区问题来处理,但是我希望只能输入 n 和 k 数字(没有 max_element),但是当我尝试从代码中删除它时,它似乎不起作用了。
How can I change that plus reverse it?我怎样才能改变它加上扭转它?
def c(n, k, max_element):
allowed = range(max_element, 0, -1)
def helper(n, k, t):
if k == 0:
if n == 0:
yield t
elif k == 1:
if n in allowed:
yield t + (n,)
elif 1 * k <= n <= max_element * k:
for v in allowed:
yield from helper(n - v, k - 1, t + (v,))
return helper(n, k, ())
for p in c(5, 3, 3):
print(p)
I tried using the reversed method but apparently it doesn't work in the generator.我尝试使用相反的方法,但显然它在生成器中不起作用。
Result:结果:
(3, 1, 1)
(2, 2, 1)
(2, 1, 2)
(1, 3, 1)
(1, 2, 2)
(1, 1, 3)
Expected result:预期结果:
113 122 131 212 221 311
There are a couple of problems here;这里有几个问题; the first is that you want the numbers in order and this code generates them in reverse order, because of
range(max_element, 0, -1)
.第一个是您想要按顺序排列数字,并且此代码以相反的顺序生成它们,因为
range(max_element, 0, -1)
。 The other problem is that since you're generating digits, the minimum element should be 0 and the maximum element should always be 9. We can fix both by changing that range to range(10)
.另一个问题是,由于您正在生成数字,因此最小元素应为 0,最大元素应始终为 9。我们可以通过将该范围更改为
range(10)
来解决这两个问题。
We still need to be careful not to generate numbers starting with 0, so we'll make allowed
a parameter and use range(1, 10)
for just the first digit.我们仍然需要注意不要生成以 0 开头的数字,因此我们将
allowed
一个参数并仅使用range(1, 10)
作为第一个数字。 I've also changed it to return the result as an integer instead of a tuple.我还更改了它以将结果作为整数而不是元组返回。
For reference, the code for this generator function comes from my answer to another question .作为参考,这个生成器函数的代码来自我对另一个问题的回答。
def c(n, k):
def helper(n, k, t, allowed):
if k == 0:
if n == 0:
yield t
elif k == 1:
if n in allowed:
yield 10*t + n
elif 0 <= n <= 9 * k:
for v in allowed:
yield from helper(n - v, k - 1, 10*t + v, range(10))
return helper(n, k, 0, range(1, 10))
Example:例子:
>>> for p in c(5, 3):
... print(p)
...
104
113
122
131
140
203
212
221
230
302
311
320
401
410
500
This function should do the trick这个函数应该可以解决问题
def c(n, k, max_element):
allowed = range(max_element, 0, -1)
def helper(n, k, t):
if k == 0:
if n == 0:
yield t
elif k == 1:
if n in allowed:
yield t + (n,)
elif 1 * k <= n <= max_element * k:
for v in allowed:
yield from helper(n - v, k - 1, t + (v,))
return helper(n, k, ())
def reversed_iterator(iter):
return reversed(list(iter))
for p in reversed_iterator(c(5, 3, 3)):
print(p)
here is the output :这是输出:
(1, 1, 3)
(1, 2, 2)
(1, 3, 1)
(2, 1, 2)
(2, 2, 1)
(3, 1, 1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.