1. Sequence Routines

Hi,
I'm not sure of the protocol here, but I recently sent a file to the RDS
contributions section. In case anyone is interested, it contains a set of
functions that perform some common sequence processing...

-- remove_right
--      (sequence pSource, integer pHowMany)
--      Removes a specified number of elements from the end of a sequence.
--      Returns the updated sequence

-- remove_left
--      (sequence pSource, integer pHowMany)
--      Removes a specified number of elements from the start of a sequence.
--      Returns the updated sequence

-- remove_mid
--      (sequence pSource, integer pHowMany, integer pFrom)
--      Removes a specified number of elements from a sequence starting at a
specified point.
--      Returns the updated sequence

-- insert
--      (sequence pTarget, integer pPosition, object pNewData)
--      Inserts some new elements into a sequence at a specified position.
--      Returns the updated sequence

-- last_element
--      (sequence pSource)
--      Returns the last element of a non-empty sequence, otherwise returns {}

-- to_head
--      (sequence pSource, integer pElement)
--      Moves the specified element to the start of a sequence.
--      Returns the updated sequence

-- to_tail
--      (sequence pSource, integer pElement)
--      Moves the specified element to the end of a sequence.
--      Returns the updated sequence

-- move_back
--      (sequence pSource, integer pElement, integer pIncrement)
--      Moves the specified element towards the end of a sequence, by a
specified increment.
--      Returns the updated sequence

-- move_forward
--      (sequence pSource, integer pElement, integer pIncrement)
--      Moves the specified element towards the start of a sequence, by a
specified increment.
--      Returns the updated sequence

-- find_from
--      (object pElement, sequence pSource, integer pFrom)
--      Locates the specified element in a sequence, starting from a specified
point.
--      Returns the position relative to the start of the sequence or zero if
not found.

-- find_all
--      (object pElement, sequence pSource)
--      Locates the all the occurances of the specified element in a sequence
--      Returns a sequence listing each occurance. If none found an empty
sequence is returned.

-- match_from
--      (object pElements, sequence pSource, integer pFrom)
--      Locates the specified element list in a sequence, starting from a
specified point.
--      Returns the position relative to the start of the sequence or zero if
not found.

-- match_all
--      (sequence pElements, sequence pSource)
--      Locates the all the occurances of the specified element list in a
sequence
--      Returns a sequence listing each occurance. If none found an empty
sequence is returned.

-- mid
--      (sequence pSource, integer pFrom, integer pHowMany)
--      Returns the specified number of elements of a sequence starting from a
specified position
--      Returns a sequence

-- left
--      (sequence pSource, integer pHowMany)
--      Returns the specified number of elements from the start of a sequence.
--      Returns a sequence

-- right
--      (sequence pSource, integer pHowMany)
--      Returns the specified number of elements from the end of a sequence.
--      Returns a sequence
  
-- 
cheers,
Derek

new topic     » topic index » view message » categorize

2. Re: Sequence Routines

On Thu, 18 Sep 2003 19:50:50 +1000, Derek Parnell
<ddparnell at bigpond.com> wrote:

>-- remove_right
>--      (sequence pSource, integer pHowMany)
etc.

Hi Derek,
I've had a look at those routines and would make one observation:
There's far too much bounds correcting going on. To my mind, if the
calling program asks to remove 87 items from a list of 3, it should
fail with an error there and then. At least during development, there
might be some argument for turning it back on for released code.

Your post triggered me to start writing a gp sequence manipulation
routine. It _will_ sacrifice performance for flexibility, so it may
not interest you. However, if you still have some test cases lying
around from that code, can you mail them to me, thanks.

Below is the first draft, which handles 12 of your routines (as I
said, probably far too slowly), not the find and match extensions.
It is also written with a bit of negative index handling.

Regards,
Pete

-- General purpose sequence manipulation routine
-- Author Pete Lomax, 19/9/2003
--
-- In the following, left column holds basic pattern of the result.
-- Slices are represented by pairs, items by a digit, and inserted=20
-- object by {}
-- The middle column holds the instances of column one which must=20
-- be updated by the position, subtract if index is negative.
-- The right hand column holds the instances of column one which must=20
-- be updated by the increment.
-- If anyone can think of a better, more readable, way to code=20
-- this table, I'm all ears.
--
constant s0_1=3D{0,-1}, s1_2=3D{1,-2}, s1_1=3D{1,-1}, s10=3D{1,0},=20
		 s11=3D{1,1}, s12=3D{1,2}, s21=3D{2,1}, s22=3D{2,2},=20
		 s3_1=3D{3,-1}, s31=3D{3,1}, s32=3D{3,2}, s41=3D{4,1},

baseset=3D{
{{s1_1}, 			{s11},					{}},			-- reml
{{s1_1}, 			{s1_2},					{}},			-- remr
{{s1_1,s0_1}, 		{s12,s21},				{s21}},			-- remm
{{s1_1,{},s0_1},	{s12,s31},				{}},			-- insert
{{-1},				{},						{}},			-- last
{{0,s1_1,s1_1},		{1,s22,s31},			{}},			-- tohead
{{s1_1,s1_1,0},		{s12,s21,3},			{}},			-- totail
{{s1_1,s10,0,s1_1},	{s12,s21,s22,3,s41},	{s22,s41}},		-- mvback
{{s1_1,0,s0_1,s1_1},{s12,2,s31,s32,s41},	{s1_2,s3_1}},	-- mvfwd
{{s0_1},			{s11,s12},				{s12}},			-- mid
{{s10},				{s12},					{}},			-- left
{{s0_1},			{s1_1},					{}} }			-- right

-- As an example, mvfwd pattern (column 1) is slice,item,slice,slice.
-- The position needs to be added to five places (column 2), and the
-- increment (column 3) subtracted from two places.
-- This corresponds to Derek's code:
--	return pSource[1..pElement-pIncrement-1] &=20
--		   pSource[pElement] &
--		   pSource[pElement-pIncrement..pElement-1] &
--		   pSource[pElement+1..length(pSource)]
-- notice that the initial pattern has the needed 1,0,or -1.
-- for the last slice -1 is used to represent length(pSource).


constant F_reml=3D1, F_remr=3D2, F_remm=3D3, F_ins=3D4,=20
		 F_last=3D5, F_tohead=3D6, F_totail=3D7, F_mvback=3D8,=20
		 F_mvfwd=3D9, F_mid=3D10, F_left=3D11, F_right=3D12

function check(integer i, integer l)
	if i<0 then i+=3Dl+1 end if
	if i>=3Dl then return l elsif i<1 then return 1 end if
	return i=09
end function

function sqx(integer op, object x, object ins, object posinc)
sequence pattern
object xitem
sequence result
integer ni
	pattern=3Dbaseset[op][1]
	for c=3D1 to length(posinc) do
		for i=3D1 to length(baseset[op][c+1]) do
			xitem=3Dbaseset[op][c+1][i]
			if atom(xitem) then
				if xitem<0 then
					pattern[-xitem]-=3Dposinc[c]
				else
					pattern[xitem] +=3Dposinc[c]
				end if
			else
				if xitem[2]<0 then
					pattern[xitem[1]][-xitem[2]]-=3Dposinc[c]
				else
					pattern[xitem[1]][xitem[2]] +=3Dposinc[c]
				end if
			end if
		end for
	end for

	result=3D{}
	for i=3D1 to length(pattern) do
		xitem=3Dpattern[i]
		if atom(xitem) then
			ni=3Dcheck(xitem,length(x))
			if ni then result&=3Dx[ni] end if
		elsif equal(xitem,{}) then
			result&=3Dins
		else

result&=3Dx[check(xitem[1],length(x))..check(xitem[2],length(x))]
		end if
	end for
	return result
end function

constant x=3D"12345"
	printf(1,"345=3D%s\n",{sqx(F_reml,x,0,{2})})
	printf(1,"123=3D%s\n",{sqx(F_remr,x,0,{2})})
	printf(1,"15=3D%s\n",{sqx(F_remm,x,0,{2,3})})
	printf(1,"12abc345=3D%s\n",{sqx(F_ins,x,"abc",{3})})
	printf(1,"5=3D%s\n",{sqx(F_last,x,0,{})})
	printf(1,"{}=3D%s\n",{sqx(F_last,{},0,{})})
	printf(1,"41235=3D%s\n",{sqx(F_tohead,x,0,{4})})=09
	printf(1,"12354=3D%s\n",{sqx(F_totail,x,0,{4})})
	printf(1,"13425=3D%s\n",{sqx(F_mvback,x,0,{2,2})})
	printf(1,"14235=3D%s\n",{sqx(F_mvfwd,x,0,{4,2})})
	printf(1,"234=3D%s\n",{sqx(F_mid,x,0,{2,3})})
	printf(1,"123=3D%s\n",{sqx(F_left,x,0,{3})})
	printf(1,"345=3D%s\n",{sqx(F_right,x,0,{3})})
if getc(0) then end if=09

new topic     » goto parent     » topic index » view message » categorize

3. Re: Sequence Routines

----- Original Message ----- 
From: "Pete Lomax" <petelomax at blueyonder.co.uk>
To: "EUforum" <EUforum at topica.com>
Subject: Re: Sequence Routines


> 
> 
> On Thu, 18 Sep 2003 19:50:50 +1000, Derek Parnell
> <ddparnell at bigpond.com> wrote:
> 
> >-- remove_right
> >--      (sequence pSource, integer pHowMany)
> etc.
> 
> Hi Derek,
> I've had a look at those routines and would make one observation:
> There's far too much bounds correcting going on. To my mind, if the
> calling program asks to remove 87 items from a list of 3, it should
> fail with an error there and then. At least during development, there
> might be some argument for turning it back on for released code.

At least with open source like this you can 'fix' it to your personal tastes.
 
> Your post triggered me to start writing a gp sequence manipulation
> routine. It _will_ sacrifice performance for flexibility, so it may
> not interest you. However, if you still have some test cases lying
> around from that code, can you mail them to me, thanks.

Sorry, I deleted the test code. There were almost two hundred different test
cases too!
 
> Below is the first draft, which handles 12 of your routines (as I
> said, probably far too slowly), not the find and match extensions.
> It is also written with a bit of negative index handling.

It may be a bit slow but the main issue I see is that its obsure. Hard to read.
But that's just me; no matter.

-- 
Derek

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu