challenge ライフゲーム

セルオートマトンに関するお題です. 
2次元タイプの'ライフゲーム'を実装して下さい. 
初期値としては10行10列程度の格子上の平面に0.3程度の人口(?)密度を考え, 
末端はループするようにして下さい. (例: 座標[-1, -1] = [10, 10])

それだけだと簡単すぎると思われる方は, 
過密状態で間引きが発生するような機能を組み込んで下さい. 
間引きは, 少なくともその後の1時間ステップにおける死亡率が, 
それをしなかった場合よりも小さくなれば結構です. 
(死亡率の最小化は複雑性が高すぎる感がありますし. )
サンプル:
t = 0
[ ][*][ ][ ][ ][ ][*][*][*][ ]
[ ][ ][ ][ ][*][ ][ ][*][*][ ]
[ ][ ][ ][*][ ][ ][*][ ][*][ ]
[*][ ][*][*][ ][ ][*][ ][ ][ ]
[ ][*][ ][ ][ ][ ][ ][ ][*][ ]
[*][ ][ ][ ][*][ ][*][*][ ][*]
[ ][*][ ][ ][ ][ ][*][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][*]
[*][ ][ ][ ][ ][ ][*][ ][ ][*]
[ ][ ][ ][ ][*][*][ ][ ][*][ ]
t = 1
[ ][ ][ ][ ][*][ ][ ][ ][ ][*]
[ ][ ][ ][ ][ ][*][ ][ ][ ][*]
[ ][ ][*][ ][*][*][*][ ][*][*]
[ ][*][ ][*][ ][ ][ ][ ][ ][*]
[ ][ ][*][*][ ][*][*][ ][*][ ]
[ ][*][ ][ ][ ][*][*][ ][*][*]
[ ][ ][ ][ ][ ][*][*][*][*][*]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][*]
[*][ ][ ][ ][ ][*][ ][ ][*][ ]
[*][ ][ ][ ][ ][ ][ ][ ][ ][ ]

Posted feedbacks - SQL

まだ投稿されていないようなのでSQLで書いてみました。
Microsoft SQL Server 2005 で確認しています。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* 生存セルを格納する表: G=世代 */
CREATE TABLE LIFE (G INT, X INT, Y INT)

/* 周囲9セルを求めるための補助的な表 */
CREATE TABLE NEAR (X INT, Y INT)
INSERT INTO NEAR VALUES (-1, -1)
INSERT INTO NEAR VALUES ( 0, -1)
INSERT INTO NEAR VALUES ( 1, -1)
INSERT INTO NEAR VALUES (-1,  0)
INSERT INTO NEAR VALUES ( 0,  0)
INSERT INTO NEAR VALUES ( 1,  0)
INSERT INTO NEAR VALUES (-1,  1)
INSERT INTO NEAR VALUES ( 0,  1)
INSERT INTO NEAR VALUES ( 1,  1)

/* 初期配置 (グライダー) */
INSERT INTO LIFE VALUES (0, 1, 0)
INSERT INTO LIFE VALUES (0, 0, 1)
INSERT INTO LIFE VALUES (0, 0, 2)
INSERT INTO LIFE VALUES (0, 1, 2)
INSERT INTO LIFE VALUES (0, 2, 2)

/* 処理本体: 実行するたびにLIFE表に次世代を挿入します */
INSERT INTO LIFE
SELECT L1.G + 1, L1.X, L1.Y
FROM (SELECT L.G AS G, L.X + N.X AS X, L.Y + N.Y AS Y, COUNT(*) AS C
      FROM LIFE L, NEAR N
      WHERE L.G >= ALL(SELECT G FROM LIFE)
      GROUP BY L.G, L.X + N.X, L.Y + N.Y) L1
      LEFT JOIN LIFE L2 ON L2.G = L1.G AND L2.X = L1.X AND L2.Y = L1.Y
WHERE L1.C = 3 OR L2.G IS NOT NULL AND L1.C = 4

すごい。もっと評価されるべき。

ということで2次元に表示するSQLを作ってみました。
グライダーが実際に動いているのを見ると鳥肌モノです。sqliteのみでしか確認していませんが、caseの辺りを直せばどこでも動くと思います。

ちなみにsqliteはALLを使えないらしく、#5459 の28行目を max(G)に変えて問題なく動きました。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
create table LG_ROWS ( Y integer );
insert into LG_ROWS values (0);
insert into LG_ROWS values (1);
insert into LG_ROWS values (2);
insert into LG_ROWS values (3);
insert into LG_ROWS values (4);

select 0 SEDAI
     , case (CM3.G isnull) when 0 then "o" else " " end
     , case (CM2.G isnull) when 0 then "o" else " " end
     , case (CM1.G isnull) when 0 then "o" else " " end
     , case (CZ0.G isnull) when 0 then "o" else " " end
     , case (CP1.G isnull) when 0 then "o" else " " end
     , case (CP2.G isnull) when 0 then "o" else " " end
     , case (CP3.G isnull) when 0 then "o" else " " end
from LG_ROWS R
left join life CM3 on R.Y = CM3.Y and CM3.X = -3 and CM3.G = SEDAI
left join life CM2 on R.Y = CM2.Y and CM2.X = -2 and CM2.G = SEDAI
left join life CM1 on R.Y = CM1.Y and CM1.X = -1 and CM1.G = SEDAI
left join life CZ0 on R.Y = CZ0.Y and CZ0.X =  0 and CZ0.G = SEDAI
left join life CP1 on R.Y = CP1.Y and CP1.X =  1 and CP1.G = SEDAI
left join life CP2 on R.Y = CP2.Y and CP2.X =  2 and CP2.G = SEDAI
left join life CP3 on R.Y = CP3.Y and CP3.X =  3 and CP3.G = SEDAI
order by R.Y;

Index

Feed

Other

Link

Pathtraq

loading...