Bomb dropping algorithm

后端 未结 30 839
挽巷
挽巷 2021-01-29 16:55

I have an n x m matrix consisting of non-negative integers. For example:

2 3 4 7 1
1 5 2 6 2
4 3 4 2 1
2 1 2 4 1
3 1 3 4 1
2 1 4 3 2
6 9 1 6 4
         


        
30条回答
  •  离开以前
    2021-01-29 17:35

    This does a breadth-search for the shortest path (a series of bombings) through this "maze" of positions. No, I cannot prove that there is no faster algorithm, sorry.

    #!/usr/bin/env python
    
    M = ((1,2,3,4),
         (2,3,4,5),
         (5,2,7,4),
         (2,3,5,8))
    
    def eachPossibleMove(m):
      for y in range(1, len(m)-1):
        for x in range(1, len(m[0])-1):
          if (0 == m[y-1][x-1] == m[y-1][x] == m[y-1][x+1] ==
                   m[y][x-1]   == m[y][x]   == m[y][x+1] ==
                   m[y+1][x-1] == m[y+1][x] == m[y+1][x+1]):
            continue
          yield x, y
    
    def bomb(m, (mx, my)):
      return tuple(tuple(max(0, m[y][x]-1)
          if mx-1 <= x <= mx+1 and my-1 <= y <= my+1
          else m[y][x]
          for x in range(len(m[y])))
        for y in range(len(m)))
    
    def findFirstSolution(m, path=[]):
    #  print path
    #  print m
      if sum(map(sum, m)) == 0:  # empty?
        return path
      for move in eachPossibleMove(m):
        return findFirstSolution(bomb(m, move), path + [ move ])
    
    def findShortestSolution(m):
      black = {}
      nextWhite = { m: [] }
      while nextWhite:
        white = nextWhite
        nextWhite = {}
        for position, path in white.iteritems():
          for move in eachPossibleMove(position):
            nextPosition = bomb(position, move)
            nextPath = path + [ move ]
            if sum(map(sum, nextPosition)) == 0:  # empty?
              return nextPath
            if nextPosition in black or nextPosition in white:
              continue  # ignore, found that one before
            nextWhite[nextPosition] = nextPath
    
    def main(argv):
      if argv[1] == 'first':
        print findFirstSolution(M)
      elif argv[1] == 'shortest':
        print findShortestSolution(M)
      else:
        raise NotImplementedError(argv[1])
    
    if __name__ == '__main__':
      import sys
      sys.exit(main(sys.argv))
    

提交回复
热议问题