【问题描述】
1970年John Conway发表了一篇论文,在该文中他描述了一种由非常简单规则导致的有趣和复杂的行为。他的研究主要是关于生物组织工作方面。他假象将一些活体组织放在一个二维的网格空间中,然后将四种简单的规则应用在网格的每个区域并迭代一定次数,最终产生了复杂的行为。
这四种规则都是基于与该区域临近区域的活体数量。在他的实验中,网格中横向、纵向、斜向紧挨的格子被认为是临近的,因此每个格子会有8个其他的格子与之临近。
原始的四种规则如下:
1、如果一个格子的临近格子中只有少于2个活体,由于过于孤单的原因这个活体将死亡;
2、如果一个格子的临近格子中刚好有2个活体,该活体将继续生存;
3、如果一个格子的临近格子中刚好有3个活体,该活体将继续生存,如果之前该位置没有活体那么将产生一个活体;
4、如果一个格子的临近格子中大于3个活体,由于过于拥挤的原因这个活体将死亡;
对于这个问题,我们可以自定义规则,而不是简单的重复它,我们通过给定一个规则串来指定规则。规则串是由 'D', 'S', 'B'三种字母组成。每个字母在规则串中的位置索引值决定了临近活体数量产生的影响。比如,规则串中第一个字母的索引为0,这是指一个格子周围存在0个活体时候应该产生的影响。
在规则字符串中,D表示当一个格子的临近区域的活体数等于其在规则串中的索引数的时候,这个格子中的活体死亡,S表示活体继续保持生存,B表示活体将继续生存,如果之前该位置没有活体那么将产生一个活体。
因此使用这种表示方法,前面提到的四个规则可以表示成"DDSBDDDDD"该规则串。(临近区域存在0、1、4、5、6、7、8个活体的时候该活体死亡,存在2个的时候继续生存,存在3个的时候允许再生)
程序输入中,给定一个描述网格中机体初始状态的String数组start,和一个规则串,以及一个迭代次数。需要返回最终在该网格空间中的活体数量。
定义:
类 GameOfLife
方法 public int alive(String[] start, String rules, int generations)
说明:
1、在输入的初始网格中,'X'代表一个活体,'.'代表一个空区域或者一个已死的机体。
2、在计算临近区域的时候,应该使用”循环“的方式,即比如最左面的格子应该认为和最右面的相关格子相邻,因此4个角的格子是互相相邻的。
3、每次应用规则的时候,应该是同时应用到所有的格子,因此我们计算每个格子临近活体数的时候需要在我们应用规则之前,即本次迭代的结果不能影响本次计算。
约束:
1、网格是一个n×m的二维数组,n为start数组的大小,m为每个字符串的长度,均为1至50(包括)。
2、网格中仅包括'X'和'.'字符。
3、规则串是由9个字母组成的字符串,仅包含字母'D', 'S', 'B'
4、迭代次数在0至1000次(包括)。
测试用例:
1、 {"......"
,"......"
,".XXXX."
,"......"
,"......"}
"DDSBDDDDD"
2
Returns: 6
2、 {"XX","XX"}
"DDSBDDDDD"
1
Returns: 0
3、 {"........XXX"
,"..........X"
,".........X."
,"..........."
,"..........."
,"..........."
,"..........."
,"..........."
,"..........."
,"..........."
,"..........."}
"DDSBDDDDD"
1000
Returns: 5
【我的解答】
1970年John Conway发表了一篇论文,在该文中他描述了一种由非常简单规则导致的有趣和复杂的行为。他的研究主要是关于生物组织工作方面。他假象将一些活体组织放在一个二维的网格空间中,然后将四种简单的规则应用在网格的每个区域并迭代一定次数,最终产生了复杂的行为。
这四种规则都是基于与该区域临近区域的活体数量。在他的实验中,网格中横向、纵向、斜向紧挨的格子被认为是临近的,因此每个格子会有8个其他的格子与之临近。
原始的四种规则如下:
1、如果一个格子的临近格子中只有少于2个活体,由于过于孤单的原因这个活体将死亡;
2、如果一个格子的临近格子中刚好有2个活体,该活体将继续生存;
3、如果一个格子的临近格子中刚好有3个活体,该活体将继续生存,如果之前该位置没有活体那么将产生一个活体;
4、如果一个格子的临近格子中大于3个活体,由于过于拥挤的原因这个活体将死亡;
对于这个问题,我们可以自定义规则,而不是简单的重复它,我们通过给定一个规则串来指定规则。规则串是由 'D', 'S', 'B'三种字母组成。每个字母在规则串中的位置索引值决定了临近活体数量产生的影响。比如,规则串中第一个字母的索引为0,这是指一个格子周围存在0个活体时候应该产生的影响。
在规则字符串中,D表示当一个格子的临近区域的活体数等于其在规则串中的索引数的时候,这个格子中的活体死亡,S表示活体继续保持生存,B表示活体将继续生存,如果之前该位置没有活体那么将产生一个活体。
因此使用这种表示方法,前面提到的四个规则可以表示成"DDSBDDDDD"该规则串。(临近区域存在0、1、4、5、6、7、8个活体的时候该活体死亡,存在2个的时候继续生存,存在3个的时候允许再生)
程序输入中,给定一个描述网格中机体初始状态的String数组start,和一个规则串,以及一个迭代次数。需要返回最终在该网格空间中的活体数量。
定义:
类 GameOfLife
方法 public int alive(String[] start, String rules, int generations)
说明:
1、在输入的初始网格中,'X'代表一个活体,'.'代表一个空区域或者一个已死的机体。
2、在计算临近区域的时候,应该使用”循环“的方式,即比如最左面的格子应该认为和最右面的相关格子相邻,因此4个角的格子是互相相邻的。
3、每次应用规则的时候,应该是同时应用到所有的格子,因此我们计算每个格子临近活体数的时候需要在我们应用规则之前,即本次迭代的结果不能影响本次计算。
约束:
1、网格是一个n×m的二维数组,n为start数组的大小,m为每个字符串的长度,均为1至50(包括)。
2、网格中仅包括'X'和'.'字符。
3、规则串是由9个字母组成的字符串,仅包含字母'D', 'S', 'B'
4、迭代次数在0至1000次(包括)。
测试用例:
1、 {"......"
,"......"
,".XXXX."
,"......"
,"......"}
"DDSBDDDDD"
2
Returns: 6
2、 {"XX","XX"}
"DDSBDDDDD"
1
Returns: 0
3、 {"........XXX"
,"..........X"
,".........X."
,"..........."
,"..........."
,"..........."
,"..........."
,"..........."
,"..........."
,"..........."
,"..........."}
"DDSBDDDDD"
1000
Returns: 5
【我的解答】
- import java.util.HashMap;
- public class GameOfLife {
- private boolean[][] grid;
- private HashMap<Integer, Integer> dieMap = new HashMap<Integer, Integer>();
- private HashMap<Integer, Integer> surMap = new HashMap<Integer, Integer>();
- private HashMap<Integer, Integer> borMap = new HashMap<Integer, Integer>();
- private int getAliveNum() {
- int count = 0;
- for (int i = 0; i < grid.length; i++)
- for (int k = 0; k < grid[0].length; k++)
- if (grid[i][k])
- count++;
- return count;
- }
- private boolean applyRule(int row, int col) {
- int n = grid.length;
- int m = grid[0].length;
- int upRow = row - 1 >= 0 ? row - 1 : n - 1;
- int downRow = row + 1 < n ? row + 1 : 0;
- int leftCol = col - 1 >= 0 ? col - 1 : m - 1;
- int rightCol = col + 1 < m ? col + 1 : 0;
- int count = 0;
- if (grid[upRow][leftCol])
- count++;
- if (grid[upRow][col])
- count++;
- if (grid[upRow][rightCol])
- count++;
- if (grid[row][leftCol])
- count++;
- if (grid[row][rightCol])
- count++;
- if (grid[downRow][leftCol])
- count++;
- if (grid[downRow][col])
- count++;
- if (grid[downRow][rightCol])
- count++;
- if (dieMap.containsKey(count))
- return false;
- else if (surMap.containsKey(count))
- return grid[row][col];
- else
- return true;
- }
- private void setRule(String rules) {
- for (int i = 0; i < rules.length(); i++) {
- if ('D' == rules.charAt(i))
- dieMap.put(i, 0);
- else if ('S' == rules.charAt(i))
- surMap.put(i, 0);
- else
- borMap.put(i, 0);
- }
- }
- public int alive(String[] start, String rules, int generations) {
- int n = start.length;
- int m = start[0].length();
- grid = new boolean[n][m];
- setRule(rules);
- for (int i = 0; i < n; i++)
- for (int k = 0; k < m; k++)
- if ('X' == start[i].charAt(k))
- grid[i][k] = true;
- boolean[][] tmp;
- int num = 0;
- while (num++ < generations) {
- tmp = new boolean[n][m];
- for (int i = 0; i < n; i++)
- for (int k = 0; k < m; k++)
- tmp[i][k] = applyRule(i, k);
- grid = tmp;
- }
- return getAliveNum();
- }
- }