On 09/12/2011 01:36 PM, bearophile wrote:
A more complex version that does't yield distinct sub-arrays to allocate less 
memory:


import std.stdio, std.array, std.range;

struct PowerSet(T) {
     T[] items;

     int opApply(int delegate(ref T[]) dg) {
         int result;
         T[] res;
         T[30] buf;

         if (!items.length) {
             result = dg(res);
         } else {
             outer:
             foreach (opt; [items[0..1], []]) {
                 buf[0 .. opt.length] = opt[];
                 foreach (r; PowerSet(items[1..$])) {
                     buf[opt.length .. opt.length + r.length] = r[];
                     res = buf[0 .. (opt.length + r.length)];
                     result = dg(res);
                     if (result) break outer;
                 }
             }
         }

         return result;
     }
}

void main() {
     size_t count;
     foreach (x; PowerSet!int(array(iota(22))))
         count++;
     writeln(count);
}


This runs in about 4.5 seconds, and uses less than 10 MB RAM.


You lose vs haskell because haskell does not recompute the same PowerSet multiple times.

Reply via email to