DOCOMB - Werner - 10-05-2012
DOCOMB will evaluate <ob> for every combination of <n> elements from list <L>. Usage is similar to DOLIST and DOSUBS:
Input:
3: L list of objects
2: n number of elements to be taken each time
1: ob object to be evaluated
Output: ob evaluated for each of the COMB(s,n) combinations of n elements of L
@ DOCOMB 230.5_Bytes # 1997h (48G)
\<<
ROT DUP SIZE 1 + 0
\-> ob L s DoC
\<<
{}
{ OVER 1 -
\-> t n
\<<
s 1 -
IF n
THEN FOR s n L s GET 1 \->LIST t + DoC EVAL NEXT
ELSE FOR s L s GET t LIST\-> DROP ob EVAL NEXT
END
\>>
} DUP 'DoC' STO EVAL
\>>
\>>
examples:
{ 11 22 33 44 }
3
\<< 3 \->LIST \>>
DOCOMB
results in
{ 11 22 33 }
{ 11 22 44 }
{ 11 33 44 }
{ 22 33 44 }
0
{ (0,3) (0,0) (4,0) (3,4) (4,3) }
2
\<< - ABS MAX \>>
DOCOMB
results in 5
Cheers, Werner
Edited: 6 Oct 2012, 1:38 p.m. after one or more responses were posted
Re: DOCOMB - Gilles Carpentier - 10-05-2012
Hi Werner,
Well done ! The problem is that recursivity is very slow in User RPL.
Perhaps is there a way to avoid recursivity ?
It would be great to have such a thing in SysRPL (why not in the Gofer List Library) but a will prefer an output in _one_ list of list.
I think it s not a good idea to have program wich return a variable number of items on the stack
Ex :
{ 11 22 33 44 }
3 << >>
DOCOMB
results in
{{ 11 22 33 }
{ 11 22 44 }
{ 11 33 44 }
{ 22 33 44 }}
PS : I never understood why RPL creators did not DOSUBS with n parameters to work like this :
{ 1 2 3 4 } 2 << R->C >> DOSUBS
{ (1 2) (3 4)}
Edited: 5 Oct 2012, 5:42 p.m.
Re: DOCOMB - C.Ret - 10-06-2012
RE: P.S.
Or at least propose a multidimentional version of DOSUB as done with DUP or DROP :
{ 1 2 3 4 5 6 } « SQ » DOSUB returns { 1 4 9 16 25 36 }
{ 1 2 3 4 5 6 } « R->C » DOSUB2 returns { (1 2) (3 4) (5 6) }
{ 1 2 3 4 5 6 } « 3 ->ARRY » 3 DOSUBN returns { [ 1 2 3 ] [ 4 5 6 ] }
Edited: 6 Oct 2012, 2:28 a.m.
Re: DOCOMB - Werner - 10-06-2012
Hello Gilles,
you are right that, to correspond to how DOSUBS works, the result should be wrapped up in a list.
The inputs to the object being evaluated however, should not, just like DOSUBS does.
So,
{ 11 22 33 44 }
3
\<< 3 \->LIST \>>
DOCOMB
should return
{ { 11 22 33 } { 11 22 44 } { 11 33 44 } { 22 33 44 } }
My other example remains the same, as it doesn't add a stack level.
BTW this version is not my first, and the fastest I've been able to come up with.
I too, tried to circumvent recursion (and failed) and the creation of the temporary environment
at each recursive call - that is possible, but turned out to be much slower.
My SysRPL is very rusty I'm afraid, that will take me a lot of time to get in to again.
There's some nice tricks to be played with recursion though.
So the RPL version of DOCOMB becomes:
265.5 bytes
\<<
ROT DUP SIZE 1 + 0
\-> ob L s DoC
\<<
DEPTH DEPTH ROLLD
{}
{ OVER 1 -
\-> t n
\<<
s 1 -
IF n
THEN FOR s n L s GET 1 \->LIST t + DoC EVAL NEXT
ELSE FOR s L s GET t LIST\-> DROP ob EVAL NEXT
END
\>>
} DUP 'DoC' STO EVAL
DEPTH DEPTH ROLL -
IF DUP THEN \->LIST ELSE DROP END
\>>
\>>
Cheers, Werner
|