生活:是创造还是进化?


17

给定方形的“生命游戏”网格的状态,确定它是否可以从任何先前的状态演变而来,或者只能被创建。即,确定该状态是否为“伊甸园”状态

输入项

状态的正方形网格,其中1表示“活动”,0表示“死”。如果愿意,可以选择两个可区别的符号,而不是0和1。

网格的边长将不为零,但可以为任何自然数1 <= N <= 20。

输入网格外部的任何或所有单元格可能在此世代中仍处于活动状态,而它们中的任何或全部可能在上一代中已处于活动状态。要考虑的宇宙是无限的,因此没有边界条件。输入的边不是Universe的边。具体来说,网格不环绕。

输入可以采用行分隔字符串或单个字符串的形式。如果需要,可以将边长或网格面积作为附加输入(在网格之前或之后)。

可接受的输入格式:

010,101,010

010101010

010
101
010
3 010101010

输出量

如果没有可能导致下一代输入状态的先前状态(包括大于输入网格的状态),则为“已创建”。

如果存在至少一个可能导致下一代输入状态的先前状态(包括大于输入网格的状态),则为“已演化”。

如果愿意,可以使用任何两个可区分的字符串或数字来代替“ Created”和“ Evolved”。

注意,可能的先前状态不必与输入区分开。如果一个国家拥有自己作为下一代,那么它就应该被认为是进化的。

测试用例

010
101
010 Evolved

0101110100
0010101001
1011100110
0101111101
1001001111
1111001001
1011111010
0110011101
1001010100
0010111010 Created

创建的测试用例取自Achim Flammenkamp的《生命游戏页面》

注意

感谢trichoplax编写了这个挑战,我从这里接受了它


6
有任何复杂性限制吗?对于size- mby- 的输入n,如果我测试所有可能的2^(m*n)初始状态,则程序复杂度会很大,但是它仅通过检查结果是否与输入相匹配即可解决问题
Luis Mendo

@路易斯输入?20乘20。对于程序?否
Christopher

2
我不敢打高尔夫球,但这是使用SageMath中捆绑的现成整数编程求解器的有效实现
Orlp

我假设先前的状态(如果存在)是否为伊甸园状态都没关系?
HyperNeutrino

@超级不行!只有你能得到
Christopher

Answers:


3

Java- 1254字节-非常差的解决方案

import java.util.Arrays;
public class z{
static boolean u=1>0,v=0<1;
public static void main(String[] a){
int y=a.length,x=a[0].length();Boolean[][] l=new Boolean[x][y];for(int i=0;i<a.length;i++){l[i]=m(a[i]);}
Boolean[] n=new Boolean[x*y];for(int i=0;i<n.length;i++){n[i]=v;}
while(n.length==x*y){Boolean[][] o=new Boolean[x][y];for(int i=0; i<n.length;i++){o[i%x][i/x]=n[i];}
n=p(n);o=q(o,x,y);int r=0;for(int i=0;i<x*y;i++){if(o[i%x][i/x]&&l[i%x][i/x])r++;}
if(r==x*y){System.out.println("evolved");return;}}System.out.println("created");}
public static Boolean[][] q(Boolean[][] o,int bx,int by){Boolean[][] s=new Boolean[bx][by];for(int x=0; x<bx; x++){for(int y=0;y<by;y++){
int t=0;for(int tx=-1;tx<2;tx++){for(int ty=-1;ty<2;ty++){if(ty+y<0||ty+y>by-1||tx+x<0||tx+x>bx-1)continue;if(o[tx+x][ty+y]){t++;}}}
if(t>1&&t<4){s[x][y]=u;}else{s[x][y]=v;}}}return s;}
public static Boolean[] p(Boolean[] b){boolean w=u;Boolean[] x=new Boolean[b.length];for(int i=0;i<b.length;i++){if(w&&b[i]){x[i]=u;w=u;}else if(b[i]||w){x[i]=u;w=v;}else{x[i]=v;w=v;}
}if(w){x=Arrays.copyOf(x,x.length+1);x[x.length]=u;}return x;}
public static Boolean[] m(String s){Boolean[] x=new Boolean[s.length()];for(int i=0;i<s.length();i++){x[i]=s.charAt(i)=='1';}return x;}}

它通过命令行输入。

它能做什么

这里没有花哨的技巧,只是蛮力的解决方案。它遍历所有可能的大小为X,Y的起始棋盘,并通过“生命游戏”算法对其进行迭代,并对照输入棋盘进行检查。这需要很长时间,因为每个x y的板子都有2 ^(x * y)个可能的组合。运行4x5电路板花费了将近10分钟。愚蠢的事情比它简单。

如果它可能是经过改进的电路板,则打印“已进化”。如果不能进行进化,则打印“已创建”。


真好!我同意时间复杂度很差,但是,嘿,到目前为止,它是唯一的(非伪造的),因此很可能会得到赏金!假设orlp没有发布优化过的::
HyperNeutrino

2
@HyperNeutrino“您赢得了本轮比赛,但我在我的位置上有一张王牌。” -菲利普·弗莱(Phillip J. Fry)
tuskiomi

恭喜,这个解决方案值得赏识!:)
HyperNeutrino

@HyperNeutrino我知道它不是很聪明,也许不是您想要的东西,我希望通过这个易于打败的解决方案来激发其他解决方案,但我希望它足够好。
tuskiomi

1
也是-1不打高尔夫球(哈哈只是在开玩笑,你得到了+1,但仍然可以打出微不足道的高尔夫球);)
HyperNeutrino
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.