APL で書かれたライフゲームをネタに R に初挑戦


id:sumim:20090216:p2 の続き。

最近データ処理や統計処理に適した言語としてにわかに注目を集めている「R」など、APLのように配列やベクトルの処理を得意とする言語もある。

未来の言語は「APL」? Rubyのまつもと氏が講演 − @IT

mrkn: APL って意外と無名なんだね。R を一緒にするのはどうかなぁ・・・R は配列が第一級オブジェクトなだけで、配列演算が第一級なわけじゃないよ。その証拠に R で裏の計算アルゴリズムを並列化するのはとても大変!

はてなブックマーク - 未来の言語は「APL」? Rubyのまつもと氏が講演 − @IT


くだんの記事と id:mrkn のブクマコメントにこのような言及があって、R がどんなふうな言語のかに興味をもったので書いてみました。なにぶん初 R ですので、つたない点はご容赦を…。それと、もとの APL から Smalltalkへの意訳のさらに Ruby訳を経由した R 版なので本来 R の良さが活かされてないと思います(実際、期待していたほどは簡潔に書けなかったような気もするので…^^;)。もっとスマートにこんなふうに書けるぜ!的サジェスチョンもいただければ幸いです。

arr1 = t(array(1:9, c(3,3)))
arr1 = Reduce("+", Map(function(x) arr1==x, c(2,3,4,5,8)))
arr2 = array(0, c(5,5))
arr2[2:4,2:4] <- arr1

life = function(ome){
  omes <- Map(function(dx) ome[,((1:ncol(ome)+dx-1) %% ncol(ome))+1], -1:1)
  omes2 <- Map(function(ome2)
    Map(function(dy) ome2[((1:nrow(ome2)+dy-1) %% nrow(ome2))+1,], -1:1), omes)
  sum <- Reduce("+", unlist(omes2, recursive=FALSE))
  Reduce("+", Map(function(i) Map(function(ea) sum==ea, 3:4)[[i]] & list(1, ome)[[i]], 1:2))
}

arr2

#=>
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    0    0    0
#[2,]    0    0    1    1    0
#[3,]    0    1    1    0    0
#[4,]    0    0    1    0    0
#[5,]    0    0    0    0    0

life(arr2)

#=>
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    0    0    0
#[2,]    0    1    1    1    0
#[3,]    0    1    0    0    0
#[4,]    0    1    1    0    0
#[5,]    0    0    0    0    0