【问题标题】:Code Golf: Conway's Game of Life代码高尔夫:康威的人生游戏
【发布时间】:2025-12-11 18:10:02
【问题描述】:

挑战:编写实现 John H. Conway 的生命游戏元胞自动机的最短程序。 [link]

编辑:经过大约一周的比赛,我选出了一个胜利者:pdehaan,以一个击败 Matlab 解决方案perl 中的字符。

对于那些没有听说过生命游戏的人,您可以选择一个网格(理想情况下是无限的)方形单元格。细胞可以是活的(填充的)或死的(空的)。我们通过应用以下规则来确定哪些细胞在下一步中还活着:

  1. 任何活细胞少于两个的活细胞都会死亡,好像是由于人口不足造成的。
  2. 任何有超过三个活邻居的活细胞都会死亡,就像过度拥挤一样。
  3. 任何有两三个活邻居的活细胞都可以传给下一代。
  4. 任何只有三个活邻居的死细胞都会变成活细胞,就像通过繁殖一样。

您的程序将读取指定为命令行参数的 40x80 字符 ASCII 文本文件,以及要执行的迭代次数 (N)。最后将N次迭代后系统的状态输出到ASCII文件out.txt中。

这是一个使用相关文件运行的示例:

in.txt:

................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
..................................XX............................................
..................................X.............................................
.......................................X........................................
................................XXXXXX.X........................................
................................X...............................................
.................................XX.XX...XX.....................................
..................................X.X....X.X....................................
..................................X.X......X....................................
...................................X.......XX...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................

迭代 100 次:

Q:\>life in.txt 100

结果输出 (out.txt)

................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
..................................XX............................................
..................................X.X...........................................
....................................X...........................................
................................XXXXX.XX........................................
................................X.....X.........................................
.................................XX.XX...XX.....................................
..................................X.X....X.X....................................
..................................X.X......X....................................
...................................X.......XX...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................

规则:

  • 您需要使用文件 I/O 来读取/写入文件。
  • 您需要接受输入文件和迭代次数作为参数
  • 需要生成指定格式的out.txt(如果存在则覆盖)
  • 不需要处理板的边缘(环绕、无限网格等)
  • 编辑:您确实需要在输出文件中包含换行符。

获胜者将由字符数决定。

祝你好运!

【问题讨论】:

  • 这是一个很棒的代码高尔夫!我完全相信它属于 SO。几天前我在 APL 中发现了一个很棒的实现:youtube.com/watch?v=a9xAKttWgP4
  • 可以接受的想法,但你需要加强它。 meta.stackexchange.com/questions/24242/…
  • 相对受欢迎程度对于高尔夫来说是一个不好的衡量标准。 perl 总是得到很多选票,即使它不是最短的,即使它不符合规范。你应该坚持字符数。语言更冗长的人仍然可以相互竞争
  • 输入文件中是否有换行符?
  • ^ 输出文件中是否需要它们?

标签: language-agnostic code-golf rosetta-stone conways-game-of-life


【解决方案1】:

Mathematica - 179 163 154 151 个字符

    a = {2, 2, 2};
    s = Export["out.txt", 
       CellularAutomaton[{224, {2, {a, {2, 1, 2}, a}}, {1,1}}, 
                (ReadList[#1, Byte, RecordLists → 2>1] - 46)/ 42, #2]〚#2〛
       /. {0 → ".", 1 → "X"}, "Table"] &
添加空格以提高可读性

调用

    s["c:\life.txt", 100]

动画:

您还可以获得平均人口随时间变化的图表:

Wikipedia生成滑翔机的好模式

AFAIK Mathematica uses a Cellular Automaton to generate random numbers 使用 Rule 30.

【讨论】:

  • 拥有一个内置的CellularAutomaton 函数似乎解决了一些挑战。
  • @AShelly 我猜代码高尔夫挑战可以通过两种方式进行 > 调整一个不合适的工具或找到一个好的工具
  • @Adrian 不同语言的不同挑战。在 Mathematica 中,ASCII 格式令人头疼……
【解决方案2】:

MATLAB 7.8.0 (R2009a) - 174 171 161 150 138 131 128 124 个字符

函数语法:(124 个字符)

这是更易于阅读的版本(添加了不必要的换行符和空格以更好地格式化):

function l(f,N),
  b=char(importdata(f))>46;
  for c=1:N,
    b=~fix(filter2(ones(3),b)-b/2-3);
  end;
  dlmwrite('out.txt',char(b*42+46),'')

下面是从 MATLAB 命令行窗口运行程序的方式:

l('in.txt',100)

命令语法:(130 个字符)

在关于使用命令语法调用函数的评论之后,我深入挖掘并发现 MATLAB 函数可以实际上是invoked with a command-line format(有一些限制)。你每天都能学到新东西!

function l(f,N),
  b=char(importdata(f))>46;
  for c=1:eval(N),
    b=~fix(filter2(ones(3),b)-b/2-3);
  end;
  dlmwrite('out.txt',char(b*42+46),'')

下面是从 MATLAB 命令行窗口运行程序的方式:

l in.txt 100


附加挑战:可推文 GIF 制作器 - 136 个字符

为了好玩,我想看看是否可以将输出转储到 GIF 文件而不是文本文件,同时仍将字符数保持在 140 以下(即“可推文”)。这是格式良好的代码:

function l(f,N),
  b=char(importdata(f))>46;
  k=ones(3);
  for c=1:N+1,
    a(:,:,:,c)=kron(b,k);
    b=~fix(filter2(k,b)-b/2-3);
  end;
  imwrite(~a,'out.gif')

虽然IMWRITE 应该创建一个默认无限循环的 GIF,但我的 GIF 只循环一次。也许这是一个已在较新版本的 MATLAB 中修复的错误。所以,为了让动画持续时间更长,让进化步骤更容易看到,我将帧延迟保留为默认值(似乎是半秒左右)。这是使用 Gosper Glider Gun 模式的 GIF 输出:


改进

  • 更新 1: 将矩阵 b 从逻辑(即“布尔”)类型更改为数字类型,以消除一些转换。
  • 更新 2: 缩短了加载文件的代码,并使用函数 MAGIC 作为技巧,以更少的字符创建卷积核。
  • 更新 3: 简化了索引逻辑,将 ~~b+0 替换为 b/42,并将 'same' 替换为 's' 作为 CONV2 的参数(令人惊讶的是它仍然有效!)。
  • 更新 4: 我想我应该先在网上搜索,因为今年早些时候来自 The MathWorks 的Loren blogged about golfing and the Game of Life。我合并了那里讨论的一些技术,这需要我将 b 改回逻辑矩阵。
  • 更新 5: 上述博客文章中的 comment from Aslak Grinsted 建议使用更短的算法用于逻辑和执行卷积(使用函数 FILTER2),所以我“合并”(阅读“复制”)他的建议。 ;)
  • 更新 6:b 的初始化中修剪了两个字符,并重新设计了循环中的逻辑以节省 1 个额外的字符。
  • 更新 7: Eric Sampson 在一封电子邮件中指出,我可以将 cell2mat 替换为 char,节省 4 个字符。谢谢埃里克!

【讨论】:

    【解决方案3】:

    Ruby 1.9 - 189 178 159 155 153 个字符

    f,n=$*
    c=IO.read f
    n.to_i.times{i=0;c=c.chars.map{|v|i+=1
    v<?.?v:('...X'+v)[[83,2,-79].map{|j|c[i-j,3]}.to_s.count ?X]||?.}*''}
    File.new('out.txt',?w)<<c
    

    编辑: 处理少 4 个字符的换行符。
    如果您允许它在活细胞到达边缘时破坏换行符,则可以再删除 7 个 (v&lt;?.?v:)。

    【讨论】:

    • 我认为您可以通过将第 3 行替换为 v&lt;13?v:l==3||v-l==?T?X:?.}} 来减去 12 个字符。但是我没有安装 1.9 来测试它。
    • 我认为您不能将v(字符串)与整数进行比较。
    • 所以尝试v&lt;?.?v:l==3||v.ord-l==84??X:?.}} 保存7。
    • 很好,但是当活细胞靠近边缘时,这不会覆盖换行符吗?
    • 没错,我不确定这条规则是否可行:“这意味着你可以对边缘情况做任何你想做的事情。事情可能会消失,破坏.etc”。如果@hb2pencil 说不好,将回滚。
    【解决方案4】:

    perl, 127 129 135 字符

    设法去掉了几个字符...

    $/=pop;@b=split'',<>;map{$n=-1;@b=map{++$n;/
    /?$_:($t=grep/X/,@b[map{$n+$_,$n-$_}1,80..82])==3|$t+/X/==3?X:'.'}@b}1..$/;print@b
    

    【讨论】:

    • 这会写入 'out.txt' 吗?
    • @b=&lt;&gt;=~/./g 再保存 3 个字符
    【解决方案5】:

    Python - 282 个字符

    还不如让球滚……

    import sys
    _,I,N=sys.argv;R=range(3e3);B=open(I).read();B=set(k for k in R if'A'<B[k])
    for k in R*int(N):
     if k<1:b,B=B,set()
     c=sum(len(set((k+o,k-o))&b)for o in(1,80,81,82))
     if(c==3)+(c==2)*(k in b):B.add(k)
    open('out.txt','w').write(''.join('.X\n'[(k in B)-(k%81<1)]for k in R))
    

    【讨论】:

    • 但是 2.7(和 3.x)接受大括号以进行集合理解,因此 set(...) 可以替换为 {...},并且将 range(3e3) 替换为 range(3000) 可以净改进 2 个字符。
    【解决方案6】:

    Python 2.x - 210/234 个字符

    好的,210 个字符的代码有点作弊。

    #coding:l1
    exec'xÚ=ŽA\nÂ@E÷sŠº1­ƒÆscS‰ØL™Æª··­âî¿GÈÿÜ´1iÖ½;Sçu.~H®J×Þ-‰­Ñ%ª.wê,šÖ§J®d꘲>cÉZË¢V䀻Eîa¿,vKAËÀå̃<»Gce‚ÿ‡ábUt¹)G%£êŠ…óbÒüíÚ¯GÔ/n×Xši&ć:})äðtÏÄJÎòDˆÐÿG¶'.decode('zip')
    

    您可能无法复制和粘贴此代码并使其正常工作。它应该是 Latin-1 (ISO-8859-1),但我认为它在某个地方被歪曲成 Windows-1252。此外,您的浏览器可能会吞下一些非 ASCII 字符。

    因此,如果它不起作用,您可以从普通的 7 位字符生成文件:

    s = """
    23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 3D 8E 41 5C 6E C2
    40 0C 45 F7 73 8A BA 31 13 AD 83 15 11 11 C6 73 08 63 17 05 53 89 D8 4C
    99 C6 AA B7 B7 AD E2 EE BF 47 C8 FF DC B4 31 69 D6 BD 3B 53 E7 75 2E 7E
    48 AE 4A D7 DE 90 8F 2D 89 AD D1 25 AA 2E 77 16 EA 2C 9A D6 A7 4A AE 64
    EA 98 B2 3E 63 C9 5A CB A2 56 10 0F E4 03 80 BB 45 16 0B EE 04 61 BF 2C
    76 0B 4B 41 CB C0 E5 CC 83 03 3C 1E BB 47 63 65 82 FF 87 E1 62 55 1C 74
    B9 29 47 25 A3 EA 03 0F 8A 07 85 F3 62 D2 FC ED DA AF 11 47 D4 2F 6E D7
    58 9A 69 26 C4 87 3A 7D 29 E4 F0 04 74 CF C4 4A 16 CE F2 1B 44 88 1F D0
    FF 47 B6 27 2E 64 65 63 6F 64 65 28 27 7A 69 70 27 29
    """
    
    with open('life.py', 'wb') as f:
        f.write(''.join(chr(int(i, 16)) for i in s.split()))
    

    这样的结果是一个有效的 210 个字符的 Python 源文件。我在这里所做的只是对原始 Python 源代码使用 zip 压缩。真正的欺骗是我在结果字符串中使用了非 ASCII 字符。它仍然是有效的代码,只是很麻烦。

    未压缩的版本有 234 个字符,我认为这仍然是可观的。

    import sys
    f,f,n=sys.argv
    e=open(f).readlines()
    p=range
    for v in p(int(n)):e=[''.join('.X'[8+16*(e[t][i]!='.')>>sum(n!='.'for v in e[t-1:t+2]for n in v[i-1:i+2])&1]for i in p(80))for t in p(40)]
    open('out.txt','w').write('\n'.join(e))
    

    对不起,水平滚动,但上面的所有换行符都是必需的,我把它们都算作一个字符。

    我不会尝试阅读打高尔夫球的代码。随机选择变量名称以实现最佳压缩。是的,我是认真的。以下是格式更好且注释更好的版本:

    # get command-line arguments: infile and count
    import sys
    ignored, infile, count = sys.argv
    
    # read the input into a list (each input line is a string in the list)
    data = open(infile).readlines()
    
    # loop the number of times requested on the command line
    for loop in range(int(count)):
        # this monstrosity applies the rules for each iteration, replacing
        # the cell data with the next generation
        data = [''.join(
    
                    # choose the next generation's cell from '.' for
                    # dead, or 'X' for alive
                    '.X'[
    
                        # here, we build a simple bitmask that implements
                        # the generational rules.  A bit from this integer
                        # will be chosen by the count of live cells in
                        # the 3x3 grid surrounding the current cell.
                        #
                        # if the current cell is dead, this bitmask will
                        # be 8 (0b0000001000).  Since only bit 3 is set,
                        # the next-generation cell will only be alive if
                        # there are exactly 3 living neighbors in this
                        # generation.
                        #
                        # if the current cell is alive, the bitmask will
                        # be 24 (8 + 16, 0b0000011000).  Since both bits
                        # 3 and 4 are set, this cell will survive if there
                        # are either 3 or 4 living cells in its neighborhood,
                        # including itself
                        8 + 16 * (data[y][x] != '.')
    
                        # shift the relevant bit into position
                        >>
    
                        # by the count of living cells in the 3x3 grid
                        sum(character != '.' # booleans will convert to 0 or 1
                            for row in data[y - 1 : y + 2]
                            for character in row[x - 1 : x + 2]
                        )
    
                        # select the relevant bit
                        & 1
                    ]
    
                   # for each column and row
                    for x in range(80)
                )
                for y in range(40)
        ]
    
    # write the results out
    open('out.txt','w').write('\n'.join(data))
    

    对于 C-ish 括号格式,抱歉,Pythonistas,但我试图弄清楚每个括号关闭的内容。

    【讨论】:

    • open(f).readlines() 应设为list(open(f))。等效,缩小了 6 个字符,压缩了 3 个字节,奇怪的是,在 EOF 处使用 EOL 压缩了 4 个字符,这使其成为 206(使用 EOL 压缩)和 228(没有 EOL 压缩)。
    【解决方案7】:

    Haskell - 284 272 232 个字符

    import System
    main=do f:n:_<-getArgs;s<-readFile f;writeFile"out.txt"$t s$read n
    p '\n'_='\n'
    p 'X'2='X'
    p _ 3='X'
    p _ _='.'
    t r 0=r
    t r n=t[p(r!!m)$sum[1|d<-1:[80..82],s<-[1,-1],-m<=d*s,m+d*s<3240,'X'==r!!(m+d*s)]|m<-[0..3239]]$n-1
    

    【讨论】:

      【解决方案8】:

      F#, 496

      我可以减少很多,但我喜欢这个,因为它仍然在球场上并且可读性很好。

      open System.IO
      let mutable a:_[,]=null
      let N y x=
       [-1,-1;-1,0;-1,1;0,-1;0,1;1,-1;1,0;1,1]
       |>Seq.sumBy(fun(i,j)->try if a.[y+i,x+j]='X' then 1 else 0 with _->0)
      [<EntryPoint>]
      let M(r)=
       let b=File.ReadAllLines(r.[0])
       a<-Array2D.init 40 80(fun y x->b.[y].[x])
       for i=1 to int r.[1] do 
        a<-Array2D.init 40 80(fun y x->
         match N y x with|3->'X'|2 when a.[y,x]='X'->'X'|_->'.')
       File.WriteAllLines("out.txt",Array.init 40(fun y->
        System.String(Array.init 80(fun x->a.[y,x]))))
       0
      

      编辑

      428

      根据要求,这是我的下一个刺:

      open System
      let mutable a,k=null,Array2D.init 40 80
      [<EntryPoint>]
      let M r=
       a<-k(fun y x->IO.File.ReadAllLines(r.[0]).[y].[x])
       for i=1 to int r.[1] do a<-k(fun y x->match Seq.sumBy(fun(i,j)->try if a.[y+i,x+j]='X'then 1 else 0 with _->0)[-1,-1;-1,0;-1,1;0,-1;0,1;1,-1;1,0;1,1]with|3->'X'|2 when a.[y,x]='X'->'X'|_->'.')
       IO.File.WriteAllLines("out.txt",Array.init 40(fun y->String(Array.init 80(fun x->a.[y,x]))))
       0
      

      在一些基本的高尔夫球运动中减少了 14%。我不禁觉得使用 2D 数组/字符串数组而不是 1D 数组正在失败,但现在不想进行这种转换。请注意我如何优雅地读取文件 3200 次来初始化我的数组 :)

      【讨论】:

      • 请减少很多,我很好奇!
      【解决方案9】:

      Ruby 1.8:178 175 个字符

      f,n=$*;b=IO.read f
      n.to_i.times{s=b.dup
      s.size.times{|i|t=([82,1,-80].map{|o|b[i-o,3]||''}*'').count 'X'
      s[i]=t==3||b[i]-t==?T??X:?.if s[i]>13};b=s}
      File.new('out.txt','w')<<b
      

      换行符很重要(尽管都可以用分号替换。)

      编辑:修复了换行问题,并修剪了 3 个字符。

      【讨论】:

      • 输出文件中的行似乎没有分开。
      • 它们不是 - 但它们在我的 80 字符控制台中完美显示。
      • 你需要有换行符;很抱歉没有明确指出这一点。
      【解决方案10】:

      Java,441... 346


      • 更新 1 删除了内部 if 和更多的丑陋
      • 更新 2 修复了一个错误并获得了一个角色
      • 更新 3 使用更多内存和数组,同时忽略一些边界问题。可能可以保存几个字符。
      • 更新 4 保存了一些字符。感谢 BalusC。
      • 更新 5 进行了一些小改动,使其低于 400 并使其更加丑陋。
      • 更新 6 现在事情如此硬编码,不妨一口气读入确切的数量。再加上一些节省。
      • 更新 7 将写入链接到文件以保存字符。加上一些奇怪的位。

      只是在玩 BalusC 的解决方案。声誉有限意味着我无法在他的评论中添加任何内容。

      class M{public static void main(String[]a)throws Exception{int t=3240,j=t,i=new Integer(a[1])*t+t;char[]b=new char[i+t],p={1,80,81,82};for(new java.io.FileReader(a[0]).read(b,t,t);j<i;){char c=b[j],l=0;for(int n:p)l+=b[j+n]/88+b[j-n]/88;b[j+++t]=c>10?(l==3|l+c==90?88:'.'):c;}new java.io.FileWriter("out.txt").append(new String(b,j,t)).close();}}
      

      更具可读性(?)版本:

      class M{
       public static void main(String[]a)throws Exception{
        int t=3240,j=t,i=new Integer(a[1])*t+t;
        char[]b=new char[i+t],p={1,80,81,82};
        for(new java.io.FileReader(a[0]).read(b,t,t);j<i;){
          char c=b[j],l=0;
          for(int n:p)l+=b[j+n]/88+b[j-n]/88;
          b[j+++t]=c>10?(l==3|l+c==90?88:'.'):c;
        }
        new java.io.FileWriter("out.txt").append(new String(b,j,t)).close();
       }
      }
      

      【讨论】:

      • String 而不是 char[] 更贵,但这在代码高尔夫中并不重要!不错的一个:)
      • 请注意,文件/字符的总长度不是 2754 个字符。
      • @BallusC 谢谢,我设法只复制了 34 行而不是全部 40 行!
      • 这确实是一个真正的记忆猪!顺便说一句,--i 可以进入 new char[i--*t]b[l++]+=(char)j 可以只是 b[l++]=(char)j。这又节省了 3 个字符。
      • 顺便说一句:你为​​什么删除&amp;n+j&lt;s?当输入文件实际上是 3240 个字符长时,这将导致 AIOBE。更多优化:看看我是怎么把文件读成char[]的,你的可以换成while(l&lt;t)b[l++]=(char)r.read();,节省4个字符。
      【解决方案11】:

      Scala - 467 364 339 个字符

      object G{def main(a:Array[String]){val l=io.Source.fromFile(new java.io.File(a(0)))getLines("\n")map(_.toSeq)toSeq
      val f=new java.io.FileWriter("out.txt")
      f.write((1 to a(1).toInt).foldLeft(l){(t,_)=>(for(y<-0 to 39)yield(for(x<-0 to 79)yield{if(x%79==0|y%39==0)'.'else{val m=t(y-1)
      val p=t(y+1);val s=Seq(m(x-1),m(x),m(x+1),t(y)(x-1),t(y)(x+1),p(x-1),p(x),p(x+1)).count('X'==_)
      if(s==3|(s==2&t(y)(x)=='X'))'X'else'.'}})toSeq)toSeq}map(_.mkString)mkString("\n"))
      f.close}}
      

      我认为还有很大的改进空间......

      [编辑]是的,就是:

      object G{def main(a:Array[String]){var l=io.Source.fromFile(new java.io.File(a(0))).mkString
      val f=new java.io.FileWriter("out.txt")
      var i=a(1).toInt
      while(i>0){l=l.zipWithIndex.map{case(c,n)=>if(c=='\n')'\n'else{val s=Seq(-83,-82,-81,-1,1,81,82,83).map(_+n).filter(k=>k>=0&k<l.size).count(l(_)=='X')
      if(s==3|(s==2&c=='X'))'X'else'.'}}.mkString
      i-=1}
      f.write(l)
      f.close}}
      

      [编辑]而且我觉得还有更多的东西要挤出来……

      object G{def main(a:Array[String]){val f=new java.io.FileWriter("out.txt")
      f.write(((1 to a(1).toInt):\(io.Source.fromFile(new java.io.File(a(0))).mkString)){(_,m)=>m.zipWithIndex.map{case(c,n)=>
      val s=Seq(-83,-82,-81,-1,1,81,82,83)count(k=>k+n>=0&k+n<m.size&&m(k+n)=='X')
      if(c=='\n')c else if(s==3|s==2&c=='X')'X'else'.'}.mkString})
      f.close}}
      

      【讨论】:

      • 你让我阅读了 Scala *的文章。多么美丽的语言! :)
      • 是的。它改变了我的生活。
      【解决方案12】:

      以下解决方案使用我自己的自定义领域特定编程语言,我称之为 NULL:

      3499538
      

      如果您想知道这是如何工作的:我的语言每个程序仅包含一个语句。该语句表示属于代码高尔夫线程的 * 线程 ID。我的编译器将它编译成一个程序,该程序会寻找最好的 javascript 解决方案(使用 SO API),下载它并在 Web 浏览器中运行它。

      运行时对于新线程可能会更好(可能需要一些时间才能出现第一个支持的 Javascript 答案),但从好的方面来说,它只需要很少的编码技能。

      【讨论】:

      • @Platinum Azure:你的意思是其他人之前有这个想法?老实说,我没有在另一个线程中看到它。
      • 好吧,我想伟大的思想都一样;-)。但与上面的解决方案相比,我的解决方案实际上可以解决几乎所有代码高尔夫挑战,而上面的解决方案只能打印“Hello World”。
      • 它不是图灵完备的,它无法解释抽象代码。它不一定每次都有效,因为可能永远不会有有效的(javascript)解决方案。它不应该出现在 Code Golf 上。
      • 嘿,那只是我的翻译。 Javascript 解决方案是否包括 javascript 引擎的字符数? ;-)
      • 在我读完所有严肃的 cmets 之前,我还以为这是个玩笑。
      【解决方案13】:

      Javascript/Node.js - 233 个 236 个字符

      a=process.argv
      f=require('fs')
      m=46
      t=f.readFileSync(a[2])
      while(a[3]--)t=[].map.call(t,function(c,i){for(n=g=0;e=[-82,-81,-80,-1,1,80,81,82][g++];)t[i+e]>m&&n++
      return c<m?c:c==m&&n==3||c>m&&n>1&&n<4?88:m})
      f.writeFile('out.txt',t)
      

      【讨论】:

        【解决方案14】:

        C - 300


        只是想知道我的 java 解决方案在 C 中可以变得更小更丑。减少到 300,包括预处理器位的换行符。将内存释放给操作系统!假设操作系统也将关闭并刷新文件,可以节省约 20 个。

        #include<stdio.h>
        #include<stdlib.h>
        #define A(N)j[-N]/88+j[N]/88
        
        int main(int l,char**a){
          int t=3240,i=atoi(a[2])*t+t;
          char*b=malloc(i+t),*j;
          FILE*f;
          fread(j=b+t,1,t,fopen(a[1],"r"));
          for(;j-b-i;j++[t]=*j>10?l==3|l+*j==90?88:46:10)
              l=A(1)+A(80)+A(81)+A(82);
          fwrite(j,1,t,f=fopen("out.txt","w"));
          fclose(f);
        }
        

        【讨论】:

          【解决方案15】:

          MUMPS:314 个字符

          L(F,N,R=40,C=80)
              N (F,N,R,C)
              O F:"RS" U F D  C F
              .F I=1:1:R R L F J=1:1:C S G(0,I,J)=($E(L,J)="X")
              F A=0:1:N-1 F I=1:1:R F J=1:1:C D  S G(A+1,I,J)=$S(X=2:G(A,I,J),X=3:1,1:0)
              .S X=0 F i=-1:1:1 F j=-1:1:1 I i!j S X=X+$G(G(A,I+i,J+j))
              S F="OUT.TXT" O F:"WNS" U F D  C F
              .F I=1:1:R F J=1:1:C W $S(G(N,I,J):"X",1:".") W:J=C !
              Q
          

          【讨论】:

          • 那是一种可怕的语言。不错的字符数。
          【解决方案16】:

          Java, 556 532 517 496 472 433 428 420 418 381 个字符


          • 更新 1:将第一个 StringBuffer 替换为 Appendable,将第二个替换为 char[]。保存了 24 个字符。

          • 更新 2: 找到了一种将文件读入 char[] 的更短方法。节省了 15 个字符。

          • 更新 3:if/else 替换为 ?: 并合并 char[]int 声明。保存了 21 个字符。

          • 更新 4:(int)f.length()c.length 替换为 s。保存了 24 个字符。

          • 更新 5: 根据 Molehill 的提示进行了改进。主要是对字符长度进行硬编码,以便我可以摆脱File。节省了 39 个字符。

          • 更新 6: 次要重构。节省了 6 个字符。

          • 更新 7:Integer#valueOf() 替换为 new Integer() 并重构 for 循环。保存了 8 个字符。

          • 更新 8: 改进了邻居计算。保存 2 个字符。

          • 更新 9: 优化文件读取,因为文件长度已经被硬编码。节省了 37 个字符。


           import java.io.*;class L{public static void main(String[]a)throws Exception{int i=new Integer(a[1]),j,l,s=3240;int[]p={-82,-81,-80,-1,1,80,81,82};char[]o,c=new char[s];for(new FileReader(a[0]).read(c);i-->0;c=o)for(o=new char[j=s];j-->0;){l=0;for(int n:p)l+=n+j>-1&n+j<s?c[n+j]/88:0;o[j]=c[j]>13?l==3|l+c[j]==90?88:'.':10;}Writer w=new FileWriter("out.txt");w.write(c);w.close();}}
          

          更易读的版本:

          import java.io.*;
          class L{
           public static void main(String[]a)throws Exception{
            int i=new Integer(a[1]),j,l,s=3240;
            int[]p={-82,-81,-80,-1,1,80,81,82};
            char[]o,c=new char[s];
            for(new FileReader(a[0]).read(c);i-->0;c=o)for(o=new char[j=s];j-->0;){
             l=0;for(int n:p)l+=n+j>-1&n+j<s?c[n+j]/88:0;
             o[j]=c[j]>10?l==3|l+c[j]==90?88:'.':10;
            }
            Writer w=new FileWriter("out.txt");w.write(c);w.close();
           }
          }
          

          写入后关闭是绝对强制的,否则文件为空。否则它会再节省 21 个字符。

          此外,当我使用 46 而不是 '.' 时,我还可以再保存一个字符,但 javac 和 Eclipse 都会出现编译错误可能会丢失精度。奇怪的东西。


          注意:这需要一个带有 \n 换行符的输入文件,而不是 Windows 默认使用的 \r\n

          【讨论】:

          • 你可以用 new FileWriter(out.txt).write(c) 说几个字符。不幸的是,您不能丢弃整个变量,因为 write() 不会返回这个。如果你能找到一个文件写入类,可以节省大量资金。另外,我喜欢你使用 throws 来避免那些可怕的强制接球。
          【解决方案17】:

          PHP - 365 328 322 个字符。


          list(,$n,$l) = $_SERVER["argv"];
          $f = file( $n );
          for($j=0;$j<$l;$j++){   
              foreach($f as $k=>$v){  
                  $a[$k]="";      
                  for($i=0;$i < strlen( $v );$i++ ){
                      $t = 0;
                      for($m=-1;$m<2;$m++){
                          for($h=-1;$h<2;$h++){
                              $t+=ord($f[$k + $m][$i + $h]);
                          }
                      }
                      $t-=ord($v[$i]);          
                      $a[$k] .= ( $t == 494 || ($t == 452 && ord($v[$i])==88)) ?  "X" : "." ;
                  }
              }
              $f = $a;
          }       
          file_put_contents("out.txt", implode("\n", $a )); 
          

          我确信这可以改进,但我很好奇它在 PHP 中会是什么样子。也许这会激励那些有更多代码高尔夫经验的人。

          • 更新对两个 args 使用 list() 而不是 $var = $_SERVER["argv"]。 不错的一个唐
          • 更新 += 和 -= 这个让我 /facepalm 不敢相信我错过了它
          • 更新文件输出以使用 file_put_contents() Don 的另一个好方法
          • 更新删除了未使用的变量 $q 和 $w 的初始化

          【讨论】:

          • list($n,$l) = $_SERVER['argv'];
          • 更改:$o= fopen ("out.txt", "w"); fwrite($o, 内爆("\n", $a)); fclose ($o); TO:file_put_contents("out.txt", implode("\n",$a));
          • 更改:$t=$t-ord($v[$i]); TO:$t-=ord($v[$i]);
          • 更改:$t=$t+ord($f[$k + $m][$i + $h]); TO $t+=ord($f[$k + $m][$i + $h]);
          【解决方案18】:

          R 340 个字符

          cgc<-function(i="in.txt",x=100){
              require(simecol)
              z<-file("in.txt", "rb")
              y<-matrix(data=NA,nrow=40,ncol=80)
              for(i in seq(40)){
                  for(j in seq(80)){
                      y[i,j]<-ifelse(readChar(z,1) == "X",1,0)
                  }
                  readChar(z,3)
              }
              close(z)
              init(conway) <- y
              times(conway)<-1:x
              o<-as.data.frame(out(sim(conway))[[100]])
              write.table(o, "out.txt", sep="", row.names=FALSE, col.names=FALSE)
          }
          cgc()
          

          我觉得添加一个为您执行实际自动机的附加程序包有点作弊,但我会继续使用它,因为我仍然不得不在文件中使用“X”来读取矩阵和东西1 个。

          这是我的第一个“代码高尔夫”,很有趣....

          【讨论】:

            【解决方案19】:

            c++ - 492 454 386


            我的第一个代码高尔夫;)

            #include<fstream>
            #define B(i,j)(b[i][j]=='X')
            int main(int i,char**v){for(int n=0;n<atoi(v[2]);++n){std::ifstream f(v[1]);v[1]="out.txt";char b[40][83];for(i=0;i<40;++i)f.getline(b[i],83);std::ofstream g("out.txt");g<<b[0]<<'\n';for(i=1;i<39;++i){g<<'.';for(int j=1;j<79;++j){int k=B(i-1,j)+B(i+1,j)+B(i,j-1)+B(i,j+1)+B(i-1,j-1)+B(i+1,j+1)+B(i+1,j-1)+B(i-1,j+1);(B(i,j)&&(k<2||k>3))?g<<'.':(!B(i,j)&&k==3)?g<<'X':g<<b[i][j];}g<<".\n";}g<<b[0]<<'\n';}}
            

            稍微修改过的版本,用表格查找替换了一些逻辑+一些其他小技巧:

            #include<fstream>
            #define B(x,y)(b[i+x][j+y]=='X')
            int main(int i,char**v){for(int n=0;n<atoi(v[2]);++n){std::ifstream f(v[1]);*v="out.txt";char b[40][83], O[]="...X.....";for(i=0;i<40;++i)f>>b[i];std::ofstream g(*v);g<<b[0]<<'\n';for(i=1;i<39;++i){g<<'.';for(int j=1;j<79;++j){O[2]=b[i][j];g<<O[B(-1,0)+B(1,0)+B(0,-1)+B(0,1)+B(-1,-1)+B(1,1)+B(1,-1)+B(-1,1)];}g<<".\n";}g<<b[0]<<'\n';}}
            

            【讨论】:

            • 一些提示:你不需要调用 main argc 和 argv 的参数。请尝试使用 c 和 v。还可以尝试使用三元运算符而不是 if/else。很高兴看到 C++ 的代表。 :)
            【解决方案20】:

            Perl – 214 个字符

            什么,还没有 perl 条目?

            $i=pop;@c=<>;@c=map{$r=$_;$u='';for(0..79)
            {$K=$_-1;$R=$r-1;$u.=((&N.(&N^"\0\W\0").&N)=~y/X//
            |(substr$c[$r],$_,1)eq'X')==3?'X':'.';}$u}keys@c for(1..$i);
            sub N{substr$c[$R++],$K,3}open P,'>','out.txt';$,=$/;print P@c
            

            运行:

            conway.pl infile #times

            【讨论】:

              【解决方案21】:

              另一个 Java 尝试,361 字符

              class L{public static void main(final String[]a)throws Exception{new java.io.RandomAccessFile("out.txt","rw"){{int e=88,p[]={-1,1,-80,80,-81,81,-82,82},s=3240,l=0,i=new Byte(a[1])*s+s,c;char[]b=new char[s];for(new java.io.FileReader(a[0]).read(b);i>0;seek(l=++l%s),i--){c=b[l];for(int n:p)c+=l+n>=0&l+n<s?b[l+n]/e:0;write(c>13?(c==49|(c|1)==91?e:46):10);}}};}}
              

              还有一点可读性

              class L {
                  public static void main(final String[]a) throws Exception {
                      new java.io.RandomAccessFile("out.txt","rw"){{
                          int e=88, p[]={-1,1,-80,80,-81,81,-82,82},s=3240,l=0,i=new Byte(a[1])*s+s,c;
                          char[] b = new char[s];
                          for (new java.io.FileReader(a[0]).read(b);i>0;seek(l=++l%s),i--) {
                              c=b[l];
                              for (int n:p)
                                  c+=l+n>=0&l+n<s?b[l+n]/e:0;
                              write(c>13?(c==49|(c|1)==91?e:46):10);
                          }
                      }};
                  }
              }
              

              与 Molehill 的版本非常相似。我尝试使用不同的 FileWriter 并在没有附加变量的情况下计算单元格的邻居。 不幸的是,RandomAccessFile 是一个很长的名称,需要您传递文件访问模式。

              【讨论】:

                【解决方案22】:

                RUST - 469 个字符 不知道我是否应该在此处发布此帖子(此帖子已有 3 年历史),但无论如何,我在 rust (0.9) 中尝试一下:

                use std::io::fs::File;fn main(){
                let mut c=File::open(&Path::new(std::os::args()[1])).read_to_end();
                for _ in range(0,from_str::<int>(std::os::args()[2]).unwrap()){
                let mut b=c.clone();for y in range(0,40){for x in range(0,80){let mut s=0;
                for z in range(x-1,x+2){for t in range(y-1,y+2){
                if z>=0&&t>=0&&z<80&&t<40&&(x !=z||y !=t)&&c[t*81+z]==88u8{s +=1;}}}
                b[y*81+x]=if s==3||(s==2&&c[y*81+x]==88u8){88u8} else {46u8};}}c = b;}
                File::create(&Path::new("out.txt")).write(c);}
                

                对于感兴趣的人,这里是一些激进的打高尔夫球之前的代码:

                use std::io::fs::File;
                fn main() {
                    let f = std::os::args()[1];
                    let mut c = File::open(&Path::new(f)).read_to_end();    
                    let n = from_str::<int>(std::os::args()[2]).unwrap();   
                    for _ in range(0,n)
                    {
                        let mut new = c.clone();
                        for y in range(0,40) {
                            for x in range(0,80) {
                                let mut sum = 0;
                                for xx in range(x-1,x+2){
                                    for yy in range(y-1,y+2) {
                                        if xx >= 0 && yy >= 0 && xx <80 && yy <40 && (x != xx || y != yy) && c[yy*81+xx] == 88u8
                                        { sum = sum + 1; }
                                    }
                                }
                                new[y*81+x] = if sum == 3 || (sum == 2 && c[y*81+x] == 88u8) {88u8} else {46u8};                    
                            }
                        }
                        c = new;
                    }
                    File::create(&Path::new("out.txt")).write(c);
                }
                

                【讨论】:

                  【解决方案23】:

                  瞧瞧 你可能想使用这个 html 文件。没有文件输入,而是一个可以完成工作的文本区域! 还有一些html和initialization和vars。主程序只有 235 个字符。 这是手工缩小的 JS。

                  <!DOCTYPE html>
                  <html><body><textarea id="t" style="width:600px;height:600px;font-family:Courier">
                  </textarea></body><script type="text/javascript">var o,c,m=new Array(3200),
                  k=new Array(3200),y,v,l,p;o=document.getElementById("t");for(y=0;y<3200;y++)
                  {m[y]=Math.random()<0.5;}setInterval(function(){p="";for(y=0;y<3200;y++){c=0;
                  for(v=-1;v<2;v+=2){c+=m[y-1*v]?1:0;for(l=79;l<82;l++)c+=m[y-l*v]?1:0;}
                  k[y]=c==3||m[y]&&c==2;}p="";for(y=0;y<3200;y++){p+=(y>0&&y%80==0)?"\n":"";
                  m[y]=k[y];p+=(m[y]?"O":"-");}o.innerHTML=p;},100);</script></html>
                  

                  【讨论】:

                    【解决方案24】:

                    经典模式之一

                    ***
                    ..*
                    .*
                    

                    我的头像是使用我的生命游戏版本使用此模式和规则创建的(请注意,它不是 23/3):

                    #D Thanks to my daughter Natalie
                    #D Try at cell size of 1
                    #R 8/1
                    #P -29 -29
                    .*********************************************************
                    *.*******************************************************.*
                    **.*****************************************************.**
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ****************************.*.****************************
                    ***********************************************************
                    ****************************.*.****************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    ***********************************************************
                    **.*****************************************************.**
                    *.*******************************************************.*
                    .*********************************************************
                    

                    恕我直言 - 当我学习康威的生命游戏时,诀窍不是编写短代码,而是可以快速完成复杂生命形式的代码。使用上面的经典模式和 594,441 个单元的包裹世界,我能做到的最好的结果是大约 1,000 代/秒。

                    另一个简单的模式

                    **********
                    .
                    ................*
                    .................**
                    ................**.......**********
                    

                    还有滑翔机

                    ........................*...........
                    ......................*.*...........
                    ............**......**............**
                    ...........*...*....**............**
                    **........*.....*...**..............
                    **........*...*.**....*.*...........
                    ..........*.....*.......*...........
                    ...........*...*....................
                    ............**......................
                    

                    【讨论】:

                    • 我想你可能误解了代码高尔夫问题的意义。
                    • 这里是一组模式,以防你像我几年前一样上瘾argentum.freeserve.co.uk/lex.htm
                    • @gnovice - 不,但这是一个让我很开心的话题。元胞自动机可能是一个有趣的最短代码问题,但它本身也是一个有趣的话题。我现在就打。
                    • 如果您有使用此处未介绍的语言的经验,我鼓励您提交代码高尔夫条目 - 所有内容都值得赞赏,即使它在长度方面落后于其他语言。 :)
                    • 仅自动机代码就将近 2000 行。绘图/编辑(图形)/图案文件处理可能超过 2000 个。所以我想我的回合会超过标准杆;)