A bit more d-ified and uses foreach + foreach_reverse without allocating an array.

```d
import std.stdio;

void main()
{
    doRepetition(4, 3);
    writeln("==========");
    doRepetitionReversed(4, 3);
}

void doRepetition(const int n, const int m)
{
    // combination total number is m,  element is repeatable.
    assert(n >= 1 && n < 10);
    assert(m >= 1 && m < 10);
    enum N = 10;
    ubyte[10] a;
    void inc(int index, int r, int start, int end)
    {
        if (index == r)
        {
            // get one unique combination result, not repeatable
            foreach (j; 0 .. r)
            {
                writef!"%d "(a[j]);
            }
            writeln;
            return;
        }

        foreach (i; start .. end)
        {
            a[index] = cast(ubyte) i;
            inc(index + 1, r, i, end);
        }
    }

    inc(0, m, 0, n);
}

void doRepetitionReversed(const int n, const int m)
{
    // combination total number is m,  element is repeatable.
    assert(n >= 1 && n < 10);
    assert(m >= 1 && m < 10);
    enum N = 10;
    ubyte[10] a;
    void inc(int index, int r, int start, int end)
    {
        if (index == r)
        {
            // get one unique combination result, not repeatable
            foreach_reverse (j; 0 .. r)
            {
                writef!"%d "(a[j]);
            }
            writeln;
            return;
        }

        foreach_reverse (i; start .. end)
        {
            a[index] = cast(ubyte) i;
            inc(index + 1, r, i, end);
        }
    }

    inc(0, m, 0, n);
}
```

Output:

```
0 0 0
0 0 1
0 0 2
0 0 3
0 1 1
0 1 2
0 1 3
0 2 2
0 2 3
0 3 3
1 1 1
1 1 2
1 1 3
1 2 2
1 2 3
1 3 3
2 2 2
2 2 3
2 3 3
3 3 3
==========
3 3 3
3 3 2
3 2 2
2 2 2
3 3 1
3 2 1
2 2 1
3 1 1
2 1 1
1 1 1
3 3 0
3 2 0
2 2 0
3 1 0
2 1 0
1 1 0
3 0 0
2 0 0
1 0 0
0 0 0
```

Reply via email to