LeetCode:Game of Life - 康威生命游戏

1、题目名称

Game of Life(康威生命游戏)

2、题目地址

https://leetcode.com/problems/game-of-life

3、题目内容

英文:

According to the Wikipedia‘s article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970."

Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):

  1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
  2. Any live cell with two or three live neighbors lives on to the next generation.
  3. Any live cell with more than three live neighbors dies, as if by over-population..
  4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

Write a function to compute the next state (after one update) of the board given its current state.

中文:

根据维基百科条目 Conway‘s Game of Life(康威生命游戏),康威生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。

给出一个m*n的细胞矩阵,每个细胞都有一个初始状态:生存(1)或死亡(0)。每个细胞的变化都与它周围8个细胞有关,规则如下:

  1. 当前细胞为存活状态时,当周围存活细胞不到2个时, 该细胞变成死亡状态。(模拟生命数量稀少)
  2. 当前细胞为存活状态时,当周围有2个或3个存活的细胞时, 该细胞保持原样。
  3. 当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
  4. 当前细胞为死亡状态时,当周围恰好有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)

写一个函数,根据矩阵当前的状态,计算这个细胞矩阵的下一个状态。

4、解题方法

在不使用定义新矩阵的情况下,要想解决本问题就需要先定义一组中间状态,中间状态要求能看出一个单元格变化前后两方面的生死情况。Java代码如下:

/**
 * @功能说明:LeetCode 289 - Game of Life
 * @开发人员:Tsybius2014
 * @开发时间:2015年10月8日
 */
public class Solution {

    //死亡单位
    final int DEAD = 0;
    //存活单位
    final int ALIVE = 1;

    //变化情况:死亡→死亡
    final int DEAD_TO_DEAD = 0;
    //变化情况:存活→存活
    final int ALIVE_TO_ALIVE = 1;
    //变化情况:存活→死亡
    final int ALIVE_TO_DEAD = 2;
    //变化情况:死亡→存活
    final int DEAD_TO_ALIVE = 3;
    
    /**
     * 判断某点在本轮变化前是否是死亡状态
     * @param obj
     * @return
     */
    private boolean isAliveOld(int obj) {
        if (obj == ALIVE_TO_ALIVE || obj == ALIVE_TO_DEAD) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * 判断某点在本轮变化后是否是死亡状态
     * @param obj
     * @return
     */
    private boolean isAliveNew(int obj) {
        if (obj % 2 == 1) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * 生命游戏
     * @param board
     */
    public void gameOfLife(int[][] board) {

        //输入合法性检查
        if (board == null) {
            return;
        }
        int height = board.length;
        if (height == 0) {
            return;
        }
        int width = board[0].length;
        if (width == 0) {
            return;
        }

        //考察所有的点,变化其生命状态
        int counter = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                
                //统计周边生命生存情况
                counter = 0;
                if (i > 0 && j > 0 && isAliveOld(board[i - 1][j - 1])) {
                    counter++;
                }
                if (i > 0 && isAliveOld(board[i - 1][j])) {
                    counter++;
                }
                if (i > 0 && j < width - 1 && isAliveOld(board[i - 1][j + 1])) {
                    counter++;
                }
                if (j > 0 && isAliveOld(board[i][j - 1])) {
                    counter++;
                }
                if (j < width - 1 && isAliveOld(board[i][j + 1])) {
                    counter++;
                }
                if (i < height - 1 && j > 0 && isAliveOld(board[i + 1][j - 1])) {
                    counter++;
                }
                if (i < height - 1 && isAliveOld(board[i + 1][j])) {
                    counter++;
                }
                if (i < height - 1 && j < width - 1 && isAliveOld(board[i + 1][j + 1])) {
                    counter++;
                }
                
                //根据指定点周边的生命生存情况决定当前点的变化
                if (isAliveOld(board[i][j])) {
                    if (counter < 2) {
                        //1.存活单位周边的存活单位少于2个,该单位死亡
                        board[i][j] = ALIVE_TO_DEAD;
                    } else if (counter == 2 || counter == 3) {
                        //2.存活单位周边的存活单位有2-3个,该单位继续存活
                        board[i][j] = ALIVE_TO_ALIVE;
                    } else {
                        //3.存活单位周边的存活单位多余3个,该单位死亡
                        board[i][j] = ALIVE_TO_DEAD;
                    }
                } else {
                    if (counter == 3) {
                        //4.死亡单位周边的存活单位恰好为3个,该单位变为存活状态
                        board[i][j] = DEAD_TO_ALIVE;                    
                    } else {
                        board[i][j] = DEAD_TO_DEAD;
                    }
                }
            }
        }

        //根据变换后的存活状态,重新赋予每个点的生死情况
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                if (isAliveNew(board[i][j])) {
                    board[i][j] = ALIVE;
                } else {
                    board[i][j] = DEAD;
                }
            }
        }
    }
}

END

时间: 2024-07-30 13:45:01

LeetCode:Game of Life - 康威生命游戏的相关文章

关于康威生命游戏的学习

 康威生命游戏,又称康威生命棋,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机.它最初于1970年10月在<科学美国人>杂志上马丁·葛登能的"数学游戏"专栏出现. 一个偶然机会发现了这个美妙的生命游戏.于是开始写程序来实现它,其实实现是很简单的,我现在还只能做到这个而已,不过还会继续深究下去的.先用Random来生成随机数,这样就可以在初始的时候在随机位置设定生死细胞了.输出的时候用2个for循环就是了.昨天做的时候遇到的问题是不知道最后该怎么判断了,因为判断

Python案例(一):协程实现康威生命游戏,元胞自动机

from collections import namedtuple import os,time import random Query=namedtuple('Query',('y','x')) Transition=namedtuple('Transition',('y','x','state')) ALIVE="*" EMPTY="-" def count_neighbors(y,x): n_=yield Query(y+1,x+0) ne=yield Qu

混沌,细胞自动机与生命游戏

混沌,细胞自动机与生命游戏 1.康威生命游戏的规则 生命游戏中,对于任意细胞,规则如下:每个细胞有两种状态-存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动. Ⅰ. A live square with two or three live neighbors survives (survival).Ⅱ. A dead square with exactly three live neighbors becomes a live cell (birth).Ⅲ. In all other c

生命游戏的三种玩法

生命游戏 每个细胞有两种状态--存活或者死亡,每个细胞只与以其自身为中心的细胞产生互动. 当细胞为死亡状态,若周围有3个存活细胞,则该细胞变成存活状态(模拟繁殖) 当细胞为存活状态,若周围有2个或3个存活细胞,保持原样 若周围有3个以上存活细胞,该细胞变成死亡(模拟极度拥挤) 若周围有低于2个一下存活细胞,该细胞死亡(模拟人口稀疏) 这个游戏也叫康威生命游戏.细胞自动机.元胞自动机等. 图案介绍 "脉冲星":它周期为3,看起来像一颗爆发的星星 "滑翔者":每4个回合

LeetCode 289 - 生命游戏 - 原地算法

Wikipedia关于原地算法的描述:原地算法(in-place algorithm)基本上不需要额外辅助的数据结构,然而,允许少量额外的辅助变量来转换数据的算法.当算法运行时,输入的数据通常会被要输出的部分覆盖掉. 很容易看出,原地算法的特点是不需要辅助的数据结构而只需要辅助变量.通常,维护一个复杂的数据结构时间空间复杂度都是比较高的,原地算法的优越性正来自于不依赖数据结构,尽管它借鉴了数据结构的思想. 同时也不难看出,原地算法总体的实现思路就是用输出的数据在原地覆盖已经“没用”的输入的数据.

[Leetcode] 第289题 生命游戏

一.题目描述 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞.每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律: 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡: 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活: 如果活细胞周围八个位置有

Leetcode 289.生命游戏

生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞.每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律: 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡: 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活: 如果活细胞周围八个位置有超过

元胞自动机+生命游戏

元胞自动机 元胞自动机(Cellular Automaton,复数为Cellular Automata,简称CA,也有人译为细胞自动机.点格自动机.分子自动机或单元自动机).是一时间和空间都离散的动力系统.散布在规则格网 (Lattice Grid)中的每一元胞(Cell)取有限的离散状态,遵循同样的作用规则,依据确定的局部规则作同步更新.大量元胞通过简单的相互作用而构成动态系统的演化. 不同于一般的动力学模型,元胞自动机不是由严格定义的物理方程或函数确定,而是用一系列模型构造的规则构成.凡是满

生命游戏&amp;一维细胞自动机 笔记

de 生命游戏是一种简单的聚合模型,展示了事物是如何聚合的,是自动机(CA)模型的一种.由剑桥大学约翰康威发明,其规则为: 1. 每个细胞拥有八个邻居,细胞状态只有存活(黑)和死亡(白)两种: 2.处于死亡状态的细胞可以在有三个存活邻居的情况下复活: 3.存活状态的细胞在相邻有2个一下或三个以上存活细胞的情况下会死去,2-3个相邻细胞存活时会继续存活: 从而产生了信号灯.闪光灯.滑翔机.警示灯等经典的变换. 遵循简单规则的简单图像聚合一起可以形成复杂图像,甚至如活物一般能进行空间平移(自组织模型