ベキ集合

とある数学パズルを解く最中にベキ集合を取得するための算出プロパティを書いたので、メモ。
もっともそもそものパズルは設問を誤解していて、ベキ集合では不十分だったんですが…

ArrayList.metaClass.getPowerSet = {->
    if (delegate.size == 0) return [[]];
    
    def last = delegate[-1]
    (delegate[0..<delegate.size-1] as ArrayList).powerSet.with {
        delegate + delegate.collect{it + last}
    }
}

これで、ArrayListインスタンスに読み取り専用のpowerSetプロパティ(算出プロパティ)が定義出来ました。

[1,2,4,8].powerSet.each{println "${it.sum(0)}: $it"}

と2の乗数を使って確認してみると、結果は

0: []
1: [1]
2: [2]
3: [1, 2]
4: [4]
5: [1, 4]
6: [2, 4]
7: [1, 2, 4]
8: [8]
9: [1, 8]
10: [2, 8]
11: [1, 2, 8]
12: [4, 8]
13: [1, 4, 8]
14: [2, 4, 8]
15: [1, 2, 4, 8]

ちゃんとベキ集合になっているようです。
ほんとは集合なんでpowerSetを定義先するのも戻り値もSetの方が良いんですけど、ちょっとSetだと色々めんどくさいんで手を抜きました^^ゞ