Python:为什么这个算法没有按预期工作?

时间:2017-08-01 12:49:09

标签: python algorithm

我在Codefights上遇到了问题。这是描述:

在流行的扫雷游戏中你有一块带有一些地雷的电路板,那些不含地雷的电池里面有一个数字,表示相邻小区的地雷总数。从一些地雷安排开始,我们想要创建一个扫雷游戏设置。

示例

有关

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

输出应为:

minesweeper(matrix) = [[1, 2, 1],
                   [2, 1, 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 if / elif语句。

3 个答案:

答案 0 :(得分: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]]

答案 1 :(得分:0)

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

您应该尝试以较小的步骤调试代码,方法是使用调试器逐步调试代码,或者在x和y的第一次迭代后停止并检出值。

答案 2 :(得分: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