2017-08-01 100 views
-2

我被困在Codefights上的一个问题上。这里是描述:Python:为什么这个算法不能按预期工作?

在流行的扫雷游戏中,你有一个有一些地雷的电路板,那些不包含地雷的单元有一个数字,表示相邻单元中的地雷总数。从一些排雷开始,我们要创建一个扫雷游戏设置。

对于

matrix = [[True, False, False], 
     [False, True, False], 
     [False, False, False]] 

输出应该是:

minesweeper(matrix) = [[1, 2, 1], 
        [2, 1, 1], 
        [1, 1, 1]] 

所以从我个人理解,我们来看看低谷整个矩阵,因为我们需要知道哪些单元格是真的,即包含炸弹,那么当我们找到一个时,所有邻居单元格的值应该增加我首先尝试使用if/elif语句为边界单元编写代码(不要抛出错误),但代码变得非常丑陋而且很长。所以,我能想出的唯一的事情是这样的:

def minesweeper(matrix): 

# First creating the same matrix but instead full of zeros. 
result = [[0]* len(matrix[0]) for row in matrix] 

# Start iterating through the original matrix to find True elements 
for y in range(len(matrix)): 
    for x in range(len(matrix[0])): 
     if matrix[y][x] == True: 

      # The remaining code tries to increment all possible neighbours by 1. 
      for j in range(-1,2): 
       for i in range(-1,2): 

        # If statement so that we do not increment the bomb cell itself. 
        if not (j == 0 and i == 0): 
         try: 
          result[y+j][x+i] += 1 
         except: 
          continue 
return result 

我的函数为

input = [[True, False, False], 
     [False, True, False], 
     [False, False, False]] 

输出是

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

任何人有一个想法,为什么它不工作?而且我也知道你应该尝试用try/except语句来捕获错误,并且这可能是不好的做法,我只是想不出超长的if/elif语句的另一种方式。

+0

请进一步解决您的例子:小写的'真'和'FALSE'应弦(即“真”和“假”)或大写。另外,内部循环中的'yi'和'xi'实际上没有定义。所以,你的代码看起来很糟糕。 – alisianoi

+0

[列表中的列表更改意外地反映到子列表中]的可能重复(https:// stackoverflow。com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) –

+0

@ŁukaszRogalski它不是重复的。结果变量被正确初始化。 – Enfenion

回答

0

我认为你的问题是,使用负向索引访问一个值是Python中的有效操作。因此,在处理第一个元素时,您会增加结果矩阵中的最后一个元素。

你应该尝试,无论是使用调试器单步运行它,或停止x和y的第一次迭代后检查出的值调试在较小的步骤,你的代码。

+0

是的,你完全正确,耶稣..谢谢。 –

0

在接受的答案帮助下面的代码工作。而try/except语句是无用的,因为它里面的代码从来不会抛出错误。

def minesweeper(matrix): 
    result = [[0]* len(matrix[0]) for row in matrix] 

    for y in range(len(matrix)): 
     for x in range(len(matrix[0])): 
      if matrix[y][x] == True: 
       for j in range(-1,2): 
        for i in range(-1,2): 
         if not (j == 0 and i == 0) and not ((y+j) < 0 or (x+i) < 0):  
          result[y+yi][x+xi] += 1 
    return result 
1

另一种可能的方式在执行lenminmax功能只有一次,没有检查,如果细胞是细胞本身上的每一个点(迭代),以限制范围:

true = True # or "true" 
false = False # or "false" 

matrix = [[true, false, false], 
      [false, true, false], 
      [false, false, false]] 


def minesweeper(matrix): 
    # First creating the same matrix but instead full of zeros. 
    result = [[0] * len(matrix[0]) for row in matrix] 

    # Start iterating through the original matrix to find "true" elements 
    y_max = len(matrix) 
    for y in range(y_max): 
     x_max = len(matrix[0]) 
     for x in range(x_max): 
      if matrix[y][x] == true: 
       # The remaining code increments all neighbours by 1, but not beyond the matrix size! 
       for dy in range(max(0, y - 2), min(y_max, y + 2)): 
        for dx in range(max(0, x - 2), min(x_max, x + 2)): 
         result[dx][dy] += 1 
       # Do not increment the bomb cell itself (it was). 
       result[y][x] -= 1 

    return result 

而且print(minesweeper(matrix))给期望的结果[[1, 2, 1], [2, 1, 1], [1, 1, 1]]

相关问题