模拟规则110


27

规则110是具有一些有趣属性的元胞自动机。 您的目标是用最少的字符来模拟规则110。

对于不知道的人,规则110是在网格中逐行模拟的。网格线中的每个正方形都会查看上方,左上方和右上方的正方形,以确定其应为哪个单元格。

current pattern  111 110 101 100 011 010 001 000
new cell          0   1   1   0   1   1   1   0

输入: 0到39之间的数字,代表任何合理格式(逗号分隔的字符串,列表,函数参数)的第n个输入行的第一行。为了容纳1索引的语言,数字也可以1索引,因此范围是1到40。

输入示例:

38,39

输出:一个40 x 40的网格,代表运行的自动机,包括第一行。您应该将0保留为空白,将1保留为任何可见的打印字符。只要可以合理区分实际网格,就可以使用尾随空格。网格的底部可能有换行符,但网格线之间不应有空行。

输出示例:

                                  XX
                                 XXX
                                XX X
                               XXXXX
                              XX   X
                             XXX  XX
                            XX X XXX
                           XXXXXXX X
                          XX     XXX
                         XXX    XX X
                        XX X   XXXXX
                       XXXXX  XX   X
                      XX   X XXX  XX
                     XXX  XXXX X XXX

等等

注意:关于一维元胞自动机的类似问题已经提出,但是我希望仅使用一条规则就可以写出较短的答案。


4
模式是否环绕(即,最左边的单元格是否检查其上方一行中最右边的单元格)?
Ventero 2014年

4
如果是单数,那么它的一个细胞自动机
ClickRick

1
答案可能比模拟任何一维元胞自动机短一些,因为规则是硬编码的,而不是必须从输入中解析的规则,但答案是相同的。如果这是一条不同的规则,那么就有节省的潜力,但是在特殊情况下,将图灵功能强大的规则放在特殊的情况下,如何在常规实现中节省任何费用?
彼得·泰勒

1
@Ventero他们不在此版本中。
qwr

1
@BMO这是一个古老的问题,但是由于如今的共识是允许灵活的输入格式,所以我将修改问题以允许它
qwr

Answers:


8

果酱-47

S40*l',/{i'!t}/{N40,S3$S++f{>3<2b137Yb='!^}}39*

!用于“ 1”单元格。

http://cjam.aditsu.net/上尝试

说明:

S40*使一个由40个空格组成的字符串(数组)
l',/读取一行并用逗号分割,
{…}/为每个项目(字符串形式的数字)执行该块
- i'!t将数字转换为整数并将该项目设置在前一个字符串中的该位置(最初为40个空格) ) 至 '!'
至此,我们已经获得了第一行。
{…}39*执行该块39次
- N添加换行符
- 40,使数组[0 1…39]
- S3$S++复制前一行(堆栈上的位置3)并在每侧填充空格
- f{…}为{每个数字从0开始执行该块至39}和{填充的行}
>3<从填充的行中抽取3个项目,从当前编号开始
- 2b从2开始转换; 我们切片的项目不是以2为基数的数字,而是将字符转换为ASCII值,并且''mod 8为0和'!' 模8是1
- 137Yb转换137至基座2(Y= 2),获得[1 0 0 0 1 0 0 1],它是110反转并否定(8位)
- ='!^得到相应的碱2位(在数组环绕,因此索引采用mod 8)并与'!'进行异或。字符,导致“!” 为0和''为1


17

Ruby,113个字符

c=[0]*41
eval"[#{gets}].map{|i|c[i]=1}"+'
c=(0..39).map{|x|putc" X"[u=c[x]]
110[4*c[x-1]+2*u+c[x+1]]}<<0;puts'*40

在stdin上接受输入。要使用其他规则,只需将110最后一行中的替换为您想尝试的任何规则。

例:

$ ruby 110.rb <<< 38,39
                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X

8

Mathematica,122个字节

f[a_]:=Riffle[CellularAutomaton[110,Array[If[MemberQ[ToExpression["{"<>a<>"}"],#-1],1,0]&,40],39]/.0->" "/.1->"X","
"]<>""

是的,您可能会认为这是在滥用此漏洞,但是a)漏洞颇具争议,b)蜂窝自动机问题需要 Mathematica答案(尤其是有关规则110的答案),c)Ventero的Ruby答案反而更短,所以我不知道认为不会造成任何伤害。

大多数字符用于输入解析和输出格式化。实际的自动机使用

CellularAutomaton[110,initialGrid,39]

这使用了周期性边界条件(因此网格环绕了)。


8

蟒蛇-141

i=input()
o=range(40)
l=''.join(' X'[c in i]for c in o)
for r in o:print l;l=''.join('X '[l[c-1:c+2]in('XXX','   ','X  ','','  ')]for c in o)

如运行 python 110.py <<< 38,39


3
['X',' ']可以更改为'X '保存5个字符。
加尔文的业余爱好

16
我最喜欢的水果是o=range()
kitcar2000 2014年

7

q,67 62 58字节

假定没有回绕:

{40{not(2 sv'flip 1 0 -1 xprev\:x)in 0 4 7}\@[40#0b;x;~:]}

旧版

{40{not(flip(prev;::;next)@\:x)in 3 cut 111100000b}\@[40#0b;x;not]}
{40{not(flip 1 0 -1 xprev\:x)in 3 3#111100000b}\@[40#0b;x;~:]}

5

Python,186

def r(s,m=range(40)):
 s=[int(i in s)for i in m]
 for g in m:print''.join([' X'[i]for i in s]);s=[int(not''.join(map(str,s[i-1:i+2]if i else s[:2]))in'111 100 000 00'.split())for i in m]

不错,但可能不是最佳的。

您没有指定如何获取输入,所以我只做了一个函数。

使用示例:

r([38,39])

输出:

                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X

我确实指定了输入:在您的情况下,您将必须使用input()并按照原始文章中指定的格式设置输入格式。
qwr 2014年

5

Mathematica,113个字符

Mathematica的另一个答案使用CellularAutomaton

Print@@" "["X"][[#]]&/@CellularAutomaton[110,SparseArray[#+1->1&/@ImportString[InputString[],"CSV"][[1]],40],39];

有趣的是,如何" "["X"][[#]]&工作?
Martin Ender 2014年

@ m.buettner " "["X"][[1]]"X"" "["X"][[0]]返回的头" "["X"],即" "
alephalpha 2014年

哦,我懂了。因此,通常只是将字符保存在列表中。那真的很聪明。我想您可以将其添加到codegolf.stackexchange.com/questions/12900/…–
Martin Ender

4

C-178

此代码取决于矩阵中的每一行都存储在连续内存中的事实。另外,由于规则仅指定了40x40的网格,因此它不会打印第一行,但是会打印接下来的40行。

仅出于可读性考虑缩进,字节数仅包含必要的代码。

a[41][42],i,j,*t;
main(){
    while(scanf("%d,",&j)>0)
        a[i][j]=1;
    for(;i<40;i++,puts(""))
        for(j=0;++j<40;)
            t=&a[i][j],
            putchar((*(t+42)=1&(110>>(*(t+1)?1:0)+(*t?2:0)+(*(t-1)?4:0)))?88:32);
}

3

Lua-351

不是打高尔夫球的理想语言。

s,n,t,u=arg[1],{},table.remove,table.insert
for i=1,40 do u(n,i,'.') end
for i in s:gmatch("%d+")do u(n,i,'x');t(n)end
function a(b) c="";for i=1,40 do c=c..b[i] end;print(c);return c end
for i=1,40 do z= n[40]..a(n)..n[1];for k=2,41 do y=string.sub(z,k-1,k+1);if y=="xxx"or y=="x.." or y=="..." then u(n,k-1,'.')else u(n,k-1,'x')end;t(n)end end

1
do u(n,i,'x')这是故意的,不是吗?
Stan Strum,

3

哈斯克尔 175个170 169 136 127 124字节

−9个字节,感谢@bmo

t(a:b:r:_)=mod(b+r+b*r+a*b*r)2
w%a=take 40.map w.iterate a
d l=t%tail$0:l++[0]
f l=map(" #"!!)%d$(fromEnum.(`elem`l))%succ$0

在线尝试!


3

Haskell中135个131 130字节

-1个字节感谢ØrjanJohansen(重新安排take 40

完全不同的方法来解决FrownyFrog的答案,但长度相同:

(a?b)r=mod(b+r+b*r+a*b*r)2
r x=0:(zipWith3(?)x=<<tail$tail x++[0])
f y=take 40$map(" o"!!)<$>iterate r[sum[1|elem i y]|i<-[0..40]]

1个

说明

4101个

f y=                               [sum[1|elem i y]|i<-[0..40]]

40

    take 40$              iterate r

01个

            map(" o"!!)<$>

r110zipWith3(?)

r x=0:(zipWith3(?)x=<<tail$tail x++[0])

(?)运营商的解决方案中最有趣的部分:以前我用卡诺图生成布尔规则,但原来有一个更简洁的方法:

(a?b)r=mod(b+r+b*r+a*b*r)2

1
通过放在take 40$之前保存一个字节map(" o"!!)<$>
与Orjan约翰森

3

外壳31 28字节

哈哈,果壳在打果冻!

†!¨↑¨↑40¡ȯẊȯ!ḋ118ḋėΘ`:0M#ŀ40

在线尝试!

解释与取消

在添加解释之前,让我稍微讲一下。.首先,我们删除各种组成,添加显式括号并解压缩¨↑¨字符串。也让我们换掉404一个更可读的解释:

†!"t "↑4¡(Ẋ(!ḋ118ḋė)Θ`:0)M#ŀ4  -- example input: [3]
                           ŀ4  -- lower range of 4: [0,1,2,3]
                         M     -- map over left argument
                          #    -- | count in list
                               -- : [0,0,0,1]
        ¡(              )      -- iterate the following indefinitely (example with [0,1,1,1])
                     `:0       -- | append 0: [0,1,1,1,0]
                    Θ          -- | prepend 0: [0,0,1,1,1,0]
          Ẋ(       )           -- | map over adjacent triples (example with  1 1 0
                  ė            -- | | create list: [1,1,0]
                 ḋ             -- | | convert from base-2: 6
                               -- | | convert 118 to base-2: [1,1,1,0,1,1,0]
                               -- | | 1-based index: 1
                               -- | : [1,1,0,1]
                               -- : [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1],[1,1,1,1],[1,0,0,1],...]
      ↑4                       -- take 4: [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1]]
†                              -- deep map the following (example with [1,1,0,1])
 !"t "                         -- | use each element to index into "t ": "tt t"
                               -- : ["   t","  tt"," ttt","tt t"]

2

Java,321个字符

例如,从命令行作为参数传递的输入 java R 38,39

我从来没有写过更加混淆的Java代码:-)

class R{public static void main(String[]a) {
Integer s=40;boolean[]n,o=new boolean[s];
for(String x:a[0].split(","))o[s.valueOf(x)]=s>0;
for(Object b:o){n=o.clone();
for(int j=0;j<s;j++){
boolean l=j>1&&o[j-1],r=o[j],c=j+1<s&&o[j+1];
n[j]=!(l&c&r|l&!c&!r|!(l|c|r));
System.out.print((r?"X":" ")+(j>s-2?"\n":""));
}o=n;}}}

2

更新:此处正确的输出示例(40行而不是50行):下面的新输出(为简便起见,删除了先前的输出):

                                      xx
                                     xxx
                                    xx x
                                   xxxxx
                                  xx   x
                                 xxx  xx
                                xx x xxx
                               xxxxxxx x
                              xx     xxx
                             xxx    xx x
                            xx x   xxxxx
                           xxxxx  xx   x
                          xx   x xxx  xx
                         xxx  xxxx x xxx
                        xx x xx  xxxxx x
                       xxxxxxxx xx   xxx
                      xx      xxxx  xx x
                     xxx     xx  x xxxxx
                    xx x    xxx xxxx   x
                   xxxxx   xx xxx  x  xx
                  xx   x  xxxxx x xx xxx
                 xxx  xx xx   xxxxxxxx x
                xx x xxxxxx  xx      xxx
               xxxxxxx    x xxx     xx x
              xx     x   xxxx x    xxxxx
             xxx    xx  xx  xxx   xx   x
            xx x   xxx xxx xx x  xxx  xx
           xxxxx  xx xxx xxxxxx xx x xxx
          xx   x xxxxx xxx    xxxxxxxx x
         xxx  xxxx   xxx x   xx      xxx
        xx x xx  x  xx xxx  xxx     xx x
       xxxxxxxx xx xxxxx x xx x    xxxxx
      xx      xxxxxx   xxxxxxxx   xx   x
     xxx     xx    x  xx      x  xxx  xx
    xx x    xxx   xx xxx     xx xx x xxx
   xxxxx   xx x  xxxxx x    xxxxxxxxxx x
  xx   x  xxxxx xx   xxx   xx        xxx
 xxx  xx xx   xxxx  xx x  xxx       xx x
xx x xxxxxx  xx  x xxxxx xx x      xxxxx
xxxxxx    x xxx xxxx   xxxxxx     xx   x

做了另一个难题,我学到了一些关于在PHP中的for循环中嵌套语句的有趣知识,突然之间,它们比我最初想象的要复杂得多。当我有时间时,我认为我可以大大超过这个分数。现在,尽管它在非竞争性408处保持不变。


我的php版本408个字符:

这是一个很大的难题。我还花了很长时间来处理输入,因为这些都是必须说的有趣的事情。无论如何,这是我的PHP版本(虽然与发布的一些答案相去甚远,但还是完整的。在第0个位置仅占右上方和上方,在第39个位置仅占左上方和上方,即没有换行。所以这里是我的版本:

<?php $a='38,39';$b='';$d=explode(',',$a);for($i=0;$i<40;++$i){$c=' ';
foreach($d as $k=>$v){if($v == $i){$c='x';}}$b.=$c;}echo $b."\n";
for($x=1;$x<41;++$x){$o='';for($i=1;$i<41;++$i){if(($i>1)AND(substr($b,$i-2,1)=='x')){
$l=1;}else{$l=0;}if((substr($b,$i-1,1))=='x'){$v=1;}else{$v=0;}if((substr($b,$i,1))=='x'){
$r=1;}else{$r=0;}if((($l+$v+$r)==2)OR(($v+$r)==1)){$o.='x';}else{$o.=' ';}}
echo $o."\n";$b=$o;}?>

您可以在此处查看并运行它:http : //codepad.org/3905T8i8

输入是开头的输入字符串,为$ a = '38,39';

输出如下:

xx removed as was too long originally - had 50 lines, not 40 xx

希望你喜欢!!!

PS我必须在代码中添加一些换行符,以便您可以看到全部内容,而不必让它在整个页面上都带有滚动条。


您的输出有50行
aditsu

啊,那是因为我在看完发生后正在玩它。稍微更改规则会产生如此有趣的效果。无论如何,现在已将其更改为40,并且很遗憾错过了。
Paul Drewett 2014年

您可能也想更改输出:p
aditsu

更正了输出并添加了具有正确值的新键盘链接。再次感谢你。
Paul Drewett

2

Stax,24 字节CP437

╦♥µ╤u{£┬íQ<;▀ΦΣ╢╕╚äZ↕áû↑

在线运行和调试!

将CP437中的代码点1用于“ 1”单元。

出色的案例展示了这种语言的力量。

说明

使用解压后的版本(29字节)进行解释。

0]40X*,1&xDQ0]|S3B{:b^374:B@m
0]40X*                           Prepare a tape with 40 cells
      ,1&                        Assign 1 to the cells specified by the input
         xD                      Repeat the rest of the program 40 times
           Q                     Output current tape
            0]|S                 Prepend and append a 0 cell to it
                3B               All runs of length 3
                  {         m    Map each run with block
                   :b            Convert from binary
                     ^           Increment (call this value `n`)
                      374:B      The binary representation of 374
                                 [1,0,1,1,1,0,1,1,0]
                                 which is `01101110` reversed and prepended a 1
                           @     Element at 0-based index `n`

1

K(ngn / k)44 35字节

{"X "39{(2\145)@2/'3'1,x,1}\^x?!40}

在线尝试!

{ } 带参数的功能 x

!40 从0到39的整数列表

x?在中找到其索引x,使用0N(“ integer null”)表示找不到

^其中哪些为空?这给了我们负面的投入

39{ }\ 申请39次,在列表中收集中间结果

1,x,1 用1s(否定0)包围列表

3' 连续项目的三倍

2/' 每个二进制解码

@ 在...中用作索引

2\145 二进制编码145(取反的110位)

"X "最后,使用40x40矩阵作为字符串中的索引"X "@此处为隐式)


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.