我正在尝试仅使用5和7生成两个数字的组合,这将等于任何给定输入的总和。输入范围是24:1000。到目前为止,我所做的是确定输入是否可以被5或7整除,然后生成一个总和等于输入的列表。
这是我的工作示例:
def change(amount):
if amount not in range(24,1001):
print("The number is outside the range.")
else:
remainder=amount%5
if remainder==0:
n = int(amount/5)
array=[0 for i in range(n)]
for i in range(n):
array[i]=5
return array, sum(array)
else:
remainder=amount%7
if remainder==0:
n = int(amount/7)
array=[0 for i in range(n)]
for i in range(n):
array[i]=7
return array, sum(array)
else:
# here is where am stuck
print(change(28))
输出必须为数组形式。例如:对于change(24),数组应为[5,5,7,7]。
答案 0 :(得分:2)
我能想到的最简单的方法
def change(target):
if target not in range(24,1001):
raise ValueError("The number is outside the range.")
res = []
while target % 5 != 0:
res.append(7)
target -= 7
while target != 0:
res.append(5)
target -= 5
return res
change(28)
>>> [7, 7, 7, 7]
答案 1 :(得分:1)
您不需要循环,只需要一点代数。有关详细信息,请参见评论。
def change(amount):
if not 24 <= amount <= 1000:
print("The number is outside the range.")
return None
# 5*3 - 7*2 = 1, so 5*(3*n) + 7*(-2*n) = n, and therefore
# 5*(3*n - 7*k) + 7*(5*k - 2*n) = n for all k
# We want to find a small k so that the terms in each bracket are positive
k = 3 * amount // 7
x = 3 * amount - 7 * k
y = 5 * k - 2 * amount
return x, y, [5] * x + [7] * y
# Print the sequences for some small amounts
for i in range(24, 70):
x, y, seq = change(i)
print(i, x, y, sum(seq) == i)
# Check all values in the range
for i in range(24, 1001):
x, y, seq = change(i)
assert sum(seq) == i
print('ok')
输出
24 2 2 True
25 5 0 True
26 1 3 True
27 4 1 True
28 0 4 True
29 3 2 True
30 6 0 True
31 2 3 True
32 5 1 True
33 1 4 True
34 4 2 True
35 0 5 True
36 3 3 True
37 6 1 True
38 2 4 True
39 5 2 True
40 1 5 True
41 4 3 True
42 0 6 True
43 3 4 True
44 6 2 True
45 2 5 True
46 5 3 True
47 1 6 True
48 4 4 True
49 0 7 True
50 3 5 True
51 6 3 True
52 2 6 True
53 5 4 True
54 1 7 True
55 4 5 True
56 0 8 True
57 3 6 True
58 6 4 True
59 2 7 True
60 5 5 True
61 1 8 True
62 4 6 True
63 0 9 True
64 3 7 True
65 6 5 True
66 2 8 True
67 5 6 True
68 1 9 True
69 4 7 True
ok
这不一定会为每个数量提供最短的序列,但是通常接近最佳值,并且修改此代码以获取最佳值并不是很困难。但这将留给读者练习。 ;)
要了解有关此技术的更多信息,请参阅有关线性Diophantine equations的Wikipedia文章。
答案 2 :(得分:0)
这是我能想到的最快的方法,因为它只使用一个while
周期。
def change(amount):
if not 24 <= amount <= 1001:
print('{} is outside range'.format(amount))
return
sevens = []
fives, remainder = divmod(amount, 5)
while remainder:
amount -= 7
sevens.append(7)
fives, remainder = divmod(amount, 5)
return [5] * fives + sevens
PS:请不要混合列表大小:-)
答案 3 :(得分:0)
对于所有组合,这里都是一个主意。循环可以进一步优化
#titlebar a{
display: inline-block;
}
还有一点优化。收集可能范围内的所有组合,并用sum == target过滤掉组合。
import itertools
def change(target):
nums = [5, 7]
min_len = int(target / 7)
max_len = int(target / 5) + 1
res = []
for len_ in range(min_len, max_len):
r = itertools.combinations_with_replacement(nums, len_)
for item in r:
if sum(item) == target:
res.append(item)
return res
包含目标= 70的所有可能组合的输出
import itertools
def change(target):
nums = [5, 7]
min_len = int(target / 7)
max_len = int(target / 5) + 1
res = []
for len_ in range(min_len, max_len):
res += (list(itertools.combinations_with_replacement(nums, len_)))
return list(filter(lambda x: sum(x) == target, res))
FP样式中没有任何循环。将所有可能的组合简化为一个列表,然后过滤此列表的正确元素。
[(7, 7, 7, 7, 7, 7, 7, 7, 7, 7), (5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7), (5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5)]