2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Juliaでライフゲームone - liner

Posted at

ライフゲームについては既知とします。必要ならWikipediaの記事を見てください。

結論

一世代計算するワンライナーです。

life(w) = let sz = size(w); let v1 = fill(0, sz[1]-2), v2 = fill(0, sz[2]); [v2'; v1 [w[i-1:i+1, j-1:j+1] .* [1 1 1;1 9 1;1 1 1] |> sum for i in 2:sz[1]-1, j in 2:sz[2]-1] .|> (a -> ((a==3 || a==11 || a==12) && return 1; return 0)) v1; v2'] end end

REPLにコピペすれば動きます。0が死んでいるセル、1が生きているセルを示します。

実行例

スクリーンショット 2023-01-17 15.42.36.png

解説

1.let sz = size(w); ... end

入力配列の大きさは何回も使うのでletブロックで事前定義

2.let v1 = fill(0, sz[1]-2), v2 = fill(0, sz[2]); ... end

行列をパディングする(後述)時に使う配列

3.w[i-1:i+1, j-1:j+1] .* [1 1 1;1 9 1;1 1 1]

入力行列から$3 \times 3$の大きさの行列を切り出し、行列

\begin{matrix}
 1&1&1\\
 1&9&1\\
 1&1&1
\end{matrix}

との要素ごとの積を取る。

4.|> sum

3.で求めた行列の要素を足し上げる。つまり畳み込み和(convolution sum)を計算している。

5.for i in 2:sz[1]-1, j in 2:sz[2]-1

3.、4.の計算を、入力行列の外周を除く要素で行う。

6..|> (a -> ((a==3 || a==11 || a==12) && return 1; return 0))

5.の結果できた行列の各要素に対し、次のような関数を適用する。

3  -> 1
11 -> 1
12 -> 1
_  -> 0

Juliaにswitch/case式やパターンマッチの構文は無いが、短絡評価する演算子&&で似たようなことができる。
行列[1 1 1;1 9 1;1 1 1]と、この関数でライフゲームのルールを表現していることになる。

7.[v2'; v1 ... v1; v2']

これが無いと、入力の大きさ(m,n)に対し、出力が(m-2, n-2)になってしまう。ので、周辺を0でパディングする。(もっとうまい方法がある気がするが...)

画像・動画にしたい?

例えば、Plots.heatmap()で画像にして、そのままPlotsで動画にするのがお手軽で良いんじゃ無いんでしょうか。

参考文献

Conway's Game of Life - APL Wiki

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?