人生の最短ゲーム


59

ConwayのGame of Lifeは、セルラーオートメーションの典型的な例です。セルは正方形のグリッドを形成し、それぞれに2つの状態があります:生きているか死んでいます。各ターンで、各セルは、その状態とその8つの隣人の状態に従って同時に更新します。

  • 生きているセルは、正確に2つまたは3つのライブネイバーがある場合、生きたままです。
  • 死んだ細胞は、生きている隣人がちょうど3人いる場合に生きます

あなたの使命は、あなたがそれを受け入れることを選択した場合、お気に入りの言語で最短のGame of Life実装をコーディングすることです。

ルール:

  • グリッドは少なくとも20x20でなければなりません
  • グリッドはラップアラウンドする必要があります(グリッドはトーラスの表面のようになります)
  • 実装では、ユーザーが独自の開始パターンを入力できるようにする必要があります
  • GoLは、何が起こっているのかわからなければ少し無意味です。そのため、各ターンの結果が表示されるまで表示されるオートマトンの視覚的な出力が必要です。

8
以前はStack Overflow:Code Golf:ConwayのGame of Lifeで、コメントのAPL実装リンクを確認してください。
-dmckee

1
ああ、私はそれを見ませんでした。しかし、これはわずかに異なります(チャレンジをまとめる作業を削除してください?
グリフィン

6
問題じゃない。Stack Overflowで既に実行されている多くのパズルもここで行われていますが、人々は、同様の課題へのリンクに執着していると言うでしょう。
dmckee

@Griffin:sの;前にあるものをすべて削除でき}ます。また、varsを時々削除することもできます(コードを壊さない場合)。また、1行forifsなどでは、{ }完全に削除できますfor(...) for(...) dosomething()
pimvdb

@pimvdb、乾杯、まだ完全にゴルフをしていない、時間がなかった。ぼんやりとチャレンジを設定するのではなく、私もやりたかったことを示したかっただけです。すぐに最大にゴルフします。
グリフィン

回答:


27

JavaScriptを使用したHTML5 Canvas、940 639 586 519文字

<html><body onload="k=40;g=10;b=[];setInterval(function(){c=[];for(y=k*k;y--;){n=0;for(f=9;f--;)n+=b[(~~(y/k)+k+f%3-1)%k*k+(y+k+~~(f/3)-1)%k];c[y]=n==3||n-b[y]==3;r.fillStyle=b[y]?'red':'tan';r.fillRect(y%k*g,~~(y/k)*g,g-1,g-1)}if(v.nextSibling.checked)b=c},1);v=document.body.firstChild;v.width=v.height=g*k;v.addEventListener('click',function(e){b[~~((e.pageY-v.offsetTop)/g)*k+~~((e.pageX-v.offsetLeft)/g)]^=1},0);r=v.getContext('2d');for(y=k*k;y--;)b[y]=0"><canvas></canvas><input type="checkbox"/>Run</body></html>

私はいつもキャンバスで何かをしたかったので、ここに私の試みがあります(元のバージョンはオンラインです)。クリックしてセルを切り替えることができます(実行モードでも可能)。

ここで新しいバージョンを試すこともできます

残念ながら、まだ回避できない問題があります。jsFiddleはテキストノードをキャンバスの直前に配置するため(なぜ?)、オンラインバージョンは11文字長くなり、キャンバスは最初の子ではなくなります。

編集1:最適化と再構築の多く。

編集2:いくつかの小さな変更。

編集3:完全なスクリプトブロックと小さな変更をインライン化しました。


良いですが、間隔の遅延を変更して、1その遅いステップではなく、私のものと同じ速さにします。また、(各正方形をクリックするのではなく)描画を実装する場合、マウスの位置を最も近いブロックサイズに丸めて、そのポイントで長方形を塗りつぶすことができます。より多くのキャラクターがより多くのポイント。
グリフィン

あなたは置き換えることができnew Array('#FFF','#800')['#FFF','#800']
ロージャッカー

ドローイングについては言っているが、私のスーパーゴルフはドローイングを許可せず、罪のようにugい。ハハ。あなたにはあなたの2色を設定することができますsに配列tanし、red彼らが最も短い表現を持つ2つの色であることから-あなたの2つの文字が保存されます。また、可能であれば、のリテラルバージョンをj間隔に入れます。絞り出すことはもっとたくさんあると確信しています。
グリフィン

@Griffin and Lowjacker:ありがとうございます。また、これ以上のゴルフができると確信しています(すでにいくつかのアイデアがあります)。残念ながら、そうする時間を見つけられませんでした。より良いゴルフバージョンが明日続く-私は願っています
ハワード

2
htmlタグとbodyタグを削除できます。同じように機能します
アロデボー

32

Python、219文字

私は質問を満足させるのにちょうど十分なインターフェースで、最大限のゴルフに出かけました。

import time
P=input()
N=range(20)
while 1:
 for i in N:print''.join(' *'[i*20+j in P]for j in N)
 time.sleep(.1);Q=[(p+d)%400 for d in(-21,-20,-19,-1,1,19,20,21)for p in P];P=set(p for p in Q if 2-(p in P)<Q.count(p)<4)

次のように実行します。

echo "[8,29,47,48,49]" | ./life.py

リスト内の数字は、開始セルの座標を表します。最初の行は0〜19、2番目の行は20〜39などです。

21行のターミナルで実行すると、かなりおしゃれです。


1
これは完全に勝ったはずです。「入力のしやすさ」はかなり高く重み付けされていたと思います。
プリモ

@primo私は、mmaが別の競争をするべきだと示唆するところまで行きたいです。
luserのドローグ

2
では、このLife of Pyはどうですか?
クリストファーワート

いつでも別の文字を保存できます... 2-(p in P)== 2-({p}<P)。ただし、入力を次のように変更する必要があります{8,29,47,48,49}:)
JBernardo

21

TI-BASIC、96バイト(競合しないエントリの場合は87)

TI-84シリーズグラフ電卓(!)用。バッファリンググラフィックス・ルーチン(内蔵間違いなく何を)書くための簡単な方法がないので、これは、かなりの挑戦だった、とグラフ画面は4つしか関連するグラフィックスコマンドを持っていますPxl-On()Pxl-Off()Pxl-Change()、とpxl-Test()

画面上のアクセス可能なすべてのピクセルを使用し、正しくラップします。各セルは1ピクセルであり、プログラムは画面を横切って水平方向に1行ずつ水平に更新します。電卓には15MHzのz80プロセッサしか搭載されておらず、BASICは低速の解釈言語であるため、コードは約5分ごとに1フレームしか取得しません。

ユーザー入力は簡単です。プログラムを実行する前に、ペンツールを使用してグラフ画面に図形を描画します。

私のエントリーから電卓フォーラムOmnimagaでのコードゴルフコンテストに適応しました

0
While 1
For(X,0,94
Ans/7+49seq(pxl-Test(remainder(Y,63),remainder(X+1,95)),Y,62,123
For(Y,0,62
If 1=pxl-Test(Y,X)+int(3fPart(3cosh(fPart(6ֿ¹iPart(sum(Ans,Y+1,Y+3
Pxl-Change(Y,X
End
End
End

Omnimagaバージョン(87バイト)

このコードには追加機能があります:初めて実行されているかどうかを検出し、画面の状態をランダム化します。後続の実行では、フレームの終了後に停止すると、シミュレーションが自動的に続行されます。ただし、画面をラップしないため、競合するエントリではありません。グラフ画面が事前にクリアされている場合、外側の境界上のセルは常に無効と見なされます。

0
While 1
For(X,0,93
Ans/7+49seq(pxl-Test(Y,X+1),Y,0,62
For(Y,1,61
If 2rand>isClockOn=pxl-Test(Y,X)+int(3fPart(3cosh(fPart(6ֿ¹iPart(sum(Ans,Y,Y+2
Pxl-Change(Y,X
End
End
ClockOff
End

このバージョンは、おそらく私がこれまでに書いた中で最もゴルフされたコードであり、本当に厄介な難読化された最適化が含まれています。

  • クロック状態をフラグとして使用します。プログラムの開始時に、日付/時刻クロックが有効になり、グローバルisClockOnフラグの値を使用して、それが最初の反復かどうかを判断します。最初のフレームが描画された後、クロックをオフにします。他の最短の方法で1バイト、明白な方法で約4バイト節約します。

  • 更新される列の隣にある3つの列の状態を、7を基数とする63要素の配列に格納します。49の場所は列を右に保持し、7の場所は中央の列を保持し、ユニットの場所は左の列を保持します。ライブセルの場合は-1、デッドセルの場合は0です。次に、変更中のセルの周りの3つの数値の合計の剰余mod 6を取り、隣接するライブセルの総数を見つけます(9トリックによる割り切れるように、基数7で剰余mod 6は次の合計に等しくなります)数字)。それ自体で約10バイトを節約し、次の2つの最適化を使用する機会を与えます。ダイアグラムの例(Y = 45の特定の列を中心とするグライダーがあるとしましょう:

    Row # | Cell State       | Stored number | Mod 6 = cell count
    ...
    44      Live, Live, Live   49+7+1 = 57     3
    45      Dead, Dead, Live   49+0+0 = 49     1
    46      Dead, Live, Dead   0+7+0  = 7      1
    ...
    

    中央のセルは、正確に5つの生セルに囲まれているため、死んだままになります。

  • 各行が完了すると、既存の数値を7で除算し、小数部分を破棄し、新しい列のセルの値の49倍を加算することにより、配列の数値が更新されます。セルを更新する前に各行のセルの値を保存する必要があるため、毎回3列すべてを保存するのは非常に遅く、エレガントではなく、少なくとも20バイト多く、1つではなく3つのリストを使用します。これは、セルの位置を保存する最も小さな方法です。

  • スニペットint(3fPart(3cosh(1、入力が3/6に等しいとき、24/6 0に等しいとき、および0、1 / 6、2 / 6、または5/6に等しいときを示します。約6バイト節約します。


19

Mathematica-333

特徴:

  • インタラクティブインターフェイス:セルをクリックしてパターンを作成します

  • 素敵なグリッド

  • ボタン:実行、一時停止、クリア

コードは次のとおりです。

Manipulate[x=Switch[run,1,x,2,CellularAutomaton[{224,{2,{{2,2,2},{2,1,2},{2,2,2}}},
{1,1}},x],3,Table[0,{k,40},{j,40}]];EventHandler[Dynamic[tds=Reverse[Transpose[x]];
ArrayPlot[tds,Mesh->True]],{"MouseClicked":>(pos=Ceiling[MousePosition["Graphics"]];
x=ReplacePart[x,pos->1-x[[Sequence@@pos]]];)}],{{run,3,""},{1->"||",2->">",3->"X"}}]

ここに画像の説明を入力してください

これがどのように実行されるかを知りたい場合、このブログの 2番目の例は、上記のコードのより精巧なバージョン(ライブフーリエ解析、より良いインターフェイス)です。プラグインを無料でダウンロードすると、ブラウザでサンプルが実行されます。


2
+1、外出にはうれしい。ええ、それがこのサイトの問題です。見逃しがちな古い質問がたくさんあります。
グリフィン

@Griffinに気付いてくれてありがとう;)
Vitaliy Kaurov

15

C 1063文字

挑戦として、私はリアルタイムIOでゴルフにやさしいWindows APIを使用してCでこれを行いました。capslockがオンの場合、シミュレーションが実行されます。capslockがオフの場合、静止したままになります。マウスでパターンを描きます。左クリックは細胞を復活させ、右クリックは細胞を殺します。

#include <windows.h>
#include<process.h>
#define K ][(x+80)%20+(y+80)%20*20]
#define H R.Event.MouseEvent.dwMousePosition
#define J R.Event.MouseEvent.dwButtonState
HANDLE Q,W;char*E[3],O;Y(x,y){return E[0 K;}U(x,y,l,v){E[l K=v;}I(){E[2]=E[1];E[1]=*E;*E=E[2];memset(E[1],0,400);}A(i,j,k,l,P){while(1){Sleep(16);for(i=0;i<20;++i)for(j=0;j<20;++j){COORD a={i,j};SetConsoleCursorPosition(Q,a);putchar(E[0][i+j*20]==1?'0':' ');}if(O){for(i=0;i<20;++i)for(j=0;j<20;++j){for(k=i-1,P=0;k<i+2;++k)for(l=j-1;l<j+2;++l){P+=Y(k,l);}U(i,j,1,P==3?1:Y(i,j)==1&&P==4?1:0);}I();}}}main(T,x,y,F,D){for(x=0;x<21;++x)puts("#####################");E[0]=malloc(800);E[1]=E[0]+400;I();I();W=GetStdHandle(-10);Q=GetStdHandle(-11);SetConsoleMode(W,24);INPUT_RECORD R;F=D=O=0;COORD size={80,25};SetConsoleScreenBufferSize(Q,size);_beginthread(A,99,0);while(1){ReadConsoleInput(W,&R,1,&T);switch(R.EventType){case 1:O=R.Event.KeyEvent.dwControlKeyState&128;break;case 2:switch(R.Event.MouseEvent.dwEventFlags){case 1:x=H.X;y=H.Y;case 0:F=J&1;D=J&2;}if(F)U(x,y,0,1);if(D)U(x,y,0,0);}}}

コンパイルされたEXEはここにあります

編集:ソースをコメントアップしました。ここから入手できます


これのコメント版が見たいです!
luser droog

1
確かに、私は私が考えていたものを思い出すことができるかどうか... = P
Kaslai

1
@luserdroogここにあるpastebin.com/BrX6wgUj
Kaslai

これは最高です。
rayryeng-モニカの復活

12

J(39文字)

l=:[:+/(3 4=/[:+/(,/,"0/~i:1)|.])*.1,:]

このAPLバージョンに基づいています(同じアルゴリズム、トロイダル畳み込み)。

使用例:

   r =: (i.3 3) e. 1 2 3 5 8
   r
0 1 1          NB. A glider!
1 0 1
0 0 1

   R =: _1 _2 |. 5 7 {. r
   R
0 0 0 0 0 0 0  NB. Test board
0 0 0 1 1 0 0
0 0 1 0 1 0 0
0 0 0 0 1 0 0
0 0 0 0 0 0 0

   l R
0 0 0 0 0 0 0  NB. Single step
0 0 0 1 1 0 0
0 0 0 0 1 1 0
0 0 0 1 0 0 0
0 0 0 0 0 0 0

10

Mathematica、123文字

Mathematicaの組み込みのCellularAutomaton関数を使用しない非常に初歩的な実装。

ListAnimate@NestList[ImageFilter[If[3<=Total@Flatten@#<=3+#[[2]][[2]],1,0]&,#,1]&,Image[Round/@RandomReal[1,{200,200}]],99]

8

Ruby 1.9 + SDL(380 325 314)

編集:314文字、および最初の反復で余分なセルが生きているように見えるバグを修正しました。カラールーチンは最下位の8ビットのみを参照するため、グリッドサイズを56に増やしました。

編集:325文字までゴルフ。グリッドの幅/高さは28になりました。これは、28 * 9が背景色として値を使用している間に最大のサイズになるためです。また、反復ごとに1つのSDLイベントのみを処理するため、内部ループが完全になくなります。かなりきついと思います!

シミュレーションは一時停止し、すべてのセルが停止します。任意のキーを押して一時停止/一時停止解除を切り替え、任意のセルをクリックして生きている状態と死んでいる状態を切り替えることができます。10分の1秒ごとに反復を実行します。

ラッピングは少し不安定です。

require'sdl'
SDL.init W=56
R=0..T=W*W
b=[]
s=SDL::Screen.open S=W*9,S,0,0
loop{r="#{e=SDL::Event.poll}"
r['yU']?$_^=1:r[?Q]?exit: r['nU']?b[e.y/9*W+e.x/9]^=1:0
b=R.map{|i|v=[~W,-W,-55,-1,1,55,W,57].select{|f|b[(i+f)%T]}.size;v==3||v==2&&b[i]}if$_
R.map{|i|s.fillRect i%W*9,i/W*9,9,9,[b[i]?0:S]*3}
s.flip
sleep 0.1}

次のようになります。

動作中のアプリのスクリーンショット

楽しいチャレンジ!誰でも見ることができる改善を歓迎します。


良い試みですが、あなたが間違っていることがすぐにわかります。GoLではそのようなパターンを持つことはできません。別のルールをお読みください:en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
Griffin

@Griffinいくつかのセルを一時停止して手動で切り替えた後にスクリーンショットが撮られたと思います-ただし、ルールをもう一度確認します。ありがとう!
ポール・プレスティッジ

7
@Griffinは、シードパターンをどのような構成にすることもできませんか?
ardnew

7

Scala、1181 1158 1128 1063 1018 1003 999 992 987文字

import swing._
import event._
object L extends SimpleSwingApplication{import java.awt.event._
import javax.swing._
var(w,h,c,d,r)=(20,20,20,0,false)
var x=Array.fill(w,h)(0)
def n(y:Int,z:Int)=for(b<-z-1 to z+1;a<-y-1 to y+1 if(!(a==y&&b==z)))d+=x((a+w)%w)((b+h)%h)
def top=new MainFrame with ActionListener{preferredSize=new Dimension(500,500)
menuBar=new MenuBar{contents+=new Menu("C"){contents+={new MenuItem("Go/Stop"){listenTo(this)
reactions+={case ButtonClicked(c)=>r= !r}}}}}
contents=new Component{listenTo(mouse.clicks)
reactions+={case e:MouseClicked=>var p=e.point
x(p.x/c)(p.y/c)^=1
repaint}
override def paint(g:Graphics2D){for(j<-0 to h-1;i<-0 to w-1){var r=new Rectangle(i*c,j*c,c,c)
x(i)(j)match{case 0=>g draw r
case 1=>g fill r}}}}
def actionPerformed(e:ActionEvent){if(r){var t=x.map(_.clone)
for(j<-0 to h-1;i<-0 to w-1){d=0
n(i,j)
x(i)(j)match{case 0=>if(d==3)t(i)(j)=1
case 1=>if(d<2||d>3)t(i)(j)=0}}
x=t.map(_.clone)
repaint}}
val t=new Timer(200,this)
t.start}}

ゴルフをしていない:

import swing._
import event._

object Life extends SimpleSwingApplication
{
    import java.awt.event._
    import javax.swing._
    var(w,h,c,d,run)=(20,20,20,0,false)
    var x=Array.fill(w,h)(0)
    def n(y:Int,z:Int)=for(b<-z-1 to z+1;a<-y-1 to y+1 if(!(a==y&&b==z)))d+=x((a+w)%w)((b+h)%h)
    def top=new MainFrame with ActionListener
    {
        title="Life"
        preferredSize=new Dimension(500,500)
        menuBar=new MenuBar
        {
            contents+=new Menu("Control")
            {
                contents+={new MenuItem("Start/Stop")
                {
                    listenTo(this)
                    reactions+=
                    {
                        case ButtonClicked(c)=>run= !run
                    }
                }}
            }
        }
        contents=new Component
        {
            listenTo(mouse.clicks)
            reactions+=
            {
                case e:MouseClicked=>
                    var p=e.point
                    if(p.x<w*c)
                    {
                        x(p.x/c)(p.y/c)^=1
                        repaint
                    }
            }
            override def paint(g:Graphics2D)
            {
                for(j<-0 to h-1;i<-0 to w-1)
                {
                    var r=new Rectangle(i*c,j*c,c,c)
                    x(i)(j) match
                    {
                        case 0=>g draw r
                        case 1=>g fill r
                    }
                }
            }
        }
        def actionPerformed(e:ActionEvent)
        {
            if(run)
            {
                var t=x.map(_.clone)
                for(j<-0 to h-1;i<-0 to w-1)
                {
                    d=0
                    n(i,j)
                    x(i)(j) match
                    {
                        case 0=>if(d==3)t(i)(j)=1
                        case 1=>if(d<2||d>3)t(i)(j)=0
                    }
                }
                x=t.map(_.clone)
                repaint
            }
        }
        val timer=new Timer(200,this)
        timer.start
    }
}

ここでのコードの大部分はSwing GUIのものです。ゲーム自体は、actionPerformedによってトリガーされるメソッドTimerと、n近隣をカウントするヘルパー関数にあります。

使用法:

でコンパイルしてscalac filenameからで実行しscala Lます。
正方形をクリックするとライブからデッドに切り替わり、メニューオプションでゲームが開始および停止します。グリッドのサイズを変更する場合は、行の最初の3つの値を変更します。var(w,h,c,d,r)=(20,20,20,0,false)これらは、それぞれ幅、高さ、およびセルサイズ(ピクセル単位)です。


2つのゴルフの改善点を見つけました:import java.awt.event._およびcontents+=m("Go",true)+=m("Stop",false)}}、1093の文字につながります。
ユーザー不明

@user unknownありがとう。自分でいくつかの改善点を見つけました-現在は1063までです。
ガレス

くそー、あなたは忙しかった。がんばり続ける!回答をさらに数人が投稿したときにテストします。
グリフィン

7

Pure Bash、244バイト

トロイドでラップされた36x24ユニバースで動作します。

mapfile a
for e in {0..863};{
for i in {0..8};{
[ "${a[(e/36+i/3-1)%24]:(e+i%3-1)%36:1}" == O ]&&((n++))
}
d=\ 
c=${a[e/36]:e%36:1}
[ "$c" == O ]&&((--n==2))&&d=O
((n-3))||d=O
b[e/36]+=$d
n=
}
printf -vo %s\\n "${b[@]}"
echo "$o"
exec $0<<<"$o"

これはシェルスクリプトであるため、入力方法は他のシェルコマンド(stdinから)と一致します。

$ ./conway.sh << EOF

   O 
    O 
  OOO 

EOF


  O O                                                       
   OO                                                       
   O                                                        

















    O                                                       
  O O                                                       
   OO                                                       

...など

任意のテキストソースからの入力をリダイレクトし、trフィルターを通してパイプ処理して、興味深い初期世代を取得できます。たとえば、

man tr | tr [:alnum:] O | ./conway.sh

6

JavaScript、130

チャレンジに完全に応えているわけではありませんが、記録のために、2013年にSubzeyとIによって作成された130バイトのGame of Lifeエンジンがあります。

http://xem.github.io/miniGameOfLife/

/* Fill an array with 0's and 1's, and call g(array, width, height) to iterate */
g=function(f,c,g,d,e,b,h){g=[];e=[c+1,c,c-1,1];for(b=c*c;b--;g[b]=3==d||f[b]&&2==d,d=0)for(h in e)d+=f[b+e[h]]+f[b-e[h]];return g}

これには、最初の行にいくつかの問題があるようです。たとえば、設定@@\n@@(左上の2 x 2の正方形)または.@\n.@\n.@。(1
アナン

5

C#-675文字

私はいつもこのプログラムのバージョンを書きたいと思っていました。早くて汚いバージョンのためにそれが怠zyな30分だけかかるとは知らなかった。(もちろん、ゴルフにはもっと時間がかかります。)

using System.Windows.Forms;class G:Form{static void Main(){new G(25).ShowDialog();}
public G(int z){var g=new Panel[z,z];var n=new int [z,z];int x,y,t;for(int i=0;i<z;
i++)for(int j=0;j<z;j++){var p=new Panel{Width=9,Height=9,Left=i*9,Top=j*9,BackColor
=System.Drawing.Color.Tan};p.Click+=(s,a)=>p.Visible=!p.Visible;Controls.Add(g[i,j]=
p);}KeyUp+=(s,_)=>{for(int i=0;i<99;i++){for(x=0;x<z;x++)for(y=0;y<z;y++){t=0;for(int 
c=-1;c<2;c++)for(int d=-1;d<2;d++)if(c!=0||d!=0){int a=x+c,b=y+d;a=a<0?24:a>24?0:a;b=
b<0?24:b>24?0:b;t+=g[a,b].Visible?0:1;}if(t==3||t>1&&!g[x,y].Visible)n[x,y]=1;if(t<2
||t>3)n[x,y]=0;}for(x=0;x<z;x++)for(y=0;y<z;y++)g[x,y].Visible=n[x,y]<1;Update();}};}}

使用法

  • セルをクリックしてオンにすることで開始パターンを入力します(有効)。
  • キーボードのキーを押してゲームを開始します。
  • ゲームは、キーが押されるたびに99世代にわたって実行されます(文字を保存するために9を作成することもできましたが、それはあまりにも不十分でした)。

ゴルフの妥協

  • セルをオンにできるのはマウスではなく、オフにできるため、間違えた場合はプログラムを再起動する必要があります。
  • グリッド線はありませんが、それはプレイアビリティをあまり害しません。
  • 更新速度はCPU速度に比例するため、非常に高速のコンピューターでは、おそらくぼやけているだけです。
  • 「黒」はさらに2文字を使用するため、生きている細胞は赤です。
  • セルの小ささと、すべてのフォームスペースを使い果たしていないという事実も、文字を節約するための妥協点です。

5

GW-BASIC、1086 1035バイト(トークン化)

トークン化された形式では、これは1035バイトです。(もちろん、ASCII形式はもう少し長くなります。)インタープリターにSAVE"life追加せずにコマンドを使用すると、トークン化された形式を取得でき",aます。

10 DEFINT A-Z:DEF SEG=&HB800:KEY OFF:COLOR 7,0:CLS:DEF FNP(X,Y)=PEEK((((Y+25)MOD 25)*80+((X+80)MOD 80))*2)
20 X=0:Y=0
30 LOCATE Y+1,X+1,1
40 S$=INKEY$:IF S$=""GOTO 40
50 IF S$=CHR$(13)GOTO 150
60 IF S$=" "GOTO 130
70 IF S$=CHR$(0)+CHR$(&H48)THEN Y=(Y-1+25)MOD 25:GOTO 30
80 IF S$=CHR$(0)+CHR$(&H50)THEN Y=(Y+1)MOD 25:GOTO 30
90 IF S$=CHR$(0)+CHR$(&H4B)THEN X=(X-1+80)MOD 80:GOTO 30
100 IF S$=CHR$(0)+CHR$(&H4D)THEN X=(X+1)MOD 80:GOTO 30
110 IF S$="c"THEN CLS:GOTO 20
120 GOTO 40
130 Z=PEEK((Y*80+X)*2):IF Z=42 THEN Z=32ELSE Z=42
140 POKE(Y*80+X)*2,Z:GOTO 40
150 LOCATE 1,1,0:ON KEY(1)GOSUB 320:KEY(1) ON
160 V!=TIMER+.5:FOR Y=0 TO 24:FOR X=0 TO 79:N=0
170 Z=FNP(X-1,Y-1):IF Z=42 OR Z=46 THEN N=N+1
180 Z=FNP(X,Y-1):IF Z=42 OR Z=46 THEN N=N+1
190 Z=FNP(X+1,Y-1):IF Z=42 OR Z=46 THEN N=N+1
200 Z=FNP(X-1,Y):IF Z=42 OR Z=46 THEN N=N+1
210 Z=FNP(X+1,Y):IF Z=42 OR Z=46 THEN N=N+1
220 Z=FNP(X-1,Y+1):IF Z=42 OR Z=46 THEN N=N+1
230 Z=FNP(X,Y+1):IF Z=42 OR Z=46 THEN N=N+1
240 Z=FNP(X+1,Y+1):IF Z=42 OR Z=46 THEN N=N+1
250 Z=PEEK((Y*80+X)*2):IF Z=32 THEN IF N=3 THEN Z=43
260 IF Z=42 THEN IF N<2 OR N>3 THEN Z=46
270 POKE(Y*80+X)*2,Z:NEXT:NEXT:FOR Y=0 TO 24:FOR X=0 TO 79:Z=PEEK((Y*80+X)*2):IF Z=46 THEN Z=32
280 IF Z=43 THEN Z=42
290 POKE(Y*80+X)*2,Z:NEXT:NEXT
300 IF TIMER<V!GOTO 300
310 IF INKEY$=""GOTO 160
320 SYSTEM

これは最大のゴルフバージョンですが、まだ機能的です。起動すると、カーソルキーで移動できるエディターが表示されます。スペースは現在のフィールドでバクテリアのオン/オフを切り替えc、画面をクリアし、リターンはゲームモードを開始します。

以下は難読化されていないバージョンです。このゲームでは、初期のゲームボードにも2つの構造(回転するものとグライダー)が設定されています。

1000 REM Conway's Game of Life
1001 REM -
1002 REM Copyright (c) 2012 Thorsten "mirabilos" Glaser
1003 REM All rights reserved. Published under The MirOS Licence.
1004 REM -
1005 DEFINT A-Z:DEF SEG=&hB800
1006 KEY OFF:COLOR 7,0:CLS
1007 DEF FNP(X,Y)=PEEK((((Y+25) MOD 25)*80+((X+80) MOD 80))*2)
1010 PRINT "Initial setting mode, press SPACE to toggle, RETURN to continue"
1020 PRINT "Press C to clear the board, R to reset. OK? Press a key then."
1030 WHILE INKEY$="":WEND
1050 CLS
1065 DATA 3,3,4,3,5,3,6,3,7,3,8,3,3,4,4,4,5,4,6,4,7,4,8,4
1066 DATA 10,3,10,4,10,5,10,6,10,7,10,8,11,3,11,4,11,5,11,6,11,7,11,8
1067 DATA 11,10,10,10,9,10,8,10,7,10,6,10,11,11,10,11,9,11,8,11,7,11,6,11
1068 DATA 4,11,4,10,4,9,4,8,4,7,4,6,3,11,3,10,3,9,3,8,3,7,3,6
1069 DATA 21,0,22,1,22,2,21,2,20,2,-1,-1
1070 RESTORE 1065
1080 READ X,Y
1090 IF X=-1 GOTO 1120
1100 POKE (Y*80+X)*2,42
1110 GOTO 1080
1120 X=0:Y=0
1125 LOCATE Y+1,X+1,1
1130 S$=INKEY$
1140 IF S$="" GOTO 1130
1150 IF S$=CHR$(13) GOTO 1804
1160 IF S$=" " GOTO 1240
1170 IF S$=CHR$(0)+CHR$(&h48) THEN Y=(Y-1+25) MOD 25:GOTO 1125
1180 IF S$=CHR$(0)+CHR$(&h50) THEN Y=(Y+1) MOD 25:GOTO 1125
1190 IF S$=CHR$(0)+CHR$(&h4B) THEN X=(X-1+80) MOD 80:GOTO 1125
1200 IF S$=CHR$(0)+CHR$(&h4D) THEN X=(X+1) MOD 80:GOTO 1125
1210 IF S$="c" THEN CLS:GOTO 1120
1220 IF S$="r" GOTO 1050
1225 IF S$=CHR$(27) THEN END
1230 GOTO 1130
1240 Z=PEEK((Y*80+X)*2)
1250 IF Z=42 THEN Z=32 ELSE Z=42
1260 POKE (Y*80+X)*2,Z
1270 GOTO 1130
1804 LOCATE 1,1,0
1900 ON KEY(1) GOSUB 2300
1910 KEY(1) ON
2000 V!=TIMER+.5
2010 FOR Y=0 TO 24
2020  FOR X=0 TO 79
2030   N=0
2040   Z=FNP(X-1,Y-1):IF Z=42 OR Z=46 THEN N=N+1
2050   Z=FNP(X  ,Y-1):IF Z=42 OR Z=46 THEN N=N+1
2060   Z=FNP(X+1,Y-1):IF Z=42 OR Z=46 THEN N=N+1
2070   Z=FNP(X-1,Y  ):IF Z=42 OR Z=46 THEN N=N+1
2080   Z=FNP(X+1,Y  ):IF Z=42 OR Z=46 THEN N=N+1
2090   Z=FNP(X-1,Y+1):IF Z=42 OR Z=46 THEN N=N+1
2100   Z=FNP(X  ,Y+1):IF Z=42 OR Z=46 THEN N=N+1
2110   Z=FNP(X+1,Y+1):IF Z=42 OR Z=46 THEN N=N+1
2120   Z=PEEK((Y*80+X)*2)
2130   IF Z=32 THEN IF N=3 THEN Z=43
2140   IF Z=42 THEN IF N<2 OR N>3 THEN Z=46
2150   POKE (Y*80+X)*2,Z
2160  NEXT X
2170 NEXT Y
2200 FOR Y=0 TO 24
2210  FOR X=0 TO 79
2220   Z=PEEK((Y*80+X)*2)
2230   IF Z=46 THEN Z=32
2240   IF Z=43 THEN Z=42
2250   POKE (Y*80+X)*2,Z
2260  NEXT X
2270 NEXT Y
2280 IF TIMER<V! GOTO 2280
2290 IF INKEY$="" GOTO 2000
2300 SYSTEM

退屈して友人を待っている間に15分でこれを書きました。友人は、コンウェイのGame of Lifeの「見習い」と同時にコードゴルフをしていました。

これは次のように機能します:すぐに80x25テキストモードの画面バッファーDEF SEGを使用します(&hB000Herculesグラフィックカードを使用している場合に使用するイニシャルを変更します。これらの設定はQemuおよび(遅い)dosboxで動作します)。アスタリスク*は細菌です。

2パスで機能します。最初に、出生地にがマークされ+、死にターゲットがでマークされ.ます。2番目のパスでは、+および.はそれぞれ*に置き換えられます。

TIMERあなたのQEMUホストが非常に高速☺である場合には事は、それが各ラウンドの後に半秒待つようにすることです

私はここで最短の勝利価格を望んでいませんが、特に初期のボードのセットアップを考慮して、クールな価格を望んでいます。興味がある場合に備えて、ゲームエンジンがアセンブリコードに置き換えられたバージョンもあります。


非ゴルフバージョンでラベルを1増やしたとしたら、ゴルフバージョンでも同じことをすることは可能ですか?(すなわち、123、など)や行番号はカウントされませんか?
ザカリー

行番号は、トークン化されたときに単語(16ビット)としてカウントされます。完全に間違えていなければ
ミラビロス

それでは、他のBASIC方言を考えていたはずです。
ザカリー

@Zacharý 「GW-BASICトークン化プログラム形式」をクリックしてから「プログラム形式」をクリックて、実際に行番号が常に2バイトであり、トークン形式の詳細を確認します。
ミラビロス

5

Mathematica、115バイト

これは簡単なコップアウトです:

ListAnimate[ArrayPlot/@CellularAutomaton[{224,{2,{{2,2,2},{2,1,2},
{2,2,2}}},{1,1}},{RandomInteger[1,{9,9}],0},90]]

1
Mathematicaは問題ありませんが、規則が示すように、プログラムはユーザーが独自のパターンを入力できるようにする必要があります。いくつかの言語ではこのような短い実装が許可されていますが、ユーザーの操作は必要ないため、このルールは意図的なものです。そこに独自の配列を配置することはできますが、勝つことはできません。
グリフィン

Mathematicaの「入力」は主にノートブックのインターフェースを介して行われるため、「ユーザーとの対話」は実際に可能だとは思いません。CellularAutomaton関数のRandomInteger引数を必要なものに置き換えて、コードを再評価するだけです。
JeremyKun

3
ユーザーとの対話が可能です。私が今考えることができる最も単純な方法は、ボタンの配列です。それを外に出してください。
グリフィン

4

Java(OpenJDK 8)-400 388 367バイト

2番目の(おそらく)最終編集:これらの(imo)鉱山を見つけてから21バイト余分にゴルフをすることができました -特にJavaを使用してこれらの課題のいくつかを試してみる場合は、新しい人に読んでもらうことをお勧めします。

結果のコード(これらの二重にネストされたforループを短縮する方法を見つけると、おそらくさらにゴルフをすることになります...):

u->{int w=u.length,h=u[0].length,x,y,i,j,n;Stack<Point>r=new Stack<Point>();for(;;){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x)for(y=0;y<h;++y){boolean o=u[x][y]>0;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]>0)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]+(y>h-2?"\n":""));}for(int[]t:u)Arrays.fill(t,0);}}

オンラインでお試しください!

(オリジナルの投稿はここから始まります。)

私は実際、しばらくの間、Javaの(ほぼ制限された)知識でPythonの最良の答えに挑戦できると思っていましたlol ...少し遅れて...)

それほど多くはありません-基本的な説明は次のとおりです(変更なし)。

/*
 * Explanation of each variable's usage:
 * w=height* of array
 * h=width* of array
 * x=y* coord of point in array
 * y=x* coord of point in array
 * i and j are counters for calculating the neighbours around a point in the array
 * n=neighbour counter
 * r=temporary array to store the cells from the current generation
 * u=the 2d array used for all the calculations (parameter from lambda expression)
 * c=temporary variable used to help populate the 2d array
 * o=boolean variable that stores the value of whether the cell is alive or not
 */
u-> // start of lambda statement with u as parameter (no need for brackets as it's only one parameter being passed)
{
    int w=u.length,h=u[0].length,x,y,i,j,n; // defines all the necessary integer variables;
    Stack<Point>r=new Stack<Point>(); // same with the only array list needed (note how I only use two data structures);
    for(;;) // notice how this is still an infinite loop but using a for loop;
    {
        for(Point c:r)u[c.x][c.y]=1; //for every point in the "previous" generation, add that to the 2D array as a live (evil?) cell;
        r.clear(); // clears the array list to be populated later on
        for(x=0;x<w;++x) // a pair of nested for loops to iterate over every cell of the 2D array;
        {
            for(y=0;y<h;++y)
            {
                // sets o to be the presence of a live cell at (x,y) then uses said value in initialising the neighbour counter;
                boolean o=u[x][y]>1;n=o?-1:0;
                for(i=-2;++i<2;) // another pair of nested for loops - this one iterates over a 3x3 grid around *each* cell of the 2D array;
                {                // this includes wrap-around (note the modulus sign in the if statement below);
                    for(j=-2;++j<2;)
                    {
                        if(u[(w+x+i)%w][(h+y+j)%h]>0)++n; // this is where the first interesting thing lies - the bit which makes wrap-around a reality;
                    }
                }
                if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y)); // this is the second interesting bit of my code - perhaps more so as I use bitwise operators to calculate the number of neighbours (x,y) has;
                                                            // (since I'm technically dealing with 0s and 1s, it's not a total misuse of them imo);
                System.out.print(u[x][y]+(y>h-2?"\n":""));  // that extra part of the print statement adds a newline if we reached the end of the current 'line';
            }
        }
        // since the information about the new generation is now in the array list, this array can be emptied out, ready to receive said info on the new generation;
        for(int[]t:u)Arrays.fill(t,0);
    }
} // end of lambda statement

(Java 8のラムダステートメントに関する詳細はこちら

はい、私のアプローチには問題があります。

おそらくお気づきのように、現在の私のゴルフのコードは永遠にループします。これを防ぐために、カウンターを先頭に導入し、whileループで使用して、n次のように(この場合は5回)反復のみを表示できます(新しいb変数が追加されたことに注意してください)。

u->{int b=0,w=u.length,h=u[0].length,x,y,i,j,n;Stack<Point>r=new Stack<Point>();for(;++b<6;){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x)for(y=0;y<h;++y){boolean o=u[x][y]>0;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]>0)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]+(y>h-2?"\n":""));}for(int[]t:u)Arrays.fill(t,0);}}

さらに、言及する価値があるいくつかのポイント。このプログラムは入力が正しいかどうかを確認しないため、(ほとんどの場合)で失敗しArrayOutOfBoundsExceptionます。そのため、配列の一部を完全に埋めることにより、入力が有効であることを確認してください(歪んだ配列は上記の例外をスローします)。また、現在のボードは「流動的」に見えます。つまり、世代間で分離はありません。生成される世代が実際に有効であることを再確認するためにそれを追加したい場合は、System.out.println();直前に追加を追加する必要がありますfor(int[]t:u)Arrays.fill(t,0);(明確にするために、オンラインで試してみてください!)。最後になりましたが、これが私の最初のコードゴルフであることを考えると、フィードバックは大歓迎です:)

前の388バイトの回答の古いコード:

u->{int w=u.length,h=u[0].length,x,y,i,j,n;ArrayList<Point>r=new ArrayList<Point>();while(true){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}for(int[]t:u)Arrays.fill(t,0);}}

そして、最初の400バイトの答えから:

int w=35,h=20,x,y,i,j,n;ArrayList<Point>l=new ArrayList<Point>(),r;while(true){int[][]u=new int[w][h];for(Point c:l)u[c.x][c.y]=1;r=new ArrayList<Point>();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}l.clear();l.addAll(r);}

すばらしい最初の投稿、PPCGへようこそ!
ザカリー

おかげで、私は間違いなくこれらの多くのことをするつもりです-彼らは楽しいです:)
NotBaal

デニスがいます。また、これは完全なプログラムではなく、IIRCである必要がある機能でもありません。
ザカリー

ああ、「プログラム」の部分を忘れました:P編集して少し。
NotBaal

それも関数になります。
ザカリー

4

ステンシル、6バイト

ではない私の好きな言語が、それはある短いです...

4コードバイトとnlistおよびTorusフラグ。

3me

オンラインでお試しください!

...である
3 3
 のメンバーメートル自己またはとoore近傍カウント 湿原電子の自己なし-neighbourhood-countは ...?
m
e


3

Scala-799文字

スクリプトとして実行します。四角をマウスでクリックすると、四角がオンまたはオフに切り替わり、キーが生成を開始または停止します。

import java.awt.Color._
import swing._
import event._
import actors.Actor._
new SimpleSwingApplication{var(y,r,b)=(200,false,Array.fill(20,20)(false))
lazy val u=new Panel{actor{loop{if(r){b=Array.tabulate(20,20){(i,j)=>def^(i:Int)= -19*(i min 0)+(i max 0)%20
var(c,n,r)=(0,b(i)(j),-1 to 1)
for(x<-r;y<-r;if x!=0||y!=0){if(b(^(i+x))(^(j+y)))c+=1}
if(n&&(c<2||c>3))false else if(!n&&c==3)true else n}};repaint;Thread.sleep(y)}}
focusable=true
preferredSize=new Dimension(y,y)
listenTo(mouse.clicks,keys)
reactions+={case e:MouseClicked=>val(i,j)=(e.point.x/10,e.point.y/10);b(i)(j)= !b(i)(j)case _:KeyTyped=>r= !r}
override def paintComponent(g:Graphics2D){g.clearRect(0,0,y,y);g.setColor(red)
for(x<-0 to 19;y<-0 to 19 if b(x)(y))g.fillRect(x*10,y*10,9,9)}}
def top=new Frame{contents=u}}.main(null)

3

J、45

Jを試してみようと思った。ゴルフはまだそれほど良くありませんが、すぐにもう一度試してみましょう。

(]+.&(3&=)+)+/((4&{.,(_4&{.))(>,{,~<i:1))&|.

例:

   f =: 5 5 $ 0 1 0 0 0   0 0 1 0 0   1 1 1 0 0   0 0 0 0 0    0 0 0 0 0
   f
0 1 0 0 0
0 0 1 0 0
1 1 1 0 0
0 0 0 0 0
0 0 0 0 0
   f (]+.&(3&=)+)+/((4&{.,(_4&{.))(>,{,~<i:1))&|. f
0 0 0 0 0
1 0 1 0 0
0 1 1 0 0
0 1 0 0 0
0 0 0 0 0

3

処理 536 532

int h=22,t=24,i,j;int[][]w=new int[t][t],b=new int[t][t];int[]q={1,0,-1};void draw(){if(t<9){clear();for(i=2;i<h;i++){for(j=2;j<h;j++)w[i][j]=b[i][j];w[i][1]=w[i][21];w[i][h]=w[i][2];w[1][i]=w[21][i];w[h][i]=w[2][i];}for(i=1;i<23;i++)for(j=1;j<23;j++){t=-w[i][j];for(int s:q)for(int d:q)t+=w[i+s][j+d];b[i][j]=w[i][j]>0&(t<2|t>3)?0:t==3?1:b[i][j];}a();}}void keyPressed(){t=0;}void mousePressed(){int i=mouseX/5+2,j=mouseY/5+2;w[i][j]=b[i][j]=1;a();}void a(){for(i=0;i<h-2;i++)for(j=0;j<h-2;j++)if(w[i+2][j+2]==1)rect(i*5,j*5,5,5);}

これはすべての要件を満たしていると思います。

ゴルフをしていない:

int h=22,t=24,i,j;
int[][]w=new int[t][t],b=new int[t][t];
int[]q={1,0,-1};
void draw(){
  if(t<9){
  clear();
  for(i=2;i<h;i++){
    for(j=2;j<h;j++)
      w[i][j]=b[i][j];  
    w[i][1]=w[i][21];
    w[i][h]=w[i][2];
    w[1][i]=w[21][i];
    w[h][i]=w[2][i];
  }
  for(i=1;i<23;i++)
    for(j=1;j<23;j++){
      t=-w[i][j];
      for(int s:q)
        for(int d:q)
          t+=w[i+s][j+d];        
      b[i][j]=w[i][j]>0&(t<2|t>3)?0:t==3?1:b[i][j];  
  }
  a();
}
}
void keyPressed(){
  t=0;
}
void mousePressed(){
  int i=mouseX/5+2,j=mouseY/5+2;
  w[i][j]=b[i][j]=1;
  a();
}
void a(){
  for(i=0;i<h-2;i++)
    for(j=0;j<h-2;j++)
      if(w[i+2][j+2]==1)
        rect(i*5,j*5,5,5);
  }  

3

Matlab(152)

b=uint8(rand(20)<0.2)
s=@(m)imfilter(m,[1 1 1;1 0 1;1 1 1],'circular')
p=@(m,n)uint8((n==3)|(m&(n==2)))
while 1
imshow(b)
drawnow
b=p(b,s(b))
end

私はそれをテストするためにMatlabを今すぐインストールしていません。数年前に書いたコードをたった今ゴルフしました。
ゴルフをしていない:

%% initialize
Bsize = 20;
nsteps = 100;
board = uint8(rand(Bsize)<0.2); % fill 20% of the board
boardsum = @(im) imfilter(im,[1 1 1; 1 0 1; 1 1 1], 'circular');
step = @(im, sumim) uint8((sumim==3) | (im & (sumim==2)) );

%% run
for i = 1:nsteps
    imshow(kron(board,uint8(ones(4))), [])
    drawnow
    ss(p,i) = sum(board(:));
    board = step(board, boardsum(board));
end
  • ボードサイズはハードコードされていますが、何でもかまいません
  • 包み込む
  • ユーザー入力については、別のマトリックスをハードコーディングするか、変数エディターを使用して、初期ボードを変更できます。きれいではないが、うまくいく
  • グラフィカル出力をスキップすると20文字を保存できますが、ボードは繰り返しごとにテキストとして印刷されます。とにかく、ミリ秒ごとに変化する1ピクセルのセルはあまり役に立ちません

R2014aで動作し、テスト済み
masterX244 14年

3

Perl、218 216 211 202バイト

$,=$/;$~=AX3AAAx76;$b=pack('(A79)23',<>)x6;{print unpack'(a79)23a0',$b;select$v,$v,$v,0.1;$b=pack'(A)*',unpack'((x7a/(x13)X4Ax!18)1817@0)4',pack'((a*)17xx!18)*',unpack"x1737(AA$~Ax$~AA$~@)2222",$b;redo}

(このコードの最後に改行はありません。)

標準入力から開始パターンを読み取ります。テキストファイルとして、ライブセルはとして表され1、デッドセルはスペースとして表され、行は改行で区切られます。入力にはこれら以外の文字は使用できません。行は可変長にすることができ、幅がちょうど79になるようにパディングまたは切り捨てられます。入力例はグライダーガンです。

                                  1
                                1 1
                      11      11            11
                     1   1    11            11
          11        1     1   11
          11        1   1 11    1 1
                    1     1       1
                     1   1
                      11









                                         11
                                         1
                                          111
                                            1

プログラムがGame of Lifeを実行すると、すべての状態が入力と同様の形式で標準出力にダンプされ、0.1秒遅延します。遅延は、select呼び出しの4番目の引数を変更することによりカスタマイズできます。

ゲームボードはサイズ79x23にハードコードされています。トーラスに包まれています。ボードを下に置いたままにすると、一番上になります。右側を離れると、左側に移動しますが、1行下に移動します。

これは、入力を一切読み込まず、ランダムなボードから始まる代替バージョンです。

$,=$/;$/=AX3AAAx76;$b=pack("(A)*",map{rand 3<1}0..1816)x6;{print unpack'(a79)23a0',$b;select$v,$v,$v,0.1;$b=pack'(A)*',unpack'((x7a/(x13)X4Ax!18)1817@0)4',pack'((a*)17xx!18)*',unpack"x1737(AA$/Ax$/AA$/@)2222",$b;redo}

このコードは私が何年も前に書いた難読化さた人生のperlプログラムから派生したものです。ボードをトロイダルにし、ゴルフをコードにするために多くの変更を加えました。

これはおそらく、PerlでGame of Lifeを実装する最短の方法ではありませんが、わかりにくい方法の1つです。

ボードはで保存されている$bの文字列として'1'' '、各セルに1つは、唯一の全体のことは、少なくとも3回繰り返しています。3番目のunpack呼び出しは、セルごとに17個の値を抽出します。セル自体に1つ、隣接する8つのセルに2つが任意の順序であり、各値は'1'空の文字列です。'1'これらの17 個の値の中の値の数が5、6、または7である場合、セルは次の反復で生きる必要があります。 。2番目のアンパックコールは、このような18ワイドフィールドを使用し、位置7のキャラクターにディスパッチします。'1'または、それ以外の場合は位置4から文字をアンパックします。この結果は、セルが次世代で持つべき値です。


2

Python、589バイト

マウスボタン:左-セルを配置、右-セルを削除、中央-開始/停止。

Tkinterインポートから*
インポートコピー
z =範囲
F = 50
T = Tk()
S = 9
f = [F * [0] for i in'7 '* F]
c = Canvas(T、width = S * F、height = S * F)
c.pack()
def p(x、y、a):f [y] [x] = f [y] [x] or c.create_oval(x * S、y * S、x * S + S、y * S + S) if a else c.delete(f [y] [x])
r = 1
def R(e):グローバルr; r = 1-r
exec( "c.bind( '<Button-%i>'、lambda e:p(ex / S、ey / S、%i));" * 2%(1,1,3,0))
c.bind( '<Button-2>'、R)
def L():
 T.after(99、L)
 r:returnの場合
 g = copy.deepcopy(f)
 z(F)のyの場合:
	z(F)のxの場合:
	 n = 8
	 z(-1,2)のjの場合:
		z(-1,2)のiの場合:
		 iまたはj:n- = not g [(y + j)%F] [(x + i)%F]の場合
	 1 <n <4の場合:
		n == 3で、g [y] [x]:p(x、y、1)ではない場合
	 else:p(x、y、0)
L()
T.mainloop()

そして、ここにマウスをドラッグして描画できるバージョンがあります。グラフィックはもう少し快適です。

from Tkinter import*
import copy
z=range
F=50
T=Tk()
S=9
f=[F*[0]for i in'7'*F]
c=Canvas(T,bg='white',width=S*F,height=S*F)
c.pack()
def p(x,y,a):f[y][x]=f[y][x]or c.create_rectangle(x*S,y*S,x*S+S,y*S+S,fill='gray')if a else c.delete(f[y][x])
r=1
def R(e):global r;r=1-r
exec("c.bind('<Button-%i>',lambda e:p(e.x/S,e.y/S,%i));c.bind('<B%i-Motion>',lambda e:p(e.x/S,e.y/S,%i));"*2%(1,1,1,1,3,0,3,0))
c.bind('<Button-2>',R)
def L():
 T.after(99,L)
 if r:return
 g=copy.deepcopy(f)
 for y in z(F):
  for x in z(F):
   n=8
   for j in z(-1,2):
    for i in z(-1,2):
     if i or j:n-=not g[(y+j)%F][(x+i)%F]
   if 1<n<4:
    if n==3and not g[y][x]:p(x,y,1)
   else:p(x,y,0)
L()
T.mainloop()

これは、ゲームオブライフのルールに正しく従っていません。
スティーブンランバルスキー

1
@StevenRumbalski:ほんとに?
オレPrypin

2
本当に。2番目のバージョンでインデントエラーがあります。で始まるセクションif 1<n<4:は、次のレベルと同じレベルでインデントする必要がありますfor j in z(-1,2):
スティーブンランバルスキー

2

Python 2、456バイト

これは古い投稿であることは知っていますが、試してみることはできませんでした。最初のボードは、周囲に境界線を引き、最後の行に余分なスペースがある限り、どのようなサイズでもかまいません。

Golf.py

import time,itertools as w,sys;t,q=map(lambda x:list(x[:-1]),sys.stdin.readlines()),list(w.product(range(-1,2),range(-1,2)));del q[4];n=map(lambda x:x[:],t[:])
while time.sleep(0.1)==None:
 for j in range(1,len(t)-1):
  for i in range(1,len(t[j])-1):x=sum(map(lambda s:1 if t[j+s[0]][i+s[1]]in'@'else 0,q));f=t[j][i];n[j][i]='@'if(f=='@'and(x==3 or x==2))or(f==' 'and x==3)else' '
 t=map(lambda x:x[:],n[:]);print'\n'.join(list(map(lambda x:''.join(x),t)))

Input.txt(最後の行に余分なスペースがあることに注意してください)

+----------------------------------------+
|                    @                   |
|                     @                  |
|                   @@@                  |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
+----------------------------------------+ 

実行方法

python Golf.py < input.txt

time.sleep(0.1)==None=> not time.sleep(.1)(f=='@'and(x==3 or x==2))or(f == '' and x == 3)=>x==3or f=='@'and x==2
CalculatorFeline

^、忘れてしまった、1 if=> 1if
ザカリー

2

処理 270,261 249バイト

グリッドは画面の100 * 100ピクセルで、入力はpng画像の形式です

void setup(){image(loadImage("g.png"),0,0);}void draw(){loadPixels();int n,i=0,j,l=10000;int[]a=new int[l],p=pixels;for(;i<l;a[i]=n==5?-1<<24:n==6?p[i]:-1,i++)for(j=n=0;j<9;j++)n+=j!=4?p[(i+l-1+j%3+100*(j/3-1))%l]&1:0;arrayCopy(a,p);updatePixels();}

非ゴルフ

void setup() {
  image(loadImage("g.png"), 0, 0);
}
void draw() {
  loadPixels();
  int c=100, i=0, n, l=c*c, b=color(0);
  int[]a=new int[l], p=pixels;
  for (; i<l; i++) {
    n=p[(i+l-101)%l]&1;
    n+=p[(i+l-100)%l]&1;
    n+=p[(i+l-99)%l]&1;
    n+=p[(i+l-1)%l]&1;
    n+=p[(i+1)%l]&1;
    n+=p[(i+99)%l]&1;
    n+=p[(i+100)%l]&1;
    n+=p[(i+101)%l]&1;
    a[i]=n==5?b:p[i]==b&&n==6?b:-1;
  }
  arrayCopy(a, pixels, l);
  updatePixels();
}

スクリーンショット


2

Lua + LÖVE/ Love2D、653バイト

l=love f=math.floor t={}s=25 w=20 S=1 for i=1,w do t[i]={}for j=1,w do t[i][j]=0 end end e=0 F=function(f)loadstring("for i=1,#t do for j=1,#t[i]do "..f.." end end")()end function l.update(d)if S>0 then return end e=e+d if e>.2 then e=0 F("c=0 for a=-1,1 do for b=-1,1 do if not(a==0 and b==0)then c=c+(t[((i+a-1)%w)+1][((j+b-1)%w)+1]>0 and 1 or 0)end end end g=t[i][j]t[i][j]=(c==3 or(c==2 and g==1))and(g==1 and 5 or-1)or(g==1 and 4 or 0)")F("t[i][j]=t[i][j]%2")end end function l.draw()F("l.graphics.rectangle(t[i][j]==1 and'fill'or'line',i*s,j*s,s,s)")end function l.mousepressed(x,y)S=0 o,p=f(x/s),f(y/s)if t[o]and t[o][p]then t[o][p]=1 S=1 end end

または間隔をあけて:

l=love
f=math.floor
t={}s=25
w=20
S=1
for i=1,w do
    t[i]={}
    for j=1,w do
        t[i][j]=0
    end
end
e=0
F=function(f)
    loadstring("for i=1,#t do for j=1,#t[i] do  "..f.." end end")()
end
function l.update(d)
    if S>0 then
        return
    end
    e=e+d
    if e>.2 then
        e=0
        F([[
        c=0
        for a=-1,1 do
            for b=-1,1 do
                if not(a==0 and b==0)then
                    c=c+(t[((i+a-1)%w)+1][((j+b-1)%w)+1]>0 and 1 or 0)
                end
            end
        end
        g=t[i][j]
        t[i][j]=(c==3 or(c==2 and g==1))and(g==1 and 5 or-1) or (g==1 and 4 or 0)]])
        F("t[i][j]=t[i][j]%2")
    end
end
function l.draw()
    F("l.graphics.rectangle(t[i][j]==1 and'fill'or'line',i*s,j*s,s,s)") end
function l.mousepressed(x,y)
    S=0
    o,p=f(x/s),f(y/s)
    if t[o]and t[o][p] then
        t[o][p]=1
        S=1
    end
end

フィールドをクリックして、生細胞を追加します。フィールドの外側をクリックして実行します。

オンラインでお試しください!

ここに画像の説明を入力してください


1

追記 529 515

Rosetta Codeの例から始めました。ファイル名引数(gs -- gol.ps pulsar)で呼び出します。ファイルには20 * 20の2進数(スペースで区切られています)が含まれています。無限ループ:ボードを描き、エンターを待ち、次世代を計算します。

[/f ARGUMENTS 0 get(r)file/n 20>>begin[/m
n 1 sub/b[n{[n{f token pop}repeat]}repeat]/c 400
n div/F{dup 0 lt{n add}if dup n ge{n sub}if}>>begin{0
1 m{dup 0 1 m{2 copy b exch get exch get 1 xor setgray
c mul exch c mul c c rectfill dup}for pop pop}for
showpage/b[0 1 m{/x exch def[0 1 m{/y exch def 0
y 1 sub 1 y 1 add{F dup x 1 sub 1 x
1 add{F b exch get exch get 3 2 roll add exch
dup}for pop pop}for b x get y get sub b x get y get
0 eq{3 eq{1}{0}ifelse}{dup 2 eq exch 3 eq
or{1}{0}ifelse}ifelse}for]}for]def}loop

いくつかのスタックコメント(必要なコメントのみ)でスペースを空けます。

[
/f ARGUMENTS 0 get(r)file
/n 20
/sz 400
%/r{rand 2147483647 div}
>>begin
[
/m n 1 sub
/b[
%n{[n{r .15 le{1}{0}ifelse}repeat]}repeat
 n{[n{f token pop}repeat]}repeat
]
/c sz n div
/F{dup 0 lt{n add}if dup n ge{n sub}if}
>>begin
{
    0 1 m{dup % y y
    0 1 m{ % y y x
        2 copy b exch get exch get 1 xor setgray
        c mul exch c mul c c rectfill
        dup 
    }for pop pop}for
    pstack
    showpage
    /b[0 1 m{/x exch def
      [0 1 m{/y exch def
          0   
          y 1 sub 1 y 1 add{F dup %s y y
          x 1 sub 1 x 1 add{F %s y y x
              b exch get exch get %s y bxy
              3 2 roll add exch %s+bxy y
              dup %s y y
          }for pop pop}for
          b x get y get sub
          b x get y get
          0 eq{3 eq{1}{0}ifelse}{dup 2 eq exch 3 eq or{1}{0}ifelse}ifelse
      }for]
      }for]def
}loop

パルサーデータファイル:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

1

JavaScript 676

申し訳ありませんが、グリフィン、あなたのコードを見ることができず、少し書き直せませんでした... 2文字を削る必要がありましたが、それはそれだけの価値がありました!

b=[];r=c=s=20;U=document;onload=function(){for(z=E=0;z<c;++z)for(b.push(t=[]),j=0;j<r;j++)with(U.body.appendChild(U.createElement("button")))t.push(0),id=z+"_"+j,style.position="absolute",style.left=s*j+"px",style.top=s*z+"px",onclick=a}; ondblclick=function(){A=E=E?clearInterval(A):setInterval(function(){Q=[];for(z=0;z<c;++z){R=[];for(j=0;j<r;)W=(c+z-1)%c,X=(c+z+1)%c,Y=(r+j-1)%r,Z=(r+j+1)%r,n=b[W][Y]+b[z][Y]+b[X][Y]+b[W][j]+b[X][j]+b[W][Z]+b[z][Z]+b[X][Z],R.push(b[z][j++]?4>n&&1<n:3==n);Q.push(R)}b=Q.slice();d()})};function a(e){E?0:P=e.target.id.split("_");b[P[0]][P[1]]^=1;d()}function d(){for(z=0;z<c;++z)for(j=0;j<r;)U.getElementById(z+"_"+j).innerHTML=b[z][j++]-0}

しかし、彼らが言うように、許可よりも許しを求める方が簡単です...;)


1

オクターブ(153)

Shortest Game of Lifeの DenDenDoによるMatlabと同じですが、imshowをimagescに変更する必要がありました。

b=uint8(rand(20)<0.2)
s=@(m)imfilter(m,[1 1 1;1 0 1;1 1 1],'circular')
p=@(m,n)uint8((n==3)|(m&(n==2)))
while 1
imagesc(b)
drawnow
b=p(b,s(b))
end

1

Python 2:334バイト

わずか6年遅れです。

import time
s='';s=map(list,iter(raw_input,s));k=len(s);l=(-1,0,1);n=int;z=range
while 1:
 r=[[0]*k for i in z(k)]
 for i in z(k*k):
  a,b=i//k,i%k
  m,g=sum([n(s[(a+c)%k][(b+d)%k])for c in l for d in l if c|d]),n(s[a][b])
  r[a][b]=n((m==2)&g or m==3)
  print'*'if r[a][b]else' ',
  if b-k+1==0:print
 s=r;time.sleep(.2);print"\033c"

次のように実行できます。

python gol.py
0000000
0001000
0000100
0011100
0000000
0000000
0000000

0と1が死細胞と生細胞を表す場合、最後に余分な改行が実行を開始します。

グリッドは正方形でなければなりません。

最短のpythonよりも実行が簡単で、任意のサイズのグリッドをサポートし、実行時にきれいに見えます。

また、100バイト以上もあるので、それもあります。


0

PHP、201バイト(テストなし)

for($s=file(f);print"\n";$s=$t)foreach($s as$y=>$r)for($x=-print"
";"
"<$c=$s[$y][++$x];print$t[$y][$x]=" X"[$n<4&$n>2-$a])for($n=-$a=$c>A,$i=$x-!!$x-1;$i++<=$x;)for($k=$y-2;$k++<=$y;)$n+=$s[$k][$i]>A;

で実行し-nrます。

壊す

for($s=file(f);                         # import input from file "f"
    print"\n";                              # infinite loop: 1. print newline
    $s=$t)                                  # 3. copy target to source, next iteration
    foreach($s as$y=>$r)                    # 2. loop through lines
        for($x=-print"\n";"\n"<$c=$s[$y][++$x]; # print newline, loop $x/$c through line characters (before line break)
            print                                   # 5. print new cell
                $t[$y][$x]=" X"[$n>2-$a&$n<4])      # 4. new cell is alive if neighbour count<4 and >2 (>1 if alive)
            for($n=-                                # 2. init neighbour count: exclude self
                $a=$c>A,                            # 1. $a=cell is alife
                $i=$x-!!$x-1;$i++<=$x;)             # 3. loop $i from one left to one right of current position
                for($k=$y-2;$k++<=$y;)                  # loop $k from one above to one below current position
                    $n+=$s[$k][$i]>A;                       # increase neighbor count if neighbour is alife
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.