Re: Sequence Routines
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Sep 19, 2003
- 395 views
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