生命游戏计划

时间:2017-02-11 19:07:43

标签: ruby algorithm

我正在处理来自Leetcode的以下问题:

  

给定具有m×n个单元的板,每个单元具有初始状态   (1)或死亡(0)。每个细胞与其八个邻居相互作用   (水平,垂直,对角线)使用以下四条规则(拍摄   来自上述维基百科的文章):

     

任何活动邻居少于两个的活细胞都会死亡,好像是由于   根据人口。任何有两三个活着的邻居的活细胞都会存在   到了下一代。任何活三个以上的活细胞   邻居死了,仿佛是过度人口..任何一个完全死亡的细胞   三个活着的邻居变成了活细胞,好像通过繁殖一样。写   计算电路板下一个状态(一次更新后)的功能   鉴于其目前的状态。

     

跟进:你能在原地解决吗?请记住,董事会需要   要同时更新:您无法先更新某些单元格   然后使用更新的值更新其他单元格。

我的解决方案是根据网站上其他用户提供的解决方案建模的,因此请添加他们的解决方案说明。

  

一开始,每个单元格都是00或01.请注意第一个状态   独立于第二州。想象一下,所有细胞都在瞬间改变   从1日到2日,同时。让我们计算#of   来自第一状态的邻居并设置第二状态位。自每个第二州   默认情况下是死的,不需要考虑转换01 - > 00.在   结束,通过执行>>删除每个单元格的第一个状态1.对于每个小区的第一个   位,检查自身周围的8个像素,并设置单元格的第2位。

     

转换01 - > 11:当董事会== 1并且生活> = 2&&生命< = 3。   过渡00 - > 10:当董事会== 0且生命== 3时。

我的代码失败了,我不确定原因。这是输出与预期的对比:

Input:
[[0,0,0,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,0,0,0]]
Output:
[[0,0,0,0,0],[0,0,0,0,0],[0,1,1,1,0],[0,1,0,1,0],[0,0,1,1,0]]
Expected:
[[0,0,0,0,0],[0,0,0,0,0],[0,1,1,1,0],[0,0,0,0,0],[0,0,0,0,0]]

似乎后来的行正在根据先前行中的先前更新进行更新,但我相信我对此进行了解释..任何人都知道问题是什么?我的解决方案如下:

# @param {Integer[][]} board
# @return {Void} Do not return anything, modify board in-place instead.
def game_of_life(board)
    #error conditions
    return nil if (board.nil? || board.length == 0) #empty or nil arr

    row = 0 
    col = 0 
    m = board.length
    n = board[0].length

    until row == m
        col = 0
        until col == n
            live_count = adj_live_counter(board, row, col) #leaving out two conditions because by default second bit is 0
            if alive?(board, row, col) && live_count == 2 || live_count == 3 
                board[row][col] = 3
            elsif dead?(board, row, col) && live_count == 3
                board[row][col] = 2 
            end
            col+=1
        end
        row+=1
    end
    p board 
    #when the above is done, grab second bit for every cell. 
    #board = clear_first_bit(board)
    clear_first_bit(board)
    p board
end 

private 

def adj_live_counter(board, row, col)
    m = board.length 
    n = board[0].length
    count = 0 

    r = [row - 1, 0].max #start: either 0 or the above element
    until r > [row + 1, m - 1].min #end: below element or end of arr
        c = [col - 1, 0].max #start: at left element or 0
        until c > [col + 1, n - 1].min #end: at right element or end of arr
            count += board[r][c] & 1
            #p count 
            c += 1
        end 
        r += 1
    end
    count -=  board[row][col] & 1

    count
end

def clear_first_bit(board)
    m = board.length 
    n = board[0].length

    row = 0 
    col = 0

    until row == m
        col = 0
        until col == n
            board[row][col] >>= 1
            col += 1
        end
        row += 1
    end
end

def alive?(board, row, count)
    board[row][count] & 1 == 1
end

def dead?(board, row, count)
    board[row][count] & 1 == 0
end

网站提供的解决方案(Java):

public void gameOfLife(int[][] board) {
    if (board == null || board.length == 0) return;
    int m = board.length, n = board[0].length;

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            int lives = liveNeighbors(board, m, n, i, j);

            // In the beginning, every 2nd bit is 0;
            // So we only need to care about when will the 2nd bit become 1.
            if (board[i][j] == 1 && lives >= 2 && lives <= 3) {  
                board[i][j] = 3; // Make the 2nd bit 1: 01 ---> 11
            }
            if (board[i][j] == 0 && lives == 3) {
                board[i][j] = 2; // Make the 2nd bit 1: 00 ---> 10
            }
        }
    }

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            board[i][j] >>= 1;  // Get the 2nd state.
        }
    }
}

public int liveNeighbors(int[][] board, int m, int n, int i, int j) {
    int lives = 0;
    for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, m - 1); x++) {
        for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, n - 1); y++) {
            lives += board[x][y] & 1;
        }
    }
    lives -= board[i][j] & 1;
    return lives;
}

1 个答案:

答案 0 :(得分:0)

这些行有一个优先问题:

if (alive?(board, row, col) && live_count == 2) || live_count == 3 
      board[row][col] = 3

此代码解析为:

if alive?(board, row, col) && (live_count == 2 || live_count == 3) 
      board[row][col] = 3

如果你有一个有3个活动邻居的死区(状态0),你将它改为状态3 - 这意味着它将在下一个状态中存活,并且现在也处于当前状态!

请改为尝试:

bCreateTask.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity2.this, NewTaskActivity.class);
            startActivity(intent);

        }
    });