たけ(tk)です

[ruby-list:42665] 組み合わせを作るrubyらしい方法 にて
しん <dezawa / aliadne.net> さん曰く:

>  [1,2,3,4].conbination(2)   => [ [1,2],[1,3],[1,4],[2,3],[2,4],[3,4] ]
>  [1,2,3].conbination([4,5]) => [ [1,4],[1,5],[2,4],[2,5],[3,4],[3,5] ]
> 
> こんな結果を帰すものを ruby的に作るにはどうしたものでしょうか。

ruby的かどうか分かりませんが、楽しんでみました。

----
class Array

def combination(array2)
  ret = []
  each{|item1|
    array2.each{|item2|
      ret.push([item1,item2])
    }
  }
  ret
end

@@combi_indices_hash = {}
def combi_indices(s,n)
  ret = @@combi_indices_hash[s] ||= []
  if ret.empty?
    s.times{|i|
      ret.dup.each{|a|
        ret.push(a+[i])
      }
      ret.push([i])
    }
  end
  ret.select{|a|a.size==n}
end

def combinationN(n)
  combi_indices(self.size,n).collect{|a| self.values_at(*a)}
end

end

p [:a,:b,:c].combination([:d,:e])  #=> [[:a, :d], [:a, :e], [:b, :d], [:b, :e], [:c, :d], [:c, :e]]

p [:r,:u,:b,:y].combinationN(0) #=> []
p [:r,:u,:b,:y].combinationN(1) #=> [[:r], [:u], [:b], [:y]]
p [:r,:u,:b,:y].combinationN(2) #=> [[:r, :u], [:r, :b], [:u, :b], [:r, :y], [:u, :y], [:b, :y]]
p [:r,:u,:b,:y].combinationN(3) #=> [[:r, :u, :b], [:r, :u, :y], [:r, :b, :y], [:u, :b, :y]]
p [:r,:u,:b,:y].combinationN(4) #=> [[:r, :u, :b, :y]]
p [:r,:u,:b,:y].combinationN(5) #=> []
----

> 今までは 多重の each のネストの中で処理をやっていたのですが、
> 今回、
>   前者の例で、組み合わせが 2 となったり 3となったり
>   ダイナミック変ってしまうので、汚くなる。
> 
>   ブロック渡しを憶えようとしてるので、こういうのがあると嬉しい。
> 
> ってところです。
> 多重の each で配列に入れて行けば出来るのですが、それは面白みがないかなぁ
> ということで。
> 
> パラメータの与え方ではエライ事になるのは承知してます。

Take_tk = KUMAGAI Hidetake
たけ(tk)=熊谷秀武