【问题标题】:Python codility lesson : stacks and queues fish bugPython codility 课程:堆栈和排队鱼虫
【发布时间】:2018-07-15 14:44:57
【问题描述】:

我的代码似乎为一个关于 codility 的测试用例返回了错误的答案。(其余测试用例是正确的)

对于一个测试用例: 大随机

大型随机测试,N = ~100,000 我得到了一个

得到 868 预期 840

问题链接: https://app.codility.com/programmers/lessons/7-stacks_and_queues/fish/



def solution(A, B): #declare stacks for fish traveling downstrea, upstream dstrm = [] ustrm = [] #set counter to zero for fish traveling upstream UNHINDERED #by fish traveling downstream, needed because iteration starts upstream counter = 0 n = len(A) #iterate over input, starting from upstream for i in range(n): if B[i] == 0: ustrm.append(A[i]) elif B[i] == 1: dstrm.append(A[i])

# clear upstream stack of fish known to be UNHINDERED, increase counter if len(ustrm) > 0 and len(dstrm) == 0: counter += len(ustrm) ustrm.clear() #compare what's bigger and decrease stack of fish that is eaten while len(dstrm) > 0 and len(ustrm) > 0: if dstrm[-1] > ustrm[-1]: ustrm.pop() elif ustrm[-1] > dstrm[-1]: dstrm.pop() return len(dstrm) + len(ustrm) + counter

【问题讨论】:

  • 只是为了澄清我的策略,我将开始“上游”并迭代“下游”,分别添加到堆栈 ustrm 和 dstrm 鱼。已知会畅通无阻地逆流而上,因此不会被吃掉的鱼将被中间的 if 语句添加到变量“counter”中,并清除 ustrm 堆栈,只要堆栈中有鱼(面向鱼的鱼),while 循环就会循环彼此)和比较之后,将被“吃掉”(弹出),留下下一条鱼进行比较。变量计数器,将添加并返回 dstrm 的长度

标签: python stack


【解决方案1】:

这是我的方法 - 可能有人能想到 - 我是如何解决的 Codility Python 中 100% 的顺从性

代码

def solution(A, B):
"""
Codility 100%
https://app.codility.com/demo/results/trainingF5HTCA-YFV/

Idea is to use stack concept
For each iteration if current fish is of type 1 add it to stack 1 fish
Create stack 1 fish - it always holds the downstream ie 1 kind of fish
 and keep killing the smaller fish from the list if it is greater
  else killed by current fish.
Now if stack 1 fish has no fish it means current fish can be counted as remaining fish.


0 represents a fish flowing upstream - 0 fish
1 represents a fish flowing downstream - 1 fish

A[0] = 4    B[0] = 0 alive fish
A[1] = 3    B[1] = 1 downstream
A[2] = 2    B[2] = 0 eaten by A[1]
A[3] = 1    B[3] = 0 eaten by A[1]
A[4] = 5    B[4] = 0 eat to A[1] and remain alive

"""

count = 0
# stores the 1 fish in stack
stack_1_fish = []
print(A)
print(B)
for index in range(len(A)):
    if B[index] == 0:
        # until stack has some 1 fish
        while stack_1_fish:
            # get last fish from stack and check if it can die or not
            # the larger fish eats the smaller one.
            # two fish P and Q meet each other when P < Q, B[P] = 1 and B[Q] = 0, and there are no living fish between them
            if stack_1_fish[-1] > A[index]:
                # stack 1 fish kill to current fish
                # exit from while loop and else block also execute next top for loop
                # check for other fish fight
                print("Killed by " + str(stack_1_fish[-1]) + " Die " + str(A[index]))
                break
            else:
                # stack 1 fish is killed by current fish
                p = stack_1_fish.pop()
                print("Killed by " + str(A[index]) + " Die " + str(p))

        # this is the case when stack becomes empty ie. no fish of kind 1
        # it would never meet previous fish but can fight with downstream fish
        else:
            print("Count fish as remaining......." + str(A[index]))
            count += 1
    else:
        # fish 1 found add to stack
        stack_1_fish.append(A[index])
        print("1 fish found, add to stack, it can kill or killed by someone..." + str(A[index]))
        print(stack_1_fish)

print("Count: " + str(count))
print("Stack 1 fish: " + str(len(stack_1_fish)))
return count + len(stack_1_fish)

执行输出 -

if __name__ == '__main__':
result = solution([4, 3, 2, 1, 5], [0, 1, 0, 0, 0])
# result = solution([4, 3, 2, 1, 5], [0, 0, 0, 0, 0])
# result = solution([4, 3, 2, 1, 5], [1, 1, 1, 1, 1])
print("")
print("Solution " + str(result))

[4, 3, 2, 1, 5]
[0, 1, 0, 0, 0]
Count fish as remaining.......4
1 fish found, add to stack, it can kill or killed by someone...3
[3]
Killed by 3 Die 2
Killed by 3 Die 1
Killed by 5 Die 3
Count fish as remaining.......5
Count: 2
Stack 1 fish: 0

Solution 2

[4, 3, 2, 1, 5]
[0, 0, 0, 0, 0]
Count fish as remaining.......4
Count fish as remaining.......3
Count fish as remaining.......2
Count fish as remaining.......1
Count fish as remaining.......5
Count: 5
Stack 1 fish: 0

Solution 5

[4, 3, 2, 1, 5]
[1, 1, 1, 1, 1]
1 fish found, add to stack, it can kill or killed by someone...4
[4]
1 fish found, add to stack, it can kill or killed by someone...3
[4, 3]
1 fish found, add to stack, it can kill or killed by someone...2
[4, 3, 2]
1 fish found, add to stack, it can kill or killed by someone...1
[4, 3, 2, 1]
1 fish found, add to stack, it can kill or killed by someone...5
[4, 3, 2, 1, 5]
Count: 0
Stack 1 fish: 5

Solution 5

【讨论】:

    【解决方案2】:

    如果有人仍然对此问题的解决方案感兴趣,这是我使用元组的 Python 方法。我得到了 100%。

    def solution(A, B):
    
        fishes, stack = [], []
    
        for i in range(len(A)):
            fishes.append((B[i], A[i]))
    
        while fishes:
            if stack and not stack[-1][0] and fishes[-1][0]:
                if stack[-1][1] > fishes[-1][1]:
                    fishes.pop()
                else:
                    stack.pop()
            else:
                stack.append(fishes.pop())
    
        return len(stack)
    

    【讨论】:

      【解决方案3】:

      Python 3

      对于那些正在寻找易于理解的分步说明的人,这是我的 100% 解决方案。

      按照课程的建议,它通过 append 和 pop 使用队列/堆栈。

      您可以在底部添加各种测试。提交前不要忘记删除打印输出!

      def solution(A, B):
          N = len(A)
          print('START')
          print('Fish sizes:      ' + str(A))
          print('Fish directions: ' +  str(B))
          print()
          
          upstream = 0
          downstream = []
          
          for n in range(N):
              fs = A[n]
              fd = B[n]
          
              print('Fish pos: ' + str(n) + ', fish dir: ' + str(fd)+ ', fish size: ' + str(fs))
      
              if fd == 0 and downstream == []:
                  print('No fishes in the way')
                  upstream += 1
                  print('Fishes gone upstream: ' + str(upstream))
      
              elif fd == 1:
                  downstream.append(fs)
                  print('No fishes in the way')
                  print('Fishes going downstream: ' + str(downstream))
      
              elif fd == 0 and downstream != []:
                  print('Challenge!')
      
                  while downstream:
                      # pick the downstream head
                      pfs = downstream.pop()
      
                      # if it's bigger kills upstream, puts back downstream, move on
                      if pfs > fs:
                          downstream.append(pfs)
                          print('Downward eats upward')
                          print('Fishes going downstream: ' + str(downstream))
                          break
      
                          # if it's smaller don't put it back and move on to next fish
                      elif pfs < fs:
                          print('Upward eats downward')
                          print('Fishes going downstream: ' + str(downstream))
                          if downstream == []:
                              upstream += 1
                              print('Fishes gone upstream: ' + str(upstream))
                              break
                      continue
              print()
      
          print('FINISH')
          print('Fishes gone upstream: ' + str(upstream))
          print('Fishes going downstream: ' + str(len(downstream)))
          fishes = upstream + len(downstream)
          print('Fishes alive: ' + str(fishes))
      
          return fishes
      
          
      if __name__ == '__main__':
          assert solution([4,3,2,1,5], [0,1,0,0,0]) == 2
          print('Test 1 OK!')
          print()
          assert solution([1,2,3,4,5], [1,1,1,1,0]) == 1
          print('Test 2 OK!')
          print()
          assert solution([5,4,3,2,1], [1,0,0,0,0]) == 1
          print('Test 3 OK!')
          print()
          assert solution([1,2,3,4,5], [1,0,0,0,0]) == 4
          print('Test 4 OK!')
          print()
          assert solution([1,2,3,4,5], [1,1,1,1,1]) == 5
          print('Test 4 OK!')
          print()
      

      这里是逐步解释清楚的输出:

      START
      Fish sizes:      [4, 3, 2, 1, 5]
      Fish directions: [0, 1, 0, 0, 0]
      
      Fish pos: 0, fish dir: 0, fish size: 4
      No fishes in the way
      Fishes gone upstream: 1
      
      Fish pos: 1, fish dir: 1, fish size: 3
      No fishes in the way
      Fishes going downstream: [3]
      
      Fish pos: 2, fish dir: 0, fish size: 2
      Challenge!
      Downward eats upward
      Fishes going downstream: [3]
      
      Fish pos: 3, fish dir: 0, fish size: 1
      Challenge!
      Downward eats upward
      Fishes going downstream: [3]
      
      Fish pos: 4, fish dir: 0, fish size: 5
      Challenge!
      Upward eats downward
      Fishes going downstream: []
      Fishes gone upstream: 2
      
      FINISH
      Fishes gone upstream: 2
      Fishes going downstream: 0
      Fishes alive: 2
      Test 1 OK!
      
      START
      Fish sizes:      [1, 2, 3, 4, 5]
      Fish directions: [1, 1, 1, 1, 0]
      
      Fish pos: 0, fish dir: 1, fish size: 1
      No fishes in the way
      Fishes going downstream: [1]
      
      Fish pos: 1, fish dir: 1, fish size: 2
      No fishes in the way
      Fishes going downstream: [1, 2]
      
      Fish pos: 2, fish dir: 1, fish size: 3
      No fishes in the way
      Fishes going downstream: [1, 2, 3]
      
      Fish pos: 3, fish dir: 1, fish size: 4
      No fishes in the way
      Fishes going downstream: [1, 2, 3, 4]
      
      Fish pos: 4, fish dir: 0, fish size: 5
      Challenge!
      Upward eats downward
      Fishes going downstream: [1, 2, 3]
      Upward eats downward
      Fishes going downstream: [1, 2]
      Upward eats downward
      Fishes going downstream: [1]
      Upward eats downward
      Fishes going downstream: []
      Fishes gone upstream: 1
      
      FINISH
      Fishes gone upstream: 1
      Fishes going downstream: 0
      Fishes alive: 1
      Test 2 OK!
      
      START
      Fish sizes:      [5, 4, 3, 2, 1]
      Fish directions: [1, 0, 0, 0, 0]
      
      Fish pos: 0, fish dir: 1, fish size: 5
      No fishes in the way
      Fishes going downstream: [5]
      
      Fish pos: 1, fish dir: 0, fish size: 4
      Challenge!
      Downward eats upward
      Fishes going downstream: [5]
      
      Fish pos: 2, fish dir: 0, fish size: 3
      Challenge!
      Downward eats upward
      Fishes going downstream: [5]
      
      Fish pos: 3, fish dir: 0, fish size: 2
      Challenge!
      Downward eats upward
      Fishes going downstream: [5]
      
      Fish pos: 4, fish dir: 0, fish size: 1
      Challenge!
      Downward eats upward
      Fishes going downstream: [5]
      
      FINISH
      Fishes gone upstream: 0
      Fishes going downstream: 1
      Fishes alive: 1
      Test 3 OK!
      
      START
      Fish sizes:      [1, 2, 3, 4, 5]
      Fish directions: [1, 0, 0, 0, 0]
      
      Fish pos: 0, fish dir: 1, fish size: 1
      No fishes in the way
      Fishes going downstream: [1]
      
      Fish pos: 1, fish dir: 0, fish size: 2
      Challenge!
      Upward eats downward
      Fishes going downstream: []
      Fishes gone upstream: 1
      
      Fish pos: 2, fish dir: 0, fish size: 3
      No fishes in the way
      Fishes gone upstream: 2
      
      Fish pos: 3, fish dir: 0, fish size: 4
      No fishes in the way
      Fishes gone upstream: 3
      
      Fish pos: 4, fish dir: 0, fish size: 5
      No fishes in the way
      Fishes gone upstream: 4
      
      FINISH
      Fishes gone upstream: 4
      Fishes going downstream: 0
      Fishes alive: 4
      Test 4 OK!
      
      START
      Fish sizes:      [1, 2, 3, 4, 5]
      Fish directions: [1, 1, 1, 1, 1]
      
      Fish pos: 0, fish dir: 1, fish size: 1
      No fishes in the way
      Fishes going downstream: [1]
      
      Fish pos: 1, fish dir: 1, fish size: 2
      No fishes in the way
      Fishes going downstream: [1, 2]
      
      Fish pos: 2, fish dir: 1, fish size: 3
      No fishes in the way
      Fishes going downstream: [1, 2, 3]
      
      Fish pos: 3, fish dir: 1, fish size: 4
      No fishes in the way
      Fishes going downstream: [1, 2, 3, 4]
      
      Fish pos: 4, fish dir: 1, fish size: 5
      No fishes in the way
      Fishes going downstream: [1, 2, 3, 4, 5]
      
      FINISH
      Fishes gone upstream: 0
      Fishes going downstream: 5
      Fishes alive: 5
      Test 4 OK!
      
      > 
      

      【讨论】:

        【解决方案4】:

        您的总体策略对我来说没有意义,实际上我很惊讶大多数测试用例都通过了。这是您的代码出错的一个非常简单的案例:

        A:[1,2] B:[0,1]
        

        如果我对符号的理解正确的话,鱼 0 是最上游的鱼,它正在上游游,鱼 1 是最下游的鱼,它正在下游游。因此,鱼不会相遇,答案是两条。

        但是,您的代码输出 1,因为它实际上根本不检查它们的相对位置。它只是将最上游的下游有头鱼与最上游的上游有头鱼进行比较,并宣布无论它们是否相遇,都会吃掉另一个。

        (如果我把符号倒过来,只需反转数组 B - 您的代码在两种情况下都输出 1,这绝对是不正确的。)

        正确的解决方案需要比较鱼的位置,而不仅仅是它们的大小。

        【讨论】:

        • 我逐字复制了您的代码并完全按照您的描述调用它,它返回 1。您运行的代码与问题中的代码相同吗?如所写,您提到的 if 语句肯定不会运行,因为此时 len(dstrm) != 0 。我想知道,这是一个缩进问题吗?这是否应该在 for 循环内?
        • 对不起,这是我的错,我一定是在复制和粘贴我的代码时搞砸了,我刚刚注意到 return 语句也在 def 解决方案之外......我已经将 if 语句和 while 放在 for 循环中(编辑上面的代码)但仍然得到与原始问题中描述的相同的错误......这是我的策略的问题
        【解决方案5】:

        我发现最优雅的Codility fish solution 可以在这里找到。 它正在使用堆栈:

        def solution(a, b):
            l = 0 # left
            s = [] # stack
            for i in range(len(a)):
                if b[i]==1: # fish moving upwards
                    s.append(a[i]) # to the stack
                else: # eat fish mowing downwards.
                    while len(s)>0:
                        if s[-1]<a[i]:
                            s.pop() # eat from the stack
                        else:
                            break
                    else:
                        l+=1
            l+=len(s)
            return l
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-19
          • 2014-04-21
          • 2015-02-19
          • 2013-09-18
          • 1970-01-01
          • 2015-06-12
          • 2018-04-08
          • 2014-07-21
          相关资源
          最近更新 更多