2017-08-01 153 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]]

相關問題