Few things II
Oskar Linde
oskar.lindeREM at OVEgmail.com
Thu Aug 16 02:43:25 PDT 2007
bearophile wrote:
> In the meantime I have found some problems translating lazy recursive generators from Py=>D, like this one, that yields the combinations of the given items, taking k distinct elements (this kind of code may look slow). You may help me:
>
> def xcombinations(items, k):
> if k:
> for i in xrange(len(items) - k + 1):
> for cc in xcombinations(items[i+1:], k-1):
> yield [items[i]] + cc
> else:
> yield []
>
> Usage example:
> xcombinations("abcd", 1) ==> "a" "b" "c" "d"
> xcombinations("abcd", 2) ==> "ab" "ac" "ad" "bc" "bd" "cd"
> xcombinations("abcd", 3) ==> "abc" "abd" "acd" "bcd"
As far as I can tell, the following should work. Maybe I am missing
something fundamental, as this is just a straight forward implementation
of the above. Note that yield(x) is:
{ auto tmp = x; if (auto r = dg(tmp)) return r; }
(Might be a nice macro in the future.)
Code:
struct XRange {
int n;
int opApply(int delegate(inout int v) dg) {
for (int i = 0; i < n; i++)
if (auto r = dg(i)) return r;
return 0;
}
}
XRange xrange(int n) { XRange r; r.n = n; return r; }
struct XCombinations(T) {
T[] items;
int k;
int opApply(int delegate(inout T[] arr) dg) {
if (k > 0)
foreach (i; xrange(items.length - k + 1))
foreach(cc; xcombinations(items[i+1..$], k-1)) {
auto tmp = items[i] ~ cc; // must be an lvalue
if (auto r = dg(tmp)) return r;
}
else {
T[] tmp = null; // need an lvalue
return dg(tmp);
}
return 0;
}
}
XCombinations!(T) xcombinations(T)(T[] items, int k) {
XCombinations!(T) ret;
ret.items = items;
ret.k = k;
return ret;
}
--
Oskar
More information about the Digitalmars-d
mailing list