生成数字严格递减的数字
Generate numbers with strictly decreasing digits
我正在尝试生成最大长度为 n 的数字,其所有数字都严格递减。
如果n = 5
,
那么数字将是:
54321
5432
543
54
5421
542
541
5321
532
53
521
52
51
5
4321
432
43
431
421
42
41
4
...
关于如何进行的任何提示?
提前致谢
编辑 -
我当前的代码如下所示,但我没有得到所有结果。
def func(arr):
for x in arr:
token=x[-1]
k=int(token)-1
while k>1:
for i in range(1,k):
f.write(x)
for j in range(k,i,-1):
f.write(str(j))
k-=1
f = open ("demo.txt", "w")
arr = ["987"]
for i in range(986,321,-1):
tens = i
units = i%10
tens = int(tens)/10
hundreds = int(tens)/10
tens%=10
hundreds%=10
if tens >= hundreds or units>= tens:
continue
arr.append(str(i))
func(arr)
f.close()
这是一个递归生成器函数:
def nums(n):
if n:
yield from (int(f"{n}{num}") for num in nums(n-1))
yield n
yield from nums(n-1)
[*nums(1)]
# [1]
[*nums(2)]
# [21, 2, 1]
[*nums(3)]
# [321, 32, 31, 3, 21, 2, 1]
[*nums(4)]
# [4321, 432, 431, 43, 421, 42, 41, 4, 321, 32, 31, 3, 21, 2, 1]
或使用itertools.combinations
方法:
from itertools import combinations
def nums(n):
for l in range(n, 0, -1):
for c in combinations(range(n, 0, -1), l):
yield int("".join(map(str, c)))
[*nums(2)]
# [21, 2, 1]
[*nums(3)]
# [321, 32, 31, 21, 3, 2, 1]
[*nums(4)]
# [4321, 432, 431, 421, 321, 43, 42, 41, 32, 31, 21, 4, 3, 2, 1]
其实并不复杂,你可以用itertools.combinations
生成数字组合,然后用zip
应用一个因子,然后取每个项目的乘积和sum
。
例如 [1,2,4,5] 和因数 [1,10,100,1000] 会得到 1+20+400+5000 = 5421。
诀窍是 combinations
总是按照定义的顺序(从前到后)生成组合,所以 combinations([1,2,3], 2)
会给出 [(1, 2), (1, 3), (2, 3)]
from math import prod
n = 5
factors = [10**i for i in range(n)]
[sum(map(prod, zip(factors, c)))
for i in range(n,0,-1)
for c in combinations(range(1,n+1), i)]
输出:
[54321,
4321,
5321,
5421,
5431,
5432,
321,
421,
521,
431,
531,
541,
432,
532,
542,
543,
21,
31,
41,
51,
32,
42,
52,
43,
53,
54,
1,
2,
3,
4,
5]
如果您需要输出的严格顺序,请使用以下(效率稍低):
[sum(map(prod, zip(factors, c)))
for i in range(n,0,-1)
for c in list(combinations(range(1,n+1), i))[::-1]]
输出:
[54321,
5432,
5431,
5421,
5321,
4321,
543,
542,
532,
432,
541,
531,
431,
521,
421,
321,
54,
53,
43,
52,
42,
32,
51,
41,
31,
21,
5,
4,
3,
2,
1]
all digits are strictly decreasing.
此代码生成具有自定义长度的降序数字系列:
import itertools
def generate(lenght):
arr = [range(10)] * lenght
for digits_tuple in itertools.product(*arr):
if all(current_item > next_item for current_item, next_item in zip(digits_tuple, digits_tuple[1:])):
print(digits_tuple)
generate(5)
如果您希望长度为 5 或更小:
for i in range(5):
generate(i+1)
问题有点模糊,不过你可以修改这部分代码来达到你的目的:
all(current_item > next_item for current_item, next_item in zip(digits_tuple, digits_tuple[1:])):
我正在尝试生成最大长度为 n 的数字,其所有数字都严格递减。
如果n = 5
,
那么数字将是:
54321
5432
543
54
5421
542
541
5321
532
53
521
52
51
5
4321
432
43
431
421
42
41
4
...
关于如何进行的任何提示?
提前致谢
编辑 - 我当前的代码如下所示,但我没有得到所有结果。
def func(arr):
for x in arr:
token=x[-1]
k=int(token)-1
while k>1:
for i in range(1,k):
f.write(x)
for j in range(k,i,-1):
f.write(str(j))
k-=1
f = open ("demo.txt", "w")
arr = ["987"]
for i in range(986,321,-1):
tens = i
units = i%10
tens = int(tens)/10
hundreds = int(tens)/10
tens%=10
hundreds%=10
if tens >= hundreds or units>= tens:
continue
arr.append(str(i))
func(arr)
f.close()
这是一个递归生成器函数:
def nums(n):
if n:
yield from (int(f"{n}{num}") for num in nums(n-1))
yield n
yield from nums(n-1)
[*nums(1)]
# [1]
[*nums(2)]
# [21, 2, 1]
[*nums(3)]
# [321, 32, 31, 3, 21, 2, 1]
[*nums(4)]
# [4321, 432, 431, 43, 421, 42, 41, 4, 321, 32, 31, 3, 21, 2, 1]
或使用itertools.combinations
方法:
from itertools import combinations
def nums(n):
for l in range(n, 0, -1):
for c in combinations(range(n, 0, -1), l):
yield int("".join(map(str, c)))
[*nums(2)]
# [21, 2, 1]
[*nums(3)]
# [321, 32, 31, 21, 3, 2, 1]
[*nums(4)]
# [4321, 432, 431, 421, 321, 43, 42, 41, 32, 31, 21, 4, 3, 2, 1]
其实并不复杂,你可以用itertools.combinations
生成数字组合,然后用zip
应用一个因子,然后取每个项目的乘积和sum
。
例如 [1,2,4,5] 和因数 [1,10,100,1000] 会得到 1+20+400+5000 = 5421。
诀窍是 combinations
总是按照定义的顺序(从前到后)生成组合,所以 combinations([1,2,3], 2)
会给出 [(1, 2), (1, 3), (2, 3)]
from math import prod
n = 5
factors = [10**i for i in range(n)]
[sum(map(prod, zip(factors, c)))
for i in range(n,0,-1)
for c in combinations(range(1,n+1), i)]
输出:
[54321,
4321,
5321,
5421,
5431,
5432,
321,
421,
521,
431,
531,
541,
432,
532,
542,
543,
21,
31,
41,
51,
32,
42,
52,
43,
53,
54,
1,
2,
3,
4,
5]
如果您需要输出的严格顺序,请使用以下(效率稍低):
[sum(map(prod, zip(factors, c)))
for i in range(n,0,-1)
for c in list(combinations(range(1,n+1), i))[::-1]]
输出:
[54321,
5432,
5431,
5421,
5321,
4321,
543,
542,
532,
432,
541,
531,
431,
521,
421,
321,
54,
53,
43,
52,
42,
32,
51,
41,
31,
21,
5,
4,
3,
2,
1]
all digits are strictly decreasing.
此代码生成具有自定义长度的降序数字系列:
import itertools
def generate(lenght):
arr = [range(10)] * lenght
for digits_tuple in itertools.product(*arr):
if all(current_item > next_item for current_item, next_item in zip(digits_tuple, digits_tuple[1:])):
print(digits_tuple)
generate(5)
如果您希望长度为 5 或更小:
for i in range(5):
generate(i+1)
问题有点模糊,不过你可以修改这部分代码来达到你的目的:
all(current_item > next_item for current_item, next_item in zip(digits_tuple, digits_tuple[1:])):