[Issue 12007] cartesianProduct does'nt work with immutable ranges

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Jan 27 01:06:29 PST 2014


https://d.puremagic.com/issues/show_bug.cgi?id=12007



--- Comment #2 from matovitch <camille.brugel at laposte.net> 2014-01-27 01:06:27 PST ---
I found an ugly workaround for finite ranges (using cycle([a]) instead of
repeat(a)) :

import std.algorithm;
import std.range;
import std.stdio;

auto myCartesianProduct(R1, R2)(R1 range1, R2 range2)
{
    static if (isInfinite!R1 && isInfinite!R2)
    {
        static if (isForwardRange!R1 && isForwardRange!R2)
        {
            // This algorithm traverses the cartesian product by alternately
            // covering the right and bottom edges of an increasing square area
            // over the infinite table of combinations. This schedule allows us
            // to require only forward ranges.
            return zip(sequence!"n"(cast(size_t)0), range1.save, range2.save,
                       repeat(range1), repeat(range2))
                .map!(function(a) => chain(
                    zip(repeat(a[1]), take(a[4].save, a[0])),
                    zip(take(a[3].save, a[0]+1), repeat(a[2]))
                ))()
                .joiner();
        }
        else static assert(0, "cartesianProduct of infinite ranges requires "~
                              "forward ranges");
    }
    else static if (isInputRange!R2 && isForwardRange!R1 && !isInfinite!R1)
    {
        return joiner(map!((ElementType!R2 a) => zip(range1.save, cycle([a])))
                          (range2));
    }
    else static if (isInputRange!R1 && isForwardRange!R2 && !isInfinite!R2)
    {
        return joiner(map!((ElementType!R1 a) => zip(cycle([a]), range2.save))
                          (range1));
    }
    else static assert(0, "cartesianProduct involving finite ranges must "~
                          "have at least one finite forward range");
}

void main() 
{
    immutable int[] A = [1,2,3];
    immutable int[] B = [4,5,6];

    auto AB = myCartesianProduct(A,B);

    writeln(AB);
}

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list