英文:
How to distribute value between fixed amount of notes
问题
def find_note_combinations():
target_value = 1397
target_count = 512
notes = [200, 100, 50, 20, 10, 5, 2]
notes_count = len(notes)
# Initialize variables to store the current combination
current_combination = [0] * notes_count
while True:
# Calculate the current sum based on the current combination
current_sum = sum(note * count for note, count in zip(notes, current_combination))
# If the current sum matches the target value and the count matches the target count
if current_sum == target_value and sum(current_combination) == target_count:
return current_combination
# Find the rightmost non-maxed out note
index = notes_count - 1
while index >= 0 and current_combination[index] == target_count:
index -= 1
# If all notes are maxed out, no solution is possible
if index == -1:
return None
# Increment the count of the rightmost non-maxed out note
current_combination[index] += 1
# Reset all counts to the right of this note
for i in range(index + 1, notes_count):
current_combination[i] = 0
x1, x2, x3, x4, x5, x6, x7 = find_note_combinations()
print("Number of 200 notes:", x1)
print("Number of 100 notes:", x2)
print("Number of 50 notes:", x3)
print("Number of 20 notes:", x4)
print("Number of 10 notes:", x5)
print("Number of 5 notes:", x6)
print("Number of 2 notes:", x7)
This code efficiently finds a combination of notes that satisfies your conditions without the need for nested loops. It uses a systematic approach to explore possible combinations and returns the result when a valid combination is found.
英文:
I have 512 notes between the values of 200, 100, 50, 20, 10, 5 and 2. The sum of these notes is exactly 1397. How much of each note do I have with none of them being 0?
Answer:
- 200: 1 note
- 100: 1 note
- 50: 1 note
- 20: 1 note
- 10: 1 note
- 5: 1 note
- 2: 506 notes
I know there are several possibilities, how I can write a algorithm who return at least one solution for any number of notes and any sum of values? I need to make an code in Python. Thanks!
EDIT: Thanks to Kelly Bundy in the comments, it turns out I'm trying to find an impossible solution with my bad example. So, with the comment edited, I arrived at this code:
def find_note_combinations():
for x1 in range(1, 513):
for x2 in range(1, 513):
for x3 in range(1, 513):
for x4 in range(1, 513):
for x5 in range(1, 513):
for x6 in range(1, 513):
for x7 in range(1, 513):
if x1 + x2 + x3 + x4 + x5 + x6 + x7 == 512 and 200 * x1 + 100 * x2 + 50 * x3 + 20 * x4 + 10 * x5 + 5 * x6 + 2 * x7 == 1397:
return x1, x2, x3, x4, x5, x6, x7
x1, x2, x3, x4, x5, x6, x7 = find_note_combinations()
print("Number of 200 notes:", x1)
print("Number of 100 notes:", x2)
print("Number of 50 notes:", x3)
print("Number of 20 notes:", x4)
print("Number of 10 notes:", x5)
print("Number of 5 notes:", x6)
print("Number of 2 notes:", x7)
But it's ugly and inefficient, help?
答案1
得分: 2
以下是代码的翻译部分:
# 笔记字典(至少要有每个值为1的)
notes = [
[2, 1],
[5, 1],
[10, 1],
[20, 1],
[50, 1],
[100, 1],
[200, 1],
]
def find_solution(target, amount, notes):
s = sum(n * a for n, a in notes)
if amount == 0 and s == target:
return True
if s > target or amount < 0:
return False
for i in range(len(notes)):
notes[i][1] += 1
if find_solution(target, amount - 1, notes):
return True
notes[i][1] -= 1
return False
if find_solution(1397, 512 - len(notes), notes):
print(notes)
打印:
[[2, 506], [5, 1], [10, 1], [20, 1], [50, 1], [100, 1], [200, 1]]
编辑:添加一些启发式方法:
from itertools import product
notes = [
[2, 1],
[5, 1],
[10, 1],
[20, 1],
[50, 1],
[100, 1],
[200, 1],
]
def find_solution(target, amount, notes):
global steps
steps += 1
if steps > 1_000_000:
return False
s = sum(n * a for n, a in notes)
if amount == len(notes):
if target - s not in amount_shorcut:
return False
else:
for val in amount_shorcut[target - s]:
for i in range(len(notes)):
if notes[i][0] == val:
notes[i][1] += 1
break
return True
if amount == 0 and s == target:
return True
if s >= target or amount <= 0:
return False
for i in range(len(notes)):
notes[i][1] += 1
if find_solution(target, amount - 1, notes):
return True
notes[i][1] -= 1
return False
amount_shorcut = {}
for t in product([n for n, _ in notes], repeat=len(notes)):
amount_shorcut[sum(t)] = t
AMOUNT = 12345
N = 87
notes = sorted(notes, key=lambda l: abs(l[0] - (AMOUNT / N)))
# 步骤1:
steps = 0
if find_solution(AMOUNT, N - len(notes), notes):
print(notes)
else:
# 步骤2(交换前两个钞票):
steps = 0
notes[0], notes[1] = notes[1], notes[0]
if find_solution(AMOUNT, N - len(notes), notes):
print(notes)
print('总步数:', steps)
这将打印:
[[200, 60], [100, 2], [50, 1], [20, 2], [10, 1], [5, 1], [2, 20]]
总步数:60434
英文:
You can use a recursion for the task (I recommend to sort the notes
array from lower bill to bigger one):
# notes dict (we must have 1 of each at minimum)
notes = [
[2, 1],
[5, 1],
[10, 1],
[20, 1],
[50, 1],
[100, 1],
[200, 1],
]
def find_solution(target, amount, notes):
s = sum(n * a for n, a in notes)
if amount == 0 and s == target:
return True
if s > target or amount < 0:
return False
for i in range(len(notes)):
notes[i][1] += 1
if find_solution(target, amount - 1, notes):
return True
notes[i][1] -= 1
return False
if find_solution(1397, 512 - len(notes), notes):
print(notes)
Prints:
[[2, 506], [5, 1], [10, 1], [20, 1], [50, 1], [100, 1], [200, 1]]
EDIT: Adding some heurestics:
from itertools import product
notes = [
[2, 1],
[5, 1],
[10, 1],
[20, 1],
[50, 1],
[100, 1],
[200, 1],
]
def find_solution(target, amount, notes):
global steps
steps += 1
if steps > 1_000_000:
return False
s = sum(n * a for n, a in notes)
if amount == len(notes):
if target - s not in amount_shorcut:
return False
else:
for val in amount_shorcut[target - s]:
for i in range(len(notes)):
if notes[i][0] == val:
notes[i][1] += 1
break
return True
if amount == 0 and s == target:
return True
if s >= target or amount <= 0:
return False
for i in range(len(notes)):
notes[i][1] += 1
if find_solution(target, amount - 1, notes):
return True
notes[i][1] -= 1
return False
amount_shorcut = {}
for t in product([n for n, _ in notes], repeat=len(notes)):
amount_shorcut[sum(t)] = t
AMOUNT = 12345
N = 87
notes = sorted(notes, key=lambda l: abs(l[0] - (AMOUNT / N)))
# step 1:
steps = 0
if find_solution(AMOUNT, N - len(notes), notes):
print(notes)
else:
# step 2 (swap first two bills):
steps = 0
notes[0], notes[1] = notes[1], notes[0]
if find_solution(AMOUNT, N - len(notes), notes):
print(notes)
print('Total amount of steps:', steps)
This prints:
[[200, 60], [100, 2], [50, 1], [20, 2], [10, 1], [5, 1], [2, 20]]
Total amount of steps: 60434
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论