Rubyで組み合わせと順列

Array#combination(組み合わせ)

Arrayからn個の組み合わせを取り出すことができる
ruby-1.9.2-p0 > array = [1,2,3]
 => [1, 2, 3] 
ruby-1.9.2-p0 > array.combination(2)
 => #<Enumerator: [1, 2, 3]:combination(2)> 
ruby-1.9.2-p0 > array.combination(2).to_a
 => [[1, 2], [1, 3], [2, 3]] 

Array#product(順列)

複數のArrayの順列
ruby-1.9.2-p0 > array = [0,1,2,3]
 => [0, 1, 2, 3] 
ruby-1.9.2-p0 > array.product(array)
 => [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]] 

これで何をしたかったのかというと多次元配列(Narray)において、ある座標?(2,2)とかの近傍値の計算を順列で計算出来ないかなと思ったわけです。

たとえば

0,0 1,0 2,0
0,1 1,1 2,1
0,2 1,2 2,2

だとして(1,1)の8近傍の座標を知りたい時に
(1,1)の値をそれぞれ+-1する。
(0,0) (2,2)
その時
0~2の値の順列が全座標と等しくなるので

ruby-1.9.2-p0 > array = (0..2).to_a
 => [0, 1, 2] 
ruby-1.9.2-p0 > array.product(array)
 => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]] 

のそれぞれの座標に対して処理を与えればよいです。

ただ適応出来ない場合もあります

その後一般化

これまでのだと座標が(1,1)のように同じでないと使い物にならないので、こうします

ruby-1.9.2-p0 > narray = NArray.float(4,4).collect{rand(10)}
 => NArray.float(4,4): 
[ [ 2.0, 7.0, 5.0, 8.0 ], 
  [ 2.0, 8.0, 4.0, 6.0 ], 
  [ 8.0, 1.0, 8.0, 2.0 ], 
  [ 1.0, 4.0, 9.0, 4.0 ] ] 
ruby-1.9.2-p0 > narray[2,1]
 => 4.0 

4x4のグラフから座標(2,1)の8近傍を取りたい場合
2-1と2+1で横軸を1~3として
1-1と1+1で縦軸を0~2とする。
その上で

ruby-1.9.2-p0 > w = (1..3).to_a
 => [1, 2, 3] 
ruby-1.9.2-p0 > h =(0..2).to_a
 => [0, 1, 2] 
ruby-1.9.2-p0 > w.product(h)
 => [[1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2], [3, 0], [3, 1], [3, 2]] 

でいける