Prev: Debug4x How to compress?
Next: Gaak.org, The Return
From: TW on 10 Jan 2010 16:49 I was fiddling with something today and found myself needing to remove an item from a list at a given index location and was surprised not to find a command that would do it. Am I missing one that is right in front of me? I was looking for something that would remove item N from a list, and preferably not modify the list if 0 < N or N >MAX_SIZE or something like that. It kind of surprised me I didn't see one. As a workaround I made a little routine that does a SUBCOMP on either side and puts them together, but that isn't very nice. . . TW
From: Jacob Wall on 10 Jan 2010 17:41 On Jan 10, 1:49 pm, TW <timwess...(a)gmail.com> wrote: > I was fiddling with something today and found myself needing to remove > an item from a list at a given index location and was surprised not to > find a command that would do it. Am I missing one that is right in > front of me? > > I was looking for something that would remove item N from a list, and > preferably not modify the list if 0 < N or N >MAX_SIZE or something > like that. It kind of surprised me I didn't see one. As a workaround I > made a little routine that does a SUBCOMP on either side and puts them > together, but that isn't very nice. . . > > TW Hello Tim, Hmm, how about, 2: { LIST } 1: BINT Index :: 1PUTLAM DUPLENCOMP 1GETLAM #< 1GETLAM #0= OR ?SEMI INNERCOMP reversym 1GETLAM #1+ ROLLDROP #1- reversym {}N ABND ; That is without checking for correct arguments... Jacob
From: Andreas Möller on 10 Jan 2010 19:26 Hello Tim, exploding and rebuilding the composite is the fastest way in SYS-RPL to remove an entry from the composite. Remember that ::N or {}N create a new object in tempob for the composite and embed the objects inside. > an item from a list at a given index location From which end of the composite are you counting ? Here are three possible solutions, the first based on Jacob´s example, the second counts from the beginning of the composite and the third one counts from the end. The timings were measured with debug4x. { BINT1 BINT2 BINT3 BINT4 BINT5 MINUSONE BINT7 BINT8 } ( Input Level2 ) BINT6 ( Input Level1 ) 1PUTLAM INNERCOMP reversym 1GETLAM #1+ ROLLDROP #1- reversym {}N ABND ( Elapsed: 3,47475ms ) ( based on Jacob´s code ) BINT6 ( counting from the start of the composite which means that MINUSONE will be removed ) ( Input Level2 ) ( Start of the composite End of the compsite ) ( Input Level1 ) { BINT1 BINT2 BINT3 BINT4 BINT5 MINUSONE BINT7 BINT8 } INNERCOMP DUP #2+ROLL OVER SWAP#- ( ML in the 49G ) #2+ROLL DROP #1- ( faster than DROP#1- ) TYPELIST_ COMPN_ ( faster than {}N - remember that a new tempob slot is created and the objects from the stack are embedded into the composite ) ( Elapsed: 2,663ms ) BINT3 ( counting from the end of the composite which means that MINUSONE will be removed ) ( Input Level2 ) ( Start of the composite End of the compsite ) ( Input Level1 ) { BINT1 BINT2 BINT3 BINT4 BINT5 MINUSONE BINT7 BINT8 } INNERCOMP #1- DUP#1+ #2+ROLL #1+ROLL DROP TYPELIST_ COMPN_ ( faster than {}N - remember that a new tempob slot is created and the objects from the stack are embedded into the composite ) ( Elapsed: 2,584ms ) However, if you know that your list contains only pointers (5 Nibbles for each pointer) you may want to do this in ML by copying everything 5 nibbles up from behind the object you want to delete and place a valid pointer at the end to fill up the gap, you can use the ROM address of NOP for this, as example. That way you now have two valid objects in the same tempob slot whereas the last one is unreferenced and will be deleted by the next GC. Example how your composite looks in memory where each pointer is 5 nibbles wide: DOLIST PTR01 PTR02 PTR03 PTR04 PTR05 PTR06 PTR07 SEMI Now you could, for example remove PTR03 by copying everything up and then your memory looks like this: DOLIST PTR01 PTR02 PTR04 PTR05 PTR06 PTR07 SEMI SEMI Then move to the end (of course through the saved address of it) and overwrite the ending SEMI with the 5 Nibbles address of NOP so that your memory looks like this: DOLIST PTR01 PTR02 PTR04 PTR05 PTR06 PTR07 SEMI NOP This is the fastest way you can do and you do not need any memory for it. HTH, Andreas
From: Virgil on 10 Jan 2010 19:56 In article <dbfcb94b-a6c0-4dbe-8780-d8cecaba22a4(a)j19g2000yqk.googlegroups.com>, TW <timwessman(a)gmail.com> wrote: > I was fiddling with something today and found myself needing to remove > an item from a list at a given index location and was surprised not to > find a command that would do it. Am I missing one that is right in > front of me? > > I was looking for something that would remove item N from a list, and > preferably not modify the list if 0 < N or N >MAX_SIZE or something > like that. It kind of surprised me I didn't see one. As a workaround I > made a little routine that does a SUBCOMP on either side and puts them > together, but that isn't very nice. . . > > TW Try this program with the list and the position, in that order, on the stack: \<< \-> n \<< 1 \<< n NSUB == {DROP} IFT \>> DOSUBS \>> \>> Note that the program will not do anything when the list position is below 1 or above the number of elements listed. Similarly, to eliminate all instances of a particular listed object from a list, with the list and the object, in that order, on the stack: \<< \-> a \<< 1 \<< DUP a == {DROP} IFT \>> DOLIST \>> \>> This program will do nothing if the object to be removed is not in the list.
From: TW on 10 Jan 2010 20:08
> exploding and rebuilding the composite is the fastest way in SYS-RPL > to remove an entry from the composite. Remember that ::N or {}N create > a new object in tempob for the composite and embed the objects inside. Well yes, but the thing that surprised me is that there isn't a command somewhere to do just this already. It seems common enough I am slightly surprised. Anyway, I was looking for a general routine that did built in error checking. I settled for this one below with none. SWAPINCOMP get1 OVERUNROT #- #2+ROLL DROP #1-{}N > From which end of the composite are you counting ? Front to back. > reversym That will be a speed hit right there. . . :-) > However, if you know that your list contains only pointers (5 Nibbles Yeah. Unfortunately it is for general usage. It is still kind of surprising there isn't any supported command that does it. . . TW |