The Museum of HP Calculators

HP Forum Archive 21

[ Return to Index | Top of Index ]

48G: A little list-processing help?
Message #1 Posted by Peter Murphy (Livermore) on 26 June 2012, 2:39 p.m.

On level 2 I have a list, say {2 3 5 7 11 13 17}.

On level 1 I have a list of index numbers, {1 3 5 6}.

As output I'd like a list of the first, third, fifth and sixth elements in the level-2 list, namely {2 5 11 13}.

How do I do that, in general?

Thanks for a lesson.

      
Re: 48G: A little list-processing help?
Message #2 Posted by Luiz C. Vieira (Brazil) on 26 June 2012, 3:40 p.m.,
in response to message #1 by Peter Murphy (Livermore)

Hi.

I cannot figure a solution for now, but I'd suggest reading about DOLIST and DOSUBS.

Sorry not helping some more.

Cheers.

Luiz (Brazil)

      
Re: 48G: A little list-processing help?
Message #3 Posted by Raymond Del Tondo on 26 June 2012, 4:47 p.m.,
in response to message #1 by Peter Murphy (Livermore)

I never needed the list processing functions,
so in plain UserRPL I'd do it like this:

«  -> a b
  « { } 1 b SIZE
    FOR i
      a b i GET GET +
    NEXT
  »
»

Not very elegant, but straightforward;-)

            
Re: 48G: A little list-processing help?
Message #4 Posted by Raymond Del Tondo on 27 June 2012, 5:02 a.m.,
in response to message #3 by Raymond Del Tondo

As written in my earlier post, the obvious loop version doesn't look as elegant as the DOSUBS/DOLIST versions. However, internally those are loops, too.

Slightly OT, but just for the fun, here's a much faster SysRPL version.

::  CK2
    DUP1LAMBIND
    LENCOMP
    #1+_ONE_DO	(DO)
	DUP			( *L2 L2* )
	1GETLAM			( *L2 L2 L1* )
	INDEX@ NTHCOMPDROP	( *L2 L2 i* )
	%ABSCOERCE
	NTHCOMPDROP		( *L2 i'* )
	SWAP			( *i' L2* )
    LOOP

DROP 1GETABND LENCOMP {}N ;

This could be made even faster using meta objects, but the necessary offset calculations would also make the code somewhat more complicated, at least for this example;-)

                  
Re: 48G: A little list-processing help?
Message #5 Posted by Raymond Del Tondo on 27 June 2012, 12:46 p.m.,
in response to message #4 by Raymond Del Tondo

For those still interested, I made some timing measurements.

Timings are as follows:
UserRPL Loop: 161ms
DOLIST version: 159.28ms
DOSUBS1: 173.693ms
DOSUBS2: 139.635ms
SysRPL Loop: 22.2ms

DOSUBS1 is the slowest version, which also leaves the input list in level 2, and thus is different to all other solutions.

DOSUBS2 is faster than the other UserRPL solutions since it only uses one implicit LAM binding.

The DOLIST version and the DOSUBS2 version are essentially the same,
except that the DOLIST inner workings are slower than those of DOSUBS in this case.

The SysRPL version is much faster because much of the UserRPL overhead is not there.

                        
Re: 48G: A little list-processing help?
Message #6 Posted by Gilles Carpentier on 27 June 2012, 1:23 p.m.,
in response to message #5 by Raymond Del Tondo

Thank's for the benchmark !

I think that with a more complex example, the difference between "FOR" and "DOSUBS" or "DOLIST" will be greater.

In general I noticed that the use of {} followed by numerous + is very slow. Best way is to use the stack and a ->LIST command at the end to collect all the datas.

In my opinion, the 'ideal' implementation would be simply :

{2 3 5 7 11 13 17} {1 3 5 6} GET

-> { 2 5 11 13 }

But GET don't work that way, on the contrary of other commands. (probably becaus GET already accept a {} structure for the POS argument in some situations)

But in general, it works, and without DOSUBS or DOLIST... For exemple, try :

{ 0 10  20 30 40 } SIN
(0,0) {(1,1) (3,2) (5,5)} LINE
5 { 1 2 3 4 } /
{ 1 2 3 } { 4 5 6 } /
{ 0 1 1 0 1 } { 1 2 3 4 5 } IFT
123 { 'a' 'b' 'c' 'd' 'e' 'f'} STO
{ 1 2 3 } {'a' 'b' 'c'} STO
etc.

In some case, this is very powerfull

See AUR pages F-1

Edited: 27 June 2012, 1:38 p.m.

                        
Re: 48G: A little list-processing help?
Message #7 Posted by Kiyoshi Akima on 27 June 2012, 1:27 p.m.,
in response to message #5 by Raymond Del Tondo

You could probably speed up the SysRPL a bit more by replacing the SWAP and LOOP with a SWAPLOOP. If nothing else, it'll trim 2.5 bytes off the program size.

      
Re: 48G: A little list-processing help?
Message #8 Posted by Gilles Carpentier on 26 June 2012, 4:55 p.m.,
in response to message #1 by Peter Murphy (Livermore)

Hi, there is a lot of way to do this. For example :

1 « NSUB 1 + PICK SWAP GET » DOSUBS

or

SWAP -> List « 1 « List SWAP GET » DOSUBS »

      
Re: 48G: A little list-processing help?
Message #9 Posted by Peter Murphy (Livermore) on 26 June 2012, 5:48 p.m.,
in response to message #1 by Peter Murphy (Livermore)

Thanks to Luiz for encouragement, to Raymond for one lesson and to Gilles for two.

All three solutions work as claimed, and all three will teach me something. Maybe even a lot.

What a wonderful resource this forum is!

      
Re: 48G: A little list-processing help?
Message #10 Posted by Pascal Zeihen on 27 June 2012, 2:48 a.m.,
in response to message #1 by Peter Murphy (Livermore)

Hi,

Here is another solution, using DOLIST. Just put your lists in stack levels 2 and 1, as described, and execute this program:

<< SWAP -> L << 1 << L SWAP GET >> DOLIST >> >>

Best regards.

            
Re: 48G: A little list-processing help?
Message #11 Posted by Peter Murphy (Livermore) on 27 June 2012, 10:20 a.m.,
in response to message #10 by Pascal Zeihen

Thank you, Pascal. Ma coupe déborde.

All the best,


[ Return to Index | Top of Index ]

Go back to the main exhibit hall