下面是一个适用于特定盒子大小的迭代解决方案。if
通过简单地添加更多嵌套块,它可以扩展到其他盒子场景。
满足“更喜欢小盒子”要求的方法就是确保我们适当地搜索解决方案空间。换句话说,我们从最大可能的六框数开始向下搜索。
类似地,我们从最大可能的九个盒子数量(给定六盒子的数量)开始并向下搜索。
我们不必搜索 20 箱的数量,因为考虑到两个较小尺寸的数量,只有一种可能性:尽可能接近所需数量而不会超过的数量。
然后,如果我们得到了准确的数量,我们会立即返回解决方案。否则,我们继续寻找。如果在穷举搜索后没有找到解决方案,我们返回哨兵值(全为零)。
这肯定比测试每个可能的计数场景并保存满足“首选小盒子”要求的天真方法要好。
import typing as typ
def pack_nuggets(quant: int) -> typ.Tuple[int]:
""" Figure out how many nugget boxes are needed.
Given quantity of nuggets, calculates the best triplet
of boxes (of zize 6, 9, and 20) to satisfy the order.
Best in this case prefers smaller boxes to larger.
If no solution, give all zeros.
Args:
quant: the quantity of nuggets desired.
Returns:
Tuple with total box count followed by count of
each box in ascending size).
"""
# Start with maximum possible quantity of six-boxes
# and gradually reduce to zero.
max_sixes: int = quant // 6
for six in range(quant // 6, -1, -1):
# Start with maximum possible quantity of nine-boxes
# given current six-box count and gradually reduce
# to zero.
six_val: int = six * 6
max_nines_for_six: int = (quant - six_val) // 9
for nine in range(max_nines_for_six, -1, -1):
# There's only really one possible twenty-boxes
# count that can get to (or a little below) the
# desired quantity.
nine_val: int = nine * 9
twenty: int = (quant - six_val - nine_val) // 20
# If that's a viable solution, return it.
if six * 6 + nine * 9 + twenty * 20 == quant:
return (six + nine + twenty, six, nine, twenty)
# If there were NO viable solutions, let caller know.
return (0, 0, 0, 0)
什么自尊的开发人员会在没有测试工具的情况下发布代码?“不是我,”帕克斯说 :-)
# Test harness.
if __name__ == "__main__":
for test_val in range(55):
print(f"Result is {pack_nuggets(test_val)} for {test_val} nuggets.")
print(f"Result is {pack_nuggets(1_000_000)} for {1_000_000} nuggets.")
测试工具的输出显示了正在运行的功能(我添加的评论):
Result is (0, 0, 0, 0) for 0 nuggets.
Result is (0, 0, 0, 0) for 1 nuggets.
Result is (0, 0, 0, 0) for 2 nuggets.
Result is (0, 0, 0, 0) for 3 nuggets.
Result is (0, 0, 0, 0) for 4 nuggets.
Result is (0, 0, 0, 0) for 5 nuggets.
Result is (1, 1, 0, 0) for 6 nuggets. # Six is first to satisfy.
Result is (0, 0, 0, 0) for 7 nuggets.
Result is (0, 0, 0, 0) for 8 nuggets.
Result is (1, 0, 1, 0) for 9 nuggets. # Then nine.
Result is (0, 0, 0, 0) for 10 nuggets.
Result is (0, 0, 0, 0) for 11 nuggets.
Result is (2, 2, 0, 0) for 12 nuggets.
Result is (0, 0, 0, 0) for 13 nuggets.
Result is (0, 0, 0, 0) for 14 nuggets.
Result is (2, 1, 1, 0) for 15 nuggets. # A six and a nine.
Result is (0, 0, 0, 0) for 16 nuggets.
Result is (0, 0, 0, 0) for 17 nuggets.
Result is (3, 3, 0, 0) for 18 nuggets. # Prefer 3*six over 2*nine.
Result is (0, 0, 0, 0) for 19 nuggets.
Result is (1, 0, 0, 1) for 20 nuggets. # A single twenty-box.
Result is (3, 2, 1, 0) for 21 nuggets.
Result is (0, 0, 0, 0) for 22 nuggets.
Result is (0, 0, 0, 0) for 23 nuggets.
Result is (4, 4, 0, 0) for 24 nuggets. # Use 4*six, not 2*nine + six.
Result is (0, 0, 0, 0) for 25 nuggets.
Result is (2, 1, 0, 1) for 26 nuggets.
Result is (4, 3, 1, 0) for 27 nuggets.
Result is (0, 0, 0, 0) for 28 nuggets.
Result is (2, 0, 1, 1) for 29 nuggets.
Result is (5, 5, 0, 0) for 30 nuggets.
Result is (0, 0, 0, 0) for 31 nuggets.
Result is (3, 2, 0, 1) for 32 nuggets.
Result is (5, 4, 1, 0) for 33 nuggets.
Result is (0, 0, 0, 0) for 34 nuggets.
Result is (3, 1, 1, 1) for 35 nuggets.
Result is (6, 6, 0, 0) for 36 nuggets.
Result is (0, 0, 0, 0) for 37 nuggets.
Result is (4, 3, 0, 1) for 38 nuggets.
Result is (6, 5, 1, 0) for 39 nuggets.
Result is (2, 0, 0, 2) for 40 nuggets. # Two twenty-boxes.
Result is (4, 2, 1, 1) for 41 nuggets.
Result is (7, 7, 0, 0) for 42 nuggets.
Result is (0, 0, 0, 0) for 43 nuggets.
Result is (5, 4, 0, 1) for 44 nuggets.
Result is (7, 6, 1, 0) for 45 nuggets.
Result is (3, 1, 0, 2) for 46 nuggets.
Result is (5, 3, 1, 1) for 47 nuggets.
Result is (8, 8, 0, 0) for 48 nuggets.
Result is (3, 0, 1, 2) for 49 nuggets.
Result is (6, 5, 0, 1) for 50 nuggets.
Result is (8, 7, 1, 0) for 51 nuggets.
Result is (4, 2, 0, 2) for 52 nuggets.
Result is (6, 4, 1, 1) for 53 nuggets. # 4*six + nine + twenty.
Result is (9, 9, 0, 0) for 54 nuggets. # Prefer 9*six over 6*nine.
# Still very fast, even for a million nuggets.
# But now I feel quite bloated :-)
Result is (166662, 166660, 0, 2) for 1000000 nuggets.