【问题标题】:How can I find whether my output fits the criteria or not?如何确定我的输出是否符合标准?
【发布时间】:2022-01-16 17:48:53
【问题描述】:

编写一个函数processOrders(orders:List[int], sizes:List[int]) 来确定每个给定的订单是否可以被执行。这里,orders 是一个正整数列表,其中每个整数代表该订单所要求的长度。 size 是一个正整数列表(不一定从小到大排序),表示该商店携带的各个杆长度。您的函数必须返回一个布尔值列表,其中第 i 个元素指示是否可以满足第 i 个订单。

processOrders([5, 12, 13, 20], [1, 2, 5, 10]) == [True, True, True, True]

在上面的例子中,商店销售长度为:1、2、5、10 的杆。由于商店销售 5 厘米的杆,因此可以履行 5 厘米的订单。此外,由于商店结合了 2 厘米和 10 厘米杆,因此可以完成 12 厘米的订单。 13cm的顺序可以满足,因为它是10+2+1。 20cm的订单可以完成,因为店家焊接了两根10cm的棒材。

我尝试过这样做,但它不起作用..

def findsum(s,g): 
       for f in g:         
           for x in s:            
               if sum (x) == f:               
                  return True            
               else:                         
                  return False 

我需要做哪些改变?

编辑:任何组合都应该有效:)

【问题讨论】:

  • 有没有限制,可以执行多少个挥舞操作,因为否则,每个订单,它是整数而不是浮点数,都可以通过根据需要一起挥舞尽可能多的1cm棒来完成
  • 为什么示例测试用例中的所有值都不是 True?
  • @FirestarXYZ 哎呀,对不起。他们都是真的:)如果你可以请提供解释:)
  • 就像 Yggraz 所说的,我们是否正在尝试验证任何组合是否有效?因为这意味着我们可以像一堆 1 厘米长的棒一样焊接在一起
  • @Yg 是的,如果列表中有 1,那也可以,但是我很确定我将获得的数据不会那么简单

标签: python list function boolean equation-solving


【解决方案1】:

这是一种方法。

import itertools

def processOrders(orders, sizes):
    """
    Ref:
      https://docs.python.org/3/library/itertools.html#itertools.combinations
      https://stackoverflow.com/questions/70331554/how-can-i-find-whether-my-output-fits-the-criteria-or-not#70331554
    """
    ret = []
    omax = max(orders)  # generate combo for up to max of orders
    
    # combine all sizes and get the sum and save to list
    all_sizes = []
    for i in range(1, omax + 1):
        combo = itertools.combinations_with_replacement(sizes, i)
        for j in list(combo):
            sj = sum(j)
            all_sizes.append(sj)            
    all_sizes = list(set(all_sizes))  # remove duplicates  
    # print(f'all sizes: {all_sizes}')
    
    # Read each value in the orders and check it in all_sizes.    
    for o in orders:
        if o in all_sizes:
            ret.append(True)
        else:
            ret.append(False)
            
    return ret
                
       
# Start
res = processOrders([5, 12, 13, 20], [1, 2, 5, 10])
print(res)  # [True, True, True, True]

res = processOrders([5, 12, 13, 100, 45], [4, 8, 12, 16])
print(res)  # [False, True, False, True, False]

res = processOrders([1, 2, 3, 4], [16, 8, 12, 4])
print(res)  # [False, False, False, True]

res = processOrders([27, 9, 6, 12], [7, 11])
print(res)  # [False, False, False, False]

另一种使用数字整除性的方法。

def processOrders(orders, sizes):
    """
    Ref:
      https://www.mathsisfun.com/definitions/divisible.html
      https://stackoverflow.com/questions/70331554/how-can-i-find-whether-my-output-fits-the-criteria-or-not#70331554
    """
    ret = []
    
    for o in orders:  # read each value in the orders
        success = False
        for s in sizes:  # read each value in the sizes
            if o % s == 0:  # if order can be divided by size without remainder
                ret.append(True)
                success = True
                break  # get out of for s .. loop
        if not success:
            ret.append(False)
            
    return ret
                
 
# Start
res = processOrders([5, 12, 13, 20], [1, 2, 5, 10])
print(res)  # [True, True, True, True]

res = processOrders([5, 12, 13, 100, 45], [4, 8, 12, 16])
print(res)  # [False, True, False, True, False]

res = processOrders([1, 2, 3, 4], [16, 8, 12, 4])
print(res)  # [False, False, False, True]

res = processOrders([27, 9, 6, 12], [7, 11])
print(res)  # [False, False, False, False]

【讨论】:

    【解决方案2】:

    这个问题与代表动态规划的问题非常相似,称为硬币找零问题。在这个问题中,我们只是尝试验证是否存在可能的组合来实现求和,而在硬币找零问题中,我们检查存在多少种可能的组合。

    我将首先发布这个问题的代码,然后解释硬币找零问题的实现,然后解释我们如何稍微调整一下以适应这个问题。

    代码:

    def findWays(order, sizes):
        ways = [0] * (order + 1);
        ways[0] = 1;
        for i in range(len(sizes)):
            for j in range(len(ways)):
                if (sizes[i] <= j):
                    ways[j] += ways[(j - sizes[i])];
            if ways[len(sizes) - 1] > 0:
              return True;
        return False
     
    def processOrders(orders,sizes):
        fulfilled = [False] * len(orders)
        for i in range(len(orders)):
          fulfilled[i] = findWays(orders[i],sizes)
        
        for i in range(len(fulfilled)):
          print(fulfilled[i])
    
    processOrders([5, 12, 13, 20], [1, 2, 5, 10])
    #Output: True True True True
    

    解决这个问题的关键是了解如何将其分解为更小的问题。首先,让我们假设尺寸列表已排序。

    让我们从一个小例子开始:

    我们想要价值 5 与 1、2 和 3 个有价值的硬币的总和。

    现在,让我们创建一个数组,列出我们可以将 0 到 5 的值求和的方法。我们将第 0 个索引设置为 1,因为只有一种方法可以求和 0。我将列出它们带有索引和值:

    [0, 1, 2, 3, 4, 5]

    [1, 0, 0, 0, 0, 0]

    现在,让我们从价值 1 的硬币开始。从索引 1 开始,因为这是硬币的价值,让我们在该值上加 1,因为仅使用价值 1 的硬币,我们有 1 种方法来制作 1:

    [0, 1, 2, 3, 4, 5]

    [1, 1, 0, 0, 0, 0]

    但是,如果我们有 1 种方式来制作 1,那么通过添加 1,我们可以制作 2。因此,如果我们有 1 种方式制作 2,通过添加 1,我们可以制作 3。我们可以重复这个过程,直到我们到达 5:

    [0, 1, 2, 3, 4, 5]

    [1, 1, 1, 1, 1, 1]

    现在,让我们从价值 2 的硬币开始。我们从索引 2 开始。使用相同的过程,我们将 2 的值增加 1:

    [0, 1, 2, 3, 4, 5]

    [1, 1, 2, 1, 1, 1]

    现在,用类似的思维方式:如果已经有 1 种方法可以产生 1 的值,那么通过添加一个 2 值的硬币,我们就有了一种新的方法来获得 3。如果已经有 2 种方法来得到 2 的值,然后通过添加 value-2 硬币,我们有 2 种新的方法来获得 4。如果已经有 2 种方法来获得 3 的值,那么通过添加 value-2 硬币,我们有 2 种新的方法来获得 3 的值得到 5:

    [0, 1, 2, 3, 4, 5]

    [1, 1, 2, 2, 3, 3]

    现在,用价值 3 的硬币:将 3 的价值增加 1。如果有 1 种方法得到 1,那么通过添加价值 3 的硬币,我们有 1 种新方法得到 4。如果有已经有 2 种方法来获得 2,通过添加价值 3 的硬币,我们有 2 种新的方法来获得 5:

    [0, 1, 2, 3, 4, 5]

    [1, 1, 2, 3, 4, 5]

    我们已经检查了所有的硬币,因此我们可以得出结论,有 5 种方法可以获得 5 的值,硬币值为 1、2、3。让我们手动验证我们的结果:

    5种求和的方法:

    1 + 1 + 1 + 1 + 1

    1 + 2 + 2

    2 + 3

    1 + 1 + 3

    1 + 1 + 1 + 2

    为了实现这个问题,每次我们检查一个有价值的硬币(或在这种情况下是大小)时,我们都会检查它可以制作的方式数的索引顺序值是否为1或更多。如果是,我们将退出循环并返回true。

    这是一个非常长的解释,所以如果您需要更多帮助,请告诉我!

    【讨论】:

      猜你喜欢
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 2011-03-07
      • 2015-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多