ライフゲーム

最近 R を触ってなかったので、リハビリがてらにhttp://ja.wikipedia.org/wiki/ライフゲーム:セルオートマトンを書いてみる。
ライフゲームを選んだのは、「部分行列アクセスを使えば簡単かも」と思ったから。

life_game <- function(x=40, y=40) {
	m  <- matrix(sample(c(rep(0,9),1),x*y,TRUE), y, x)
	
	nextstep <- function(m) {
		#上下左右をつなげる
		m1 <- rbind(m[nrow(m),], m, m[1,])
		m1 <- cbind(m1[,ncol(m1)], m1, m1[,1])
		outer(1:nrow(m), 1:ncol(m), function(vi,vj) {
			mapply( function(i,j) {
				#部分行列ごとに生きてるセル数を計算
				living <- sum( m1[i:(i+2), j:(j+2)] )
				if (living == 3) { 1 }
				else if (living == 4) { m[i,j] }
				else { 0 }
			}, vi, vj)
		})
	}

	function(n=100) {
		for (i in 1:n) {
			m <- nextstep(m)
			image(m)
		}
	}
}

f <- life_game()
f()

お手軽にできたけど、もとの行列の上下左右に行と列をくっつけてるあたりが、かっこ悪い。
しかも、outer のなかで apply 使ってるから計算量も多そう。
もう少し速度アップしてみるか。