RosettaCodeData/Task/Generator-Exponential/D/generator-exponential-3.d

48 lines
1.1 KiB
D

import std.stdio, std.bigint, std.range, std.algorithm;
struct Filtered(R1, R2) if (is(ElementType!R1 == ElementType!R2)) {
R1 s1;
R2 s2;
alias ElementType!R1 T;
T front, source, filter;
this(R1 r1, R2 r2) {
s1 = r1;
s2 = r2;
source = s1.front;
filter = s2.front;
popFront;
}
static immutable empty = false;
void popFront() {
while (true) {
if (source > filter) {
s2.popFront;
filter = s2.front;
continue;
} else if (source < filter) {
front = source;
s1.popFront;
source = s1.front;
break;
}
s1.popFront;
source = s1.front;
}
}
}
auto filtered(R1, R2)(R1 r1, R2 r2) // Helper function.
if (isInputRange!R1 && isInputRange!R2 &&
is(ElementType!R1 == ElementType!R2)) {
return Filtered!(R1, R2)(r1, r2);
}
void main() {
auto squares = 0.sequence!"n".map!(i => i.BigInt ^^ 2);
auto cubes = 0.sequence!"n".map!(i => i.BigInt ^^ 3);
filtered(squares, cubes).drop(20).take(10).writeln;
}