www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - please help me to reverse a function call order

reply Test123 <test123 gmail.com> writes:
I has this function, it print all possible combinations.

```d
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
             for(int j =0; j < r; j++ ){
                 printf("%d ", a[j]);
             }
             printf("\n");
             return ;
         }
         for (int i = start; i < end; i++) {
             a[index] = cast(ubyte)i;
             inc(index + 1, r, i, end);
         }
     }
     inc(0, m, 0, n);
}
```

`doRepetition(4, 3);` will print
```sh
0 0
0 1
0 2
1 1
1 2
2 2
```


I need one function,  print the number in reversed order like 
this:

`doReverseRepetition(4, 3);` will print
```sh
2 2
1 2
1 1
0 2
0 1
0 0
```

ont solution is to put the result in array, and foreach_reverse 
it.  but this is slow and need a lot memory when N, M is bigger. 
(9,9) will have 24310 restuls combinations. (I need support 
bigger N,M late and need it fast)

Any one can help me to write a function print the reversed order 
results?
Jul 23 2022
next sibling parent Test123 <test123 gmail.com> writes:
On Saturday, 23 July 2022 at 19:50:51 UTC, Test123 wrote:
 I has this function, it print all possible combinations.

 ```d
 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
             for(int j =0; j < r; j++ ){
                 printf("%d ", a[j]);
             }
             printf("\n");
             return ;
         }
         for (int i = start; i < end; i++) {
             a[index] = cast(ubyte)i;
             inc(index + 1, r, i, end);
         }
     }
     inc(0, m, 0, n);
 }
 ```

 `doRepetition(4, 3);` will print
 ```sh
 0 0
 0 1
 0 2
 1 1
 1 2
 2 2
 ```


 I need one function,  print the number in reversed order like 
 this:

 `doReverseRepetition(4, 3);` will print
 ```sh
 2 2
 1 2
 1 1
 0 2
 0 1
 0 0
 ```

 ont solution is to put the result in array, and foreach_reverse 
 it.  but this is slow and need a lot memory when N, M is 
 bigger. (9,9) will have 24310 restuls combinations. (I need 
 support bigger N,M late and need it fast)

 Any one can help me to write a function print the reversed 
 order results?
On Saturday, 23 July 2022 at 19:50:51 UTC, Test123 wrote: The give example result is `doRepetition(3, 2);`. `doRepetition(4, 3);` restuls is: ```sh 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 ``` N is the unique number as results combination element. result combination total emenent number is M.
Jul 23 2022
prev sibling next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
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
```
Jul 23 2022
next sibling parent Test123 <test123 gmail.com> writes:
On Saturday, 23 July 2022 at 20:00:06 UTC, rikki cattermole wrote:
 A bit more d-ified and uses foreach + foreach_reverse without 
 allocating an array.

 [...]
Thanks for the quick reply. I also get your results, it is not correct because the secends number is not matched. Not I look at your number, I find out just need change `a[index] = cast(ubyte) i;` to `a[m-index] = cast(ubyte) i;` will get the expect results. Thanks for the help.
Jul 23 2022
prev sibling parent Test123 <test123 gmail.com> writes:
On Saturday, 23 July 2022 at 20:00:06 UTC, rikki cattermole wrote:
 A bit more d-ified and uses foreach + foreach_reverse without 
 allocating an array.

 [...]
Your give the correct code, but wrong Output. Thanks again for the help.
Jul 23 2022
prev sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 23 July 2022 at 19:50:51 UTC, Test123 wrote:
 I has this function, it print all possible combinations.

 ```d
 void doRepetition(const int n, const int m){
     // combination total number is m,  element is repeatable.
     // ...
 }
 ```

 `doRepetition(4, 3);` will print

 0 0
 0 1
 0 2
 1 1
 1 2
 2 2
Do I misunderstand? In function parameters, m is a base, n is a power; is it true? If so, it is calculated according to the formula 2ⁿ as we know between 0 and 1, but here m can be larger. Then there are 64 possibilities for doRepetition(3, 6) But your code has 28 possibilities, I guess I didn't read the code correctly. **My code outputs:** ``` [0, 0, 0, 0, 0, 0, 0, 0]: 1 [0, 0, 0, 0, 0, 0, 0, 1]: 2 [0, 0, 0, 0, 0, 0, 1, 0]: 3 [0, 0, 0, 0, 0, 0, 2, 1]: 4 [0, 0, 0, 0, 0, 1, 1, 0]: 5 [0, 0, 0, 0, 0, 2, 0, 1]: 6 [0, 0, 0, 0, 0, 2, 1, 0]: 7 [0, 0, 0, 0, 0, 2, 2, 1]: 8 [0, 0, 0, 0, 1, 1, 1, 0]: 9 [0, 0, 0, 0, 2, 0, 0, 1]: 10 [0, 0, 0, 0, 2, 0, 1, 0]: 11 [0, 0, 0, 0, 2, 0, 2, 1]: 12 [0, 0, 0, 0, 2, 1, 1, 0]: 13 [0, 0, 0, 0, 2, 2, 0, 1]: 14 [0, 0, 0, 0, 2, 2, 1, 0]: 15 [0, 0, 0, 0, 2, 2, 2, 1]: 16 [0, 0, 0, 1, 1, 1, 1, 0]: 17 [0, 0, 0, 2, 0, 0, 0, 1]: 18 [0, 0, 0, 2, 0, 0, 1, 0]: 19 [0, 0, 0, 2, 0, 0, 2, 1]: 20 [0, 0, 0, 2, 0, 1, 1, 0]: 21 [0, 0, 0, 2, 0, 2, 0, 1]: 22 [0, 0, 0, 2, 0, 2, 1, 0]: 23 [0, 0, 0, 2, 0, 2, 2, 1]: 24 [0, 0, 0, 2, 1, 1, 1, 0]: 25 [0, 0, 0, 2, 2, 0, 0, 1]: 26 [0, 0, 0, 2, 2, 0, 1, 0]: 27 [0, 0, 0, 2, 2, 0, 2, 1]: 28 [0, 0, 0, 2, 2, 1, 1, 0]: 29 [0, 0, 0, 2, 2, 2, 0, 1]: 30 [0, 0, 0, 2, 2, 2, 1, 0]: 31 [0, 0, 0, 2, 2, 2, 2, 1]: 32 [0, 0, 1, 1, 1, 1, 1, 0]: 33 [0, 0, 2, 0, 0, 0, 0, 1]: 34 [0, 0, 2, 0, 0, 0, 1, 0]: 35 [0, 0, 2, 0, 0, 0, 2, 1]: 36 [0, 0, 2, 0, 0, 1, 1, 0]: 37 [0, 0, 2, 0, 0, 2, 0, 1]: 38 [0, 0, 2, 0, 0, 2, 1, 0]: 39 [0, 0, 2, 0, 0, 2, 2, 1]: 40 [0, 0, 2, 0, 1, 1, 1, 0]: 41 [0, 0, 2, 0, 2, 0, 0, 1]: 42 [0, 0, 2, 0, 2, 0, 1, 0]: 43 [0, 0, 2, 0, 2, 0, 2, 1]: 44 [0, 0, 2, 0, 2, 1, 1, 0]: 45 [0, 0, 2, 0, 2, 2, 0, 1]: 46 [0, 0, 2, 0, 2, 2, 1, 0]: 47 [0, 0, 2, 0, 2, 2, 2, 1]: 48 [0, 0, 2, 1, 1, 1, 1, 0]: 49 [0, 0, 2, 2, 0, 0, 0, 1]: 50 [0, 0, 2, 2, 0, 0, 1, 0]: 51 [0, 0, 2, 2, 0, 0, 2, 1]: 52 [0, 0, 2, 2, 0, 1, 1, 0]: 53 [0, 0, 2, 2, 0, 2, 0, 1]: 54 [0, 0, 2, 2, 0, 2, 1, 0]: 55 [0, 0, 2, 2, 0, 2, 2, 1]: 56 [0, 0, 2, 2, 1, 1, 1, 0]: 57 [0, 0, 2, 2, 2, 0, 0, 1]: 58 [0, 0, 2, 2, 2, 0, 1, 0]: 59 [0, 0, 2, 2, 2, 0, 2, 1]: 60 [0, 0, 2, 2, 2, 1, 1, 0]: 61 [0, 0, 2, 2, 2, 2, 0, 1]: 62 [0, 0, 2, 2, 2, 2, 1, 0]: 63 [0, 0, 2, 2, 2, 2, 2, 1]: 64 ``` SDB 79
Jul 23 2022
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 23 July 2022 at 22:50:55 UTC, Salih Dincer wrote:
 **My code outputs:**
 ```
 [0, 0, 0, 0, 0, 0, 0, 0]: 1
 [0, 0, 0, 0, 0, 0, 0, 1]: 2
 [0, 0, 0, 0, 0, 0, 1, 0]: 3
 [0, 0, 0, 0, 0, 0, 2, 1]: 4
 [0, 0, 0, 0, 0, 1, 1, 0]: 5
 [0, 0, 0, 0, 0, 2, 0, 1]: 6
 [0, 0, 0, 0, 0, 2, 1, 0]: 7
 [0, 0, 0, 0, 0, 2, 2, 1]: 8
 ```
I guess my code didn't list all possibilities either. Moreover, the m and n parameters will be swapped:
 ```
 [ 0, 0, 0 ]: 1*
 [ 0, 0, 1 ]: 2*
 [ 0, 0, 2 ]: 3
 [ 0, 1, 0 ]: 4*
 [ 0, 1, 1 ]: 5
 [ 0, 1, 2 ]: 6
 [ 0, 2, 0 ]: 7
 [ 0, 2, 1 ]: 8*
 [ 0, 2, 2 ]: 9
 [ 1, 0, 0 ]: 10
 [ 1, 0, 1 ]: 11
 [ 1, 0, 2 ]: 12
 [ 1, 1, 0 ]: 13*
 [ 1, 1, 1 ]: 14
 [ 1, 1, 2 ]: 15
 [ 1, 2, 0 ]: 16
 [ 1, 2, 1 ]: 17
 [ 1, 2, 2 ]: 18
 [ 2, 0, 0 ]: 19
 [ 2, 0, 1 ]: 20*
 [ 2, 0, 2 ]: 21
 [ 2, 1, 0 ]: 22*
 [ 2, 1, 1 ]: 23
 [ 2, 1, 2 ]: 24
 [ 2, 2, 0 ]: 25
 [ 2, 2, 1 ]: 26*
 [ 2, 2, 2 ]: 27
 ```
**PS.** * marked from version(c) in the above list is from version(b). SDB 79
Jul 23 2022
parent reply Test123 <test123 gmail.com> writes:
On Saturday, 23 July 2022 at 23:14:03 UTC, Salih Dincer wrote:
 On Saturday, 23 July 2022 at 22:50:55 UTC, Salih Dincer wrote:
 [...]
I guess my code didn't list all possibilities either. Moreover, the m and n parameters will be swapped:
 [...]
**PS.** * marked from version(c) in the above list is from version(b). SDB 79
Can you share your code ? The restuls is position unrelated.
Jul 24 2022
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Sunday, 24 July 2022 at 08:16:41 UTC, Test123 wrote:
 On Saturday, 23 July 2022 at 23:14:03 UTC, Salih Dincer wrote:
 On Saturday, 23 July 2022 at 22:50:55 UTC, Salih Dincer wrote:
 [...]
I guess my code didn't list all possibilities either. Moreover, the m and n parameters will be swapped:
 [...]
**PS.** * marked from version(c) in the above list is from version(b). SDB 79
Can you share your code ? The restuls is position unrelated.
Everyone has it, the classic permutation codes.There should even be something in the standard library? I didn't share because I didn't know what you looking for. But you know this classic recurisive function: ```d void permut(T)(T[] x, ref int count, int start = 0) { auto len = cast(int)x.length; if(start != len) { for(int i = start; i < len; i++) { x[start].swap(x[i]); x.permut(count, start + 1); x[start].swap(x[i]); } } else if(len < 9) x.writeln(": ", ++count); else ++count; // ^---a lot of output } void swap(T)(ref T x, ref T y) { auto t = y; y = x; x = t; } T factorial(T)(in T n) pure nothrow nogc in(n < 21, "The number is a very large for ulongMax") { return n > 1 ? n * factorial(n - 1) : 1; } unittest { assert (factorial!int(12) == 479001600); } import std.range, std.stdio; void main() { int totalCount, n = 3; iota(1, n + 1).array.permut(totalCount); totalCount.writeln(" permutation found..."); assert(totalCount == n.factorial); } ``` **PS.** I added extra factorial `assert()`... SDB 79
Jul 24 2022
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Sunday, 24 July 2022 at 15:11:45 UTC, Salih Dincer wrote:
 ...But you know this classic recurisive function:
The `permut()` function works with many types, for example `char`. Look at probability 40: 😀 ```d void main() { int totalCount; ['a', 'd', 'g', 'l', 'n'].permut(totalCount); totalCount.writeln(" permutation found..."); } /* Output: ... dagln: 25 dagnl: 26 dalgn: 27 dalng: 28 danlg: 29 dangl: 30 dgaln: 31 dganl: 32 dglan: 33 dglna: 34 dgnla: 35 dgnal: 36 dlgan: 37 dlgna: 38 dlagn: 39 dlang: 40 dlnag: 41 dlnga: 42 dngla: 43 dngal: 44 dnlga: 45 dnlag: 46 dnalg: 47 dnagl: 48 ... 120 permutation found... Process finished. ``` SDB
Jul 24 2022
parent reply test123 <test123 gmail.com> writes:
On Sunday, 24 July 2022 at 15:49:51 UTC, Salih Dincer wrote:
 On Sunday, 24 July 2022 at 15:11:45 UTC, Salih Dincer wrote:
 ...But you know this classic recurisive function:
The `permut()` function works with many types, for example `char`. Look at probability 40: 😀 ```d void main() { int totalCount; ['a', 'd', 'g', 'l', 'n'].permut(totalCount); totalCount.writeln(" permutation found..."); } /* Output: ... dagln: 25 dagnl: 26 dalgn: 27 dalng: 28 danlg: 29 dangl: 30 dgaln: 31 dganl: 32 dglan: 33 dglna: 34 dgnla: 35 dgnal: 36 dlgan: 37 dlgna: 38 dlagn: 39 dlang: 40 dlnag: 41 dlnga: 42 dngla: 43 dngal: 44 dnlga: 45 dnlag: 46 dnalg: 47 dnagl: 48 ... 120 permutation found... Process finished. ``` SDB
not match by: 1) the element is not repeat 2) the element is position related
Jul 24 2022
parent reply Salih Dincer <salihdb hotmail.com> writes:
On Monday, 25 July 2022 at 04:23:16 UTC, test123 wrote:
 not match by:

 1) the element is not repeat

 2) the element is position related
I got it now. So what good are such repetitive probabilities? Thanks... SDB 79
Jul 25 2022
parent Test123 <test123 gmail.com> writes:
On Monday, 25 July 2022 at 21:43:37 UTC, Salih Dincer wrote:
 On Monday, 25 July 2022 at 04:23:16 UTC, test123 wrote:
 not match by:

 1) the element is not repeat

 2) the element is position related
I got it now. So what good are such repetitive probabilities? Thanks... SDB 79
just try a stupid game.
Jul 26 2022