Range modifications: Difference between revisions
Content added Content deleted
m (added whitespace.) |
(Added solution for Action!) |
||
Line 192: | Line 192: | ||
remove 7 => 1-5,10-25,27-30 |
remove 7 => 1-5,10-25,27-30 |
||
</pre> |
|||
=={{header|Action!}}== |
|||
<lang Action!>DEFINE PTR="CARD" |
|||
TYPE Range=[BYTE low,high] |
|||
TYPE Ranges=[ |
|||
PTR data |
|||
INT count] |
|||
PROC InitRanges(Ranges POINTER rs PTR d) |
|||
rs.data=d rs.count=0 |
|||
RETURN |
|||
PROC CheckIndex(Ranges POINTER rs INT index) |
|||
IF index<0 OR index>=rs.count THEN |
|||
Break() |
|||
FI |
|||
RETURN |
|||
PTR FUNC GetItemPtr(Ranges POINTER rs INT index) |
|||
CheckIndex(rs,index) |
|||
RETURN (rs.data+2*index) |
|||
PROC PrintRanges(Ranges POINTER rs) |
|||
Range POINTER r |
|||
INT i |
|||
IF rs.count=0 THEN |
|||
Print("empty") |
|||
ELSE |
|||
FOR i=0 TO rs.count-1 |
|||
DO |
|||
IF i>0 THEN Print(",") FI |
|||
r=GetItemPtr(rs,i) |
|||
PrintF("%B-%B",r.low,r.high) |
|||
OD |
|||
FI |
|||
RETURN |
|||
PROC AppendRange(Ranges POINTER rs BYTE l,h) |
|||
Range POINTER r |
|||
rs.count==+1 |
|||
r=GetItemPtr(rs,rs.count-1) |
|||
r.low=l r.high=h |
|||
RETURN |
|||
PROC InsertRange(Ranges POINTER rs INT index BYTE l,h) |
|||
Range POINTER r1,r2 |
|||
INT i |
|||
IF index=rs.count THEN |
|||
AppendRange(rs,l,h) |
|||
RETURN |
|||
FI |
|||
CheckIndex(rs,index) |
|||
rs.count==+1 |
|||
i=rs.count-1 |
|||
WHILE i>index |
|||
DO |
|||
r1=GetItemPtr(rs,i-1) |
|||
r2=GetItemPtr(rs,i) |
|||
r2.low=r1.low r2.high=r1.high |
|||
i==-1 |
|||
OD |
|||
r1=GetItemPtr(rs,index) |
|||
r1.low=l r1.high=h |
|||
RETURN |
|||
PROC DeleteRange(Ranges POINTER rs INT index) |
|||
Range POINTER r1,r2 |
|||
INT i |
|||
CheckIndex(rs,index) |
|||
FOR i=index TO rs.count-2 |
|||
DO |
|||
r1=GetItemPtr(rs,i+1) |
|||
r2=GetItemPtr(rs,i) |
|||
r2.low=r1.low r2.high=r1.high |
|||
OD |
|||
rs.count==-1 |
|||
RETURN |
|||
BYTE FUNC InRange(Range POINTER r BYTE n) |
|||
IF r.low<=n AND n<=r.high THEN |
|||
RETURN (1) |
|||
FI |
|||
RETURN (0) |
|||
INT FUNC FindRange(Ranges POINTER rs BYTE n) |
|||
Range POINTER r |
|||
INT i |
|||
FOR i=0 TO rs.count-1 |
|||
DO |
|||
r=GetItemPtr(rs,i) |
|||
IF n<=r.high THEN |
|||
RETURN (i) |
|||
FI |
|||
OD |
|||
RETURN (rs.count) |
|||
PROC Add(Ranges POINTER rs BYTE n) |
|||
Range POINTER r,r2 |
|||
INT i |
|||
IF rs.count=0 THEN |
|||
AppendRange(rs,n,n) RETURN |
|||
FI |
|||
FOR i=0 TO rs.count-1 |
|||
DO |
|||
r=GetItemPtr(rs,i) |
|||
IF n<r.low-1 THEN |
|||
InsertRange(rs,i,n,n) RETURN |
|||
ELSEIF n=r.low-1 THEN |
|||
r.low=n RETURN |
|||
ELSEIF n<=r.high THEN |
|||
RETURN |
|||
ELSEIF n=r.high+1 THEN |
|||
r.high=n |
|||
IF i<rs.count-1 THEN |
|||
r2=GetItemPtr(rs,i+1) |
|||
IF n=r2.low OR n+1=r2.low THEN |
|||
r.high=r2.high |
|||
DeleteRange(rs,i+1) |
|||
FI |
|||
FI |
|||
RETURN |
|||
ELSEIF i=rs.count-1 THEN |
|||
AppendRange(rs,n,n) |
|||
RETURN |
|||
FI |
|||
OD |
|||
RETURN |
|||
PROC Remove(Ranges POINTER rs BYTE n) |
|||
Range POINTER r |
|||
BYTE h |
|||
INT i |
|||
IF rs.count=0 THEN |
|||
RETURN |
|||
FI |
|||
FOR i=0 TO rs.count-1 |
|||
DO |
|||
r=GetItemPtr(rs,i) |
|||
IF n<=r.low-1 THEN |
|||
RETURN |
|||
ELSEIF n=r.low THEN |
|||
r.low=n+1 |
|||
IF r.low>r.high THEN |
|||
DeleteRange(rs,i) |
|||
FI |
|||
RETURN |
|||
ELSEIF n<r.high THEN |
|||
h=r.high |
|||
r.high=n-1 |
|||
InsertRange(rs,i+1,n+1,h) |
|||
RETURN |
|||
ELSEIF n=r.high THEN |
|||
r.high=n-1 |
|||
RETURN |
|||
FI |
|||
OD |
|||
RETURN |
|||
PROC TestAdd(Ranges POINTER rs BYTE n) |
|||
PrintF("%E Add %B -> ",n) |
|||
Add(rs,n) |
|||
PrintRanges(rs) |
|||
RETURN |
|||
PROC TestRemove(Ranges POINTER rs BYTE n) |
|||
PrintF("%E Remove %B -> ",n) |
|||
Remove(rs,n) |
|||
PrintRanges(rs) |
|||
RETURN |
|||
PROC Main() |
|||
CARD ARRAY d(20) |
|||
Ranges rs |
|||
InitRanges(rs,d) |
|||
PrintRanges(rs) |
|||
TestAdd(rs,77) |
|||
TestAdd(rs,79) |
|||
TestAdd(rs,78) |
|||
TestRemove(rs,77) |
|||
TestRemove(rs,78) |
|||
TestRemove(rs,79) |
|||
PutE() PutE() |
|||
InitRanges(rs,d) |
|||
AppendRange(rs,1,3) |
|||
AppendRange(rs,5,5) |
|||
PrintRanges(rs) |
|||
TestAdd(rs,1) |
|||
TestRemove(rs,4) |
|||
TestAdd(rs,7) |
|||
TestAdd(rs,8) |
|||
TestAdd(rs,6) |
|||
TestRemove(rs,7) |
|||
PutE() PutE() |
|||
InitRanges(rs,d) |
|||
AppendRange(rs,1,5) |
|||
AppendRange(rs,10,25) |
|||
AppendRange(rs,27,30) |
|||
PrintRanges(rs) |
|||
TestAdd(rs,26) |
|||
TestAdd(rs,9) |
|||
TestAdd(rs,7) |
|||
TestRemove(rs,26) |
|||
TestRemove(rs,9) |
|||
TestRemove(rs,7) |
|||
RETURN</lang> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Range_modifications.png Screenshot from Atari 8-bit computer] |
|||
<pre> |
|||
empty |
|||
Add 77 -> 77-77 |
|||
Add 79 -> 77-77,79-79 |
|||
Add 78 -> 77-79 |
|||
Remove 77 -> 78-79 |
|||
Remove 78 -> 79-79 |
|||
Remove 79 -> empty |
|||
1-3,5-5 |
|||
Add 1 -> 1-3,5-5 |
|||
Remove 4 -> 1-3,5-5 |
|||
Add 7 -> 1-3,5-5,7-7 |
|||
Add 8 -> 1-3,5-5,7-8 |
|||
Add 6 -> 1-3,5-8 |
|||
Remove 7 -> 1-3,5-6,8-8 |
|||
1-5,10-25,27-30 |
|||
Add 26 -> 1-5,10-30 |
|||
Add 9 -> 1-5,9-30 |
|||
Add 7 -> 1-5,7-7,9-30 |
|||
Remove 26 -> 1-5,7-7,9-25,27-30 |
|||
Remove 9 -> 1-5,7-7,10-25,27-30 |
|||
Remove 7 -> 1-5,10-25,27-30 |
|||
</pre> |
</pre> |
||