tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
12
Task/Range-extraction/0DESCRIPTION
Normal file
12
Task/Range-extraction/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{{:Range extraction/Format}}
|
||||
|
||||
'''The task'''
|
||||
* Create a function that takes a list of integers in increasing order and returns a correctly formatted string in the range format.
|
||||
* Use the function to compute and print the range formatted version of the following ordered list of integers:
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39
|
||||
* Show the output of your program.
|
||||
|
||||
C.f. [[Range expansion]]
|
||||
54
Task/Range-extraction/ALGOL-68/range-extraction-1.alg
Normal file
54
Task/Range-extraction/ALGOL-68/range-extraction-1.alg
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
###
|
||||
REQUIRES(MODE SCALAR, OP(SCALAR,SCALAR)BOOL =, OP(SCALAR,SCALAR)SCALAR +);
|
||||
###
|
||||
MODE SCALARLIST = FLEX[0]SCALAR;
|
||||
MODE YIELDINT = PROC(SCALAR)VOID;
|
||||
|
||||
################################################################
|
||||
# Declarations for manipulating lists of range pairs [lwb:upb] #
|
||||
################################################################
|
||||
MODE RANGE = STRUCT(SCALAR lwb, upb);
|
||||
MODE RANGELIST = FLEX[0]RANGE;
|
||||
MODE YIELDRANGE = PROC(RANGE)VOID;
|
||||
|
||||
PROC range repr = (RANGE range)STRING: (
|
||||
STRING lwb := whole(lwb OF range,0);
|
||||
IF lwb OF range = upb OF range THEN
|
||||
lwb
|
||||
ELSE
|
||||
# "["+lwb+":"+whole(upb OF range,0)+"]" #
|
||||
lwb+"-"+whole(upb OF range,0)
|
||||
FI
|
||||
);
|
||||
|
||||
# OP REPR = (RANGE range)STRING: range repr(range); # # firmly related to UNIRANGE #
|
||||
|
||||
######################################################################
|
||||
# Declarations for manipulating lists containing pairs AND lone INTs #
|
||||
######################################################################
|
||||
MODE UNIRANGE = UNION(SCALAR, RANGE);
|
||||
MODE UNIRANGELIST = FLEX[0]UNIRANGE;
|
||||
MODE YIELDUNIRANGE = PROC(UNIRANGE)VOID;
|
||||
|
||||
PROC unirange repr = (UNIRANGE unirange)STRING:
|
||||
CASE unirange IN
|
||||
(RANGE range): range repr(range),
|
||||
(SCALAR scalar): whole(scalar,0)
|
||||
ESAC;
|
||||
|
||||
OP (UNIRANGE)STRING REPR = unirange repr; # alias #
|
||||
|
||||
# The closest thing Algol68 has to inheritance is the UNION #
|
||||
MODE UNIRANGELISTS = UNION(UNIRANGELIST, RANGELIST, SCALARLIST);
|
||||
|
||||
PROC unirange list repr = (UNIRANGELIST unirange list)STRING: (
|
||||
### Produce a STRING representation of a UNIRANGELIST ###
|
||||
STRING out # := "("#, sep := "";
|
||||
FOR key FROM LWB unirange list TO UPB unirange list DO
|
||||
out +:= sep + REPR unirange list[key];
|
||||
sep := "," # +" " #
|
||||
OD;
|
||||
out # +")" #
|
||||
);
|
||||
|
||||
OP (UNIRANGELIST)STRING REPR = unirange list repr; # alias #
|
||||
60
Task/Range-extraction/ALGOL-68/range-extraction-2.alg
Normal file
60
Task/Range-extraction/ALGOL-68/range-extraction-2.alg
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
###
|
||||
REQUIRES(MODE SCALAR, OP(SCALAR,SCALAR)BOOL =, OP(SCALAR,SCALAR)SCALAR +);
|
||||
###
|
||||
PR READ "Template_Range_extraction_Base.a68" PR
|
||||
|
||||
OP (UNIRANGELISTS)UNIRANGELIST INITUNIRANGE = init unirange list; # alias #
|
||||
|
||||
PROC init unirange list = (UNIRANGELISTS unirange list)UNIRANGELIST: (
|
||||
### Take a []SCALAR, []RANGE or []UNIRANGE, and return a normalised []UNIRANGE ###
|
||||
|
||||
INT len = UPB unirange list-LWB unirange list+1;
|
||||
[LWB unirange list: LWB unirange list+len*2]UNIRANGE out unirange list;
|
||||
SCALAR upb out unirange list := LWB out unirange list - 1;
|
||||
UNION(VOID, RANGE) prev range := EMPTY;
|
||||
|
||||
PROC out unirange list append = (RANGE value)VOID:(
|
||||
|
||||
IF lwb OF value = upb OF value THEN
|
||||
out unirange list[upb out unirange list+:=1] := lwb OF value
|
||||
ELIF lwb OF value + 1 = upb OF value THEN
|
||||
out unirange list[upb out unirange list+:=1] := lwb OF value;
|
||||
out unirange list[upb out unirange list+:=1] := upb OF value
|
||||
ELSE
|
||||
out unirange list[upb out unirange list+:=1] := value
|
||||
FI
|
||||
);
|
||||
|
||||
FOR key FROM LWB unirange list TO UPB unirange list DO
|
||||
UNIRANGE value = CASE unirange list IN
|
||||
(SCALARLIST list):list[key],
|
||||
(RANGELIST list):list[key],
|
||||
(UNIRANGELIST list):list[key]
|
||||
ESAC;
|
||||
|
||||
RANGE next range := CASE value IN
|
||||
(RANGE range): range,
|
||||
(SCALAR value): RANGE(value, value)
|
||||
ESAC;
|
||||
|
||||
prev range :=
|
||||
CASE prev range IN
|
||||
(VOID): next range,
|
||||
(RANGE prev range):
|
||||
IF upb OF prev range + 1 = lwb OF next range THEN
|
||||
RANGE(lwb OF prev range, upb OF next range) # merge the range #
|
||||
ELSE
|
||||
out unirange list append(prev range);
|
||||
next range
|
||||
FI
|
||||
OUT SKIP
|
||||
ESAC
|
||||
|
||||
OD;
|
||||
|
||||
CASE prev range IN
|
||||
(RANGE last range): out unirange list append(last range)
|
||||
ESAC;
|
||||
|
||||
out unirange list[:upb out unirange list]
|
||||
);
|
||||
44
Task/Range-extraction/ALGOL-68/range-extraction-3.alg
Normal file
44
Task/Range-extraction/ALGOL-68/range-extraction-3.alg
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/local/bin/a68g --script #
|
||||
############################
|
||||
# some simple test cases: #
|
||||
############################
|
||||
|
||||
MODE SCALAR = INT;
|
||||
PR READ "Template_Range_extraction_Iterative.a68" PR
|
||||
#PR READ "Template_Range_extraction_Generative.a68" PR#
|
||||
MODE RANGEINT = UNIRANGE;
|
||||
|
||||
test: BEGIN
|
||||
[]INT int list = ( # unnormalised #
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39);
|
||||
|
||||
[]RANGE range list = ( # unnormalised #
|
||||
(0,0), (1,1), (2,2), (4,4), (6,6), (7,7), (8,8), (11,11), (12,12), (14,14),
|
||||
(15,15), (16,16), (17,17), (18,18), (19,19), (20,20), (21,21), (22,22), (23,23), (24,24),
|
||||
(25,25), (27,27), (28,28), (29,29), (30,30), (31,31), (32,32), (33,33), (35,35), (36,36),
|
||||
(37,37), (38,38), (39,39));
|
||||
|
||||
[]RANGEINT list a = ( # unnormalised #
|
||||
RANGE(0,2), 4, RANGE(6,8), RANGE(11,12),
|
||||
RANGE(14,25), RANGE(27,33), RANGE(35,39));
|
||||
|
||||
[]RANGEINT list b = ( # unnormalised #
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39);
|
||||
|
||||
[]RANGEINT list c = INITUNIRANGE(list b); # normalised #
|
||||
|
||||
# compare manipulation of various types of argument lists #
|
||||
printf(($gl$,
|
||||
REPR INITUNIRANGE int list,
|
||||
REPR INITUNIRANGE range list,
|
||||
REPR INITUNIRANGE list a,
|
||||
REPR INITUNIRANGE list b,
|
||||
REPR list c
|
||||
))
|
||||
END
|
||||
83
Task/Range-extraction/ALGOL-68/range-extraction-4.alg
Normal file
83
Task/Range-extraction/ALGOL-68/range-extraction-4.alg
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
###
|
||||
REQUIRES(MODE SCALAR, OP(SCALAR,SCALAR)BOOL =, OP(SCALAR,SCALAR)SCALAR +);
|
||||
###
|
||||
PR READ "Template_Range_extraction_Base.a68" PR
|
||||
|
||||
PROC gen range = (UNIRANGELISTS unirange list, YIELDRANGE yield range)VOID:
|
||||
### Take a []SCALAR, []RANGE or []URANGE, and generatively yield an unnormalised RANGE ###
|
||||
|
||||
FOR key FROM LWB unirange list TO UPB unirange list DO
|
||||
# Note: Algol 68RS cannot handle LWB and UPB of a UNION in the following: #
|
||||
UNIRANGE value = CASE unirange list IN
|
||||
(SCALARLIST list):list[key],
|
||||
(RANGELIST list):list[key],
|
||||
(UNIRANGELIST list):list[key]
|
||||
ESAC;
|
||||
yield range(
|
||||
CASE value IN
|
||||
(RANGE range): range,
|
||||
(SCALAR value): (value, value)
|
||||
ESAC
|
||||
)
|
||||
OD;
|
||||
|
||||
PROC gen range merge = (UNIRANGELISTS unirange list, YIELDRANGE yield)VOID: (
|
||||
### Take a []SCALAR, []RANGE or []URANGE , and generatively yield a normalised RANGE ###
|
||||
|
||||
UNION(VOID, RANGE) prev range := EMPTY;
|
||||
|
||||
# FOR RANGE next range IN # gen range(unirange list, # ) DO #
|
||||
## (RANGE next range)VOID:
|
||||
# if the ranges cannot be merge, then yield 1st, and return 2nd #
|
||||
prev range :=
|
||||
CASE prev range IN
|
||||
(VOID): next range,
|
||||
(RANGE prev range):
|
||||
IF upb OF prev range + 1 = lwb OF next range THEN
|
||||
RANGE(lwb OF prev range, upb OF next range) # merge the range #
|
||||
ELSE
|
||||
#IF lwb OF prev range <= upb OF prev range THEN#
|
||||
yield(prev range);
|
||||
#FI;#
|
||||
next range
|
||||
FI
|
||||
OUT SKIP
|
||||
ESAC
|
||||
# OD # );
|
||||
|
||||
CASE prev range IN (RANGE last range): yield(last range) ESAC
|
||||
);
|
||||
|
||||
PROC gen unirange merge = (UNIRANGELISTS unirange list, YIELDUNIRANGE yield)VOID: (
|
||||
### Take a []SCALAR, []RANGE or []UNIRANGE and generatively yield a normalised UNIRANGE ###
|
||||
|
||||
PROC unpack = (RANGE value)VOID:(
|
||||
IF lwb OF value = upb OF value THEN
|
||||
yield(lwb OF value)
|
||||
ELIF lwb OF value + 1 = upb OF value THEN
|
||||
yield(lwb OF value);
|
||||
yield(upb OF value)
|
||||
ELSE
|
||||
yield(value)
|
||||
FI
|
||||
);
|
||||
|
||||
gen range merge(unirange list, unpack)
|
||||
);
|
||||
|
||||
PROC unirange list init = (UNIRANGELISTS unirange list)UNIRANGELIST: (
|
||||
### Take a []SCALAR, []RANGE or []UNIRANGE and return a static []UNIRANGE ###
|
||||
|
||||
INT len = UPB unirange list - LWB unirange list + 1;
|
||||
[LWB unirange list: LWB unirange list + len * 2]UNIRANGE out unirange list; # estimate #
|
||||
SCALAR upb out unirange list := LWB out unirange list - 1;
|
||||
|
||||
# FOR UNIRANGE unirange IN # gen unirange merge(unirange list, # ) DO #
|
||||
## (UNIRANGE unirange)VOID:
|
||||
out unirange list[upb out unirange list+:=1] := unirange
|
||||
# OD # );
|
||||
|
||||
out unirange list[:upb out unirange list]
|
||||
);
|
||||
|
||||
OP (UNIRANGELISTS)UNIRANGELIST INITUNIRANGE = unirange list init; # alias #
|
||||
54
Task/Range-extraction/AWK/range-extraction.awk
Normal file
54
Task/Range-extraction/AWK/range-extraction.awk
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/awk -f
|
||||
|
||||
BEGIN {
|
||||
delete sequence
|
||||
delete range
|
||||
|
||||
seqStr = "0,1,2,4,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,"
|
||||
seqStr = seqStr "25,27,28,29,30,31,32,33,35,36,37,38,39"
|
||||
print "Sequence: " seqStr
|
||||
fillSequence(seqStr)
|
||||
rangeExtract()
|
||||
showRange()
|
||||
exit
|
||||
}
|
||||
|
||||
function rangeExtract( runStart, runLen) {
|
||||
delete range
|
||||
runStart = 1
|
||||
while(runStart <= length(sequence)) {
|
||||
runLen = getSeqRunLen(runStart)
|
||||
addRange(runStart, runLen)
|
||||
runStart += runLen
|
||||
}
|
||||
}
|
||||
|
||||
function getSeqRunLen(startPos, pos) {
|
||||
for (pos = startPos; pos < length(sequence); pos++) {
|
||||
if (sequence[pos] + 1 != sequence[pos + 1]) break;
|
||||
}
|
||||
return pos - startPos + 1;
|
||||
}
|
||||
|
||||
function addRange(startPos, len, str) {
|
||||
if (len == 1) str = sequence[startPos]
|
||||
else if (len == 2) str = sequence[startPos] "," sequence[startPos + 1]
|
||||
else str = sequence[startPos] "-" sequence[startPos + len - 1]
|
||||
range[length(range) + 1] = str
|
||||
}
|
||||
|
||||
function showRange( r) {
|
||||
printf " Ranges: "
|
||||
for (r = 1; r <= length(range); r++) {
|
||||
if (r > 1) printf ","
|
||||
printf range[r]
|
||||
}
|
||||
printf "\n"
|
||||
}
|
||||
|
||||
function fillSequence(seqStr, n, s) {
|
||||
n = split(seqStr,a,/[,]+/)
|
||||
for (s = 1; s <= n; s++) {
|
||||
sequence[s] = a[s]
|
||||
}
|
||||
}
|
||||
46
Task/Range-extraction/Ada/range-extraction-1.ada
Normal file
46
Task/Range-extraction/Ada/range-extraction-1.ada
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
|
||||
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
|
||||
|
||||
procedure Range_Extraction is
|
||||
type Sequence is array (Positive range <>) of Integer;
|
||||
function Image (S : Sequence) return String is
|
||||
Result : Unbounded_String;
|
||||
From : Integer;
|
||||
procedure Flush (To : Integer) is
|
||||
begin
|
||||
if Length (Result) > 0 then
|
||||
Append (Result, ',');
|
||||
end if;
|
||||
Append (Result, Trim (Integer'Image (From), Ada.Strings.Left));
|
||||
if From < To then
|
||||
if From+1 = To then
|
||||
Append (Result, ',');
|
||||
else
|
||||
Append (Result, '-');
|
||||
end if;
|
||||
Append (Result, Trim (Integer'Image (To), Ada.Strings.Left));
|
||||
end if;
|
||||
end Flush;
|
||||
begin
|
||||
if S'Length > 0 then
|
||||
From := S (S'First);
|
||||
for I in S'First + 1..S'Last loop
|
||||
if S (I - 1) + 1 /= S (I) then
|
||||
Flush (S (I - 1));
|
||||
From := S (I);
|
||||
end if;
|
||||
end loop;
|
||||
Flush (S (S'Last));
|
||||
end if;
|
||||
return To_String (Result);
|
||||
end Image;
|
||||
begin
|
||||
Put_Line
|
||||
( Image
|
||||
( ( 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39
|
||||
) ) );
|
||||
end Range_Extraction;
|
||||
45
Task/Range-extraction/Ada/range-extraction-2.ada
Normal file
45
Task/Range-extraction/Ada/range-extraction-2.ada
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
with Ada.Text_IO, Ada.Strings.Fixed;
|
||||
|
||||
procedure Range_Extract is
|
||||
type Sequence is array (Positive range <>) of Integer;
|
||||
|
||||
function Img(I: Integer) return String is -- the image of an Integer
|
||||
begin
|
||||
return
|
||||
Ada.Strings.Fixed.Trim(Integer'Image(I), Ada.Strings.Left);
|
||||
end Img;
|
||||
|
||||
function Img(S: Sequence) return String is -- the image of a Sequence
|
||||
|
||||
function X(S : Sequence) return String is -- recursive eXtract
|
||||
Idx: Positive := S'First;
|
||||
begin
|
||||
if S'Length = 0 then return
|
||||
""; -- return nothing if Sequence is empty
|
||||
else
|
||||
while Idx < S'Last and then S(Idx+1) = S(Idx) + 1 loop
|
||||
Idx := Idx + 1;
|
||||
end loop;
|
||||
if Idx = S'First then return
|
||||
"," & Img(S(Idx)) & X(S(Idx+1 .. S'Last));
|
||||
elsif Idx = S'First+1 then return
|
||||
"," & Img(S(S'First)) & ',' & Img(S(Idx)) & X(S(Idx+1 .. S'Last));
|
||||
else return
|
||||
"," & Img(S(S'First)) & '-' & Img(S(Idx)) & X(S(Idx+1 .. S'Last));
|
||||
end if;
|
||||
end if;
|
||||
end X;
|
||||
|
||||
begin -- function Img(S: Sequence) return String
|
||||
if S'Length = 0 then return
|
||||
"";
|
||||
else return
|
||||
Img(S(S'First)) & X(S(S'First+1 .. S'Last));
|
||||
end if;
|
||||
end Img;
|
||||
|
||||
begin -- main
|
||||
Ada.Text_IO.Put_Line(Img( ( 0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29,
|
||||
30, 31, 32, 33, 35, 36, 37, 38, 39) ));
|
||||
end Range_Extract;
|
||||
54
Task/Range-extraction/Aime/range-extraction.aime
Normal file
54
Task/Range-extraction/Aime/range-extraction.aime
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
void
|
||||
fs(integer &s, data b)
|
||||
{
|
||||
if (s) {
|
||||
b_append(b, ',');
|
||||
}
|
||||
s = 1;
|
||||
}
|
||||
|
||||
text
|
||||
rp(...)
|
||||
{
|
||||
integer f, i, j;
|
||||
data b;
|
||||
|
||||
f = 0;
|
||||
i = 0;
|
||||
j = 0;
|
||||
while (i < count()) {
|
||||
while (j < count() - 1) {
|
||||
if (__integer(lead(j + 1)) == __integer(lead(j)) + 1) {
|
||||
j += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i + 1 < j) {
|
||||
fs(f, b);
|
||||
b_suffix(b, itoa(lead(i)));
|
||||
b_append(b, '-');
|
||||
b_suffix(b, itoa(lead(j)));
|
||||
} else {
|
||||
while (i < j + 1) {
|
||||
fs(f, b);
|
||||
b_suffix(b, itoa(lead(i)));
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
j += 1;
|
||||
i = j;
|
||||
}
|
||||
|
||||
return b_string(b);
|
||||
}
|
||||
|
||||
integer
|
||||
main(void)
|
||||
{
|
||||
o_text(rp(0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39));
|
||||
o_byte('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
11
Task/Range-extraction/AutoHotkey/range-extraction.ahk
Normal file
11
Task/Range-extraction/AutoHotkey/range-extraction.ahk
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
msgbox % extract("0,1,2,4,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39")
|
||||
|
||||
extract( list ) {
|
||||
loop, parse, list, `,, %A_Tab%%A_Space%`r`n
|
||||
{
|
||||
if (A_LoopField+0 != p+1)
|
||||
ret .= (f!=p ? (p>f+1 ? "-" : ",") p : "") "," f := A_LoopField
|
||||
p := A_LoopField
|
||||
}
|
||||
return SubStr(ret (f!=p ? (p>f+1 ? "-" : ",") p : ""), 2)
|
||||
}
|
||||
26
Task/Range-extraction/BBC-BASIC/range-extraction.bbc
Normal file
26
Task/Range-extraction/BBC-BASIC/range-extraction.bbc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
range$ = " 0, 1, 2, 4, 6, 7, 8, 11, 12, 14, " + \
|
||||
\ "15, 16, 17, 18, 19, 20, 21, 22, 23, 24, " + \
|
||||
\ "25, 27, 28, 29, 30, 31, 32, 33, 35, 36, " + \
|
||||
\ "37, 38, 39"
|
||||
PRINT FNrangeextract(range$)
|
||||
END
|
||||
|
||||
DEF FNrangeextract(r$)
|
||||
LOCAL f%, i%, r%, t%, t$
|
||||
f% = VAL(r$)
|
||||
REPEAT
|
||||
i% = INSTR(r$, ",", i%+1)
|
||||
t% = VALMID$(r$, i%+1)
|
||||
IF t% = f% + r% + 1 THEN
|
||||
r% += 1
|
||||
ELSE
|
||||
CASE r% OF
|
||||
WHEN 0: t$ += STR$(f%) + ","
|
||||
WHEN 1: t$ += STR$(f%) + "," + STR$(f% + r%) + ","
|
||||
OTHERWISE: t$ += STR$(f%) + "-" + STR$(f% + r%) + ","
|
||||
ENDCASE
|
||||
r% = 0
|
||||
f% = t%
|
||||
ENDIF
|
||||
UNTIL i% = 0
|
||||
= LEFT$(t$)
|
||||
51
Task/Range-extraction/Bracmat/range-extraction.bracmat
Normal file
51
Task/Range-extraction/Bracmat/range-extraction.bracmat
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
( rangeExtract
|
||||
= accumulator firstInRange nextInRange
|
||||
, accumulate fasten rangePattern
|
||||
. ( accumulate
|
||||
= !accumulator
|
||||
(!accumulator:|?&",")
|
||||
!firstInRange
|
||||
( !firstInRange+1:<>!nextInRange
|
||||
& ( !firstInRange+2:!nextInRange&","
|
||||
| "-"
|
||||
)
|
||||
-1+!nextInRange
|
||||
|
|
||||
)
|
||||
: ?accumulator
|
||||
)
|
||||
& ( fasten
|
||||
= [%( !accumulate
|
||||
& (!sjt:?firstInRange)+1:?nextInRange
|
||||
)
|
||||
)
|
||||
& ( rangePattern
|
||||
= (
|
||||
| ?
|
||||
( !nextInRange
|
||||
& 1+!nextInRange:?nextInRange
|
||||
)
|
||||
)
|
||||
( &!accumulate
|
||||
| (#<>!nextInRange:!fasten) !rangePattern
|
||||
)
|
||||
)
|
||||
& :?accumulator:?firstInRange
|
||||
& !arg:(|#!fasten !rangePattern)
|
||||
& str$!accumulator
|
||||
)
|
||||
& ( test
|
||||
= L A
|
||||
. put$(!arg " ==>\n",LIN)
|
||||
& ( !arg:(?,?)
|
||||
& whl'(!arg:(?A,?arg)&(!A,!L):?L)
|
||||
& whl'(!L:(?A,?L)&!A !arg:?arg)
|
||||
|
|
||||
)
|
||||
& out$(rangeExtract$!arg)
|
||||
)
|
||||
& test
|
||||
$ (0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39)
|
||||
53
Task/Range-extraction/C++/range-extraction.cpp
Normal file
53
Task/Range-extraction/C++/range-extraction.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <cstddef>
|
||||
|
||||
template<typename InIter>
|
||||
void extract_ranges(InIter begin, InIter end, std::ostream& os)
|
||||
{
|
||||
if (begin == end)
|
||||
return;
|
||||
|
||||
int current = *begin++;
|
||||
os << current;
|
||||
int count = 1;
|
||||
|
||||
while (begin != end)
|
||||
{
|
||||
int next = *begin++;
|
||||
if (next == current+1)
|
||||
++count;
|
||||
else
|
||||
{
|
||||
if (count > 2)
|
||||
os << '-';
|
||||
else
|
||||
os << ',';
|
||||
if (count > 1)
|
||||
os << current << ',';
|
||||
os << next;
|
||||
count = 1;
|
||||
}
|
||||
current = next;
|
||||
}
|
||||
|
||||
if (count > 1)
|
||||
os << (count > 2? '-' : ',') << current;
|
||||
}
|
||||
|
||||
template<typename T, std::size_t n>
|
||||
T* end(T (&array)[n])
|
||||
{
|
||||
return array+n;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int data[] = { 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39 };
|
||||
|
||||
extract_ranges(data, end(data), std::cout);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
58
Task/Range-extraction/C-sharp/range-extraction.cs
Normal file
58
Task/Range-extraction/C-sharp/range-extraction.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
class RangeExtraction
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
const string testString = "0, 1, 2, 4, 6, 7, 8, 11, 12, 14,15, 16, 17, 18, 19, 20, 21, 22, 23, 24,25, 27, 28, 29, 30, 31, 32, 33, 35, 36,37, 38, 39";
|
||||
var result = String.Join(",", RangesToStrings(GetRanges(testString)));
|
||||
Console.Out.WriteLine(result);
|
||||
}
|
||||
|
||||
public static IEnumerable<IEnumerable<int>> GetRanges(string testString)
|
||||
{
|
||||
var numbers = testString.Split(new[] { ',' }).Select(x => Convert.ToInt32(x));
|
||||
var current = new List<int>();
|
||||
foreach (var n in numbers)
|
||||
{
|
||||
if (current.Count == 0)
|
||||
{
|
||||
current.Add(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current.Max() + 1 == n)
|
||||
{
|
||||
current.Add(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return current;
|
||||
current = new List<int> { n };
|
||||
}
|
||||
}
|
||||
}
|
||||
yield return current;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> RangesToStrings(IEnumerable<IEnumerable<int>> ranges)
|
||||
{
|
||||
foreach (var range in ranges)
|
||||
{
|
||||
if (range.Count() == 1)
|
||||
{
|
||||
yield return range.Single().ToString();
|
||||
}
|
||||
else if (range.Count() == 2)
|
||||
{
|
||||
yield return range.Min() + "," + range.Max();
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return range.Min() + "-" + range.Max();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Task/Range-extraction/C/range-extraction-1.c
Normal file
36
Task/Range-extraction/C/range-extraction-1.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
size_t rprint(char *s, int *x, int len)
|
||||
{
|
||||
#define sep (a > s ? "," : "") /* use comma except before first output */
|
||||
#define ol (s ? 100 : 0) /* print only if not testing for length */
|
||||
int i, j;
|
||||
char *a = s;
|
||||
for (i = j = 0; i < len; i = ++j) {
|
||||
for (; j < len - 1 && x[j + 1] == x[j] + 1; j++);
|
||||
|
||||
if (i + 1 < j)
|
||||
a += snprintf(s?a:s, ol, "%s%d-%d", sep, x[i], x[j]);
|
||||
else
|
||||
while (i <= j)
|
||||
a += snprintf(s?a:s, ol, "%s%d", sep, x[i++]);
|
||||
}
|
||||
return a - s;
|
||||
#undef sep
|
||||
#undef ol
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int x[] = { 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39 };
|
||||
|
||||
char *s = malloc(rprint(0, x, sizeof(x) / sizeof(int)) + 1);
|
||||
rprint(s, x, sizeof(x) / sizeof(int));
|
||||
printf("%s\n", s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
Task/Range-extraction/C/range-extraction-2.c
Normal file
1
Task/Range-extraction/C/range-extraction-2.c
Normal file
|
|
@ -0,0 +1 @@
|
|||
0-2,4,6-8,11,12,14-25,27-33,35-39
|
||||
26
Task/Range-extraction/Common-Lisp/range-extraction.lisp
Normal file
26
Task/Range-extraction/Common-Lisp/range-extraction.lisp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
(defun format-with-ranges (list)
|
||||
(unless list (return ""))
|
||||
(with-output-to-string (s)
|
||||
(let ((current (first list))
|
||||
(list (rest list))
|
||||
(count 1))
|
||||
(princ current s)
|
||||
(dolist (next list)
|
||||
(if (= next (1+ current))
|
||||
(incf count)
|
||||
(progn (princ (if (> count 2) "-" ",") s)
|
||||
(when (> count 1)
|
||||
(princ current s)
|
||||
(princ "," s))
|
||||
(princ next s)
|
||||
(setf count 1)))
|
||||
(setf current next))
|
||||
(when (> count 1)
|
||||
(princ (if (> count 2) "-" ",") s)
|
||||
(princ current s)))))
|
||||
|
||||
CL-USER> (format-with-ranges (list 0 1 2 4 6 7 8 11 12 14
|
||||
15 16 17 18 19 20 21 22 23 24
|
||||
25 27 28 29 30 31 32 33 35 36
|
||||
37 38 39))
|
||||
"0-2,4,6-8,11,12,14-25,27-33,35-39"
|
||||
34
Task/Range-extraction/D/range-extraction.d
Normal file
34
Task/Range-extraction/D/range-extraction.d
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import std.stdio, std.conv, std.string, std.algorithm;
|
||||
|
||||
string extractRanges(in int[] items)
|
||||
in {
|
||||
assert(items.isSorted());
|
||||
} body {
|
||||
string[] ranges;
|
||||
|
||||
for (size_t i = 0; i < items.length; i++) {
|
||||
immutable low = items[i];
|
||||
while (i < (items.length - 1) && (items[i] + 1) == items[i + 1])
|
||||
i++;
|
||||
immutable hi = items[i];
|
||||
|
||||
if (hi - low >= 2)
|
||||
ranges ~= text(low, '-', hi);
|
||||
else if (hi - low == 1)
|
||||
ranges ~= text(low, ',', hi);
|
||||
else
|
||||
ranges ~= text(low);
|
||||
}
|
||||
|
||||
return ranges.join(",");
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (data; [[-8, -7, -6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9,
|
||||
10, 11, 14, 15, 17, 18, 19, 20],
|
||||
[0, 0, 0, 1, 1],
|
||||
[0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31,
|
||||
32, 33, 35, 36, 37, 38, 39]])
|
||||
writeln(extractRanges(data));
|
||||
}
|
||||
25
Task/Range-extraction/DWScript/range-extraction.dwscript
Normal file
25
Task/Range-extraction/DWScript/range-extraction.dwscript
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
procedure ExtractRanges(const values : array of Integer);
|
||||
begin
|
||||
var i:=0;
|
||||
while i<values.Length do begin
|
||||
if i>0 then
|
||||
Print(',');
|
||||
Print(values[i]);
|
||||
var j:=i+1;
|
||||
while (j<values.Length) and (values[j]=values[j-1]+1) do
|
||||
Inc(j);
|
||||
Dec(j);
|
||||
if j>i then begin
|
||||
if j=i+1 then
|
||||
Print(',')
|
||||
else Print('-');
|
||||
Print(values[j]);
|
||||
end;
|
||||
i:=j+1;
|
||||
end;
|
||||
end;
|
||||
|
||||
ExtractRanges([ 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39]);
|
||||
17
Task/Range-extraction/E/range-extraction-1.e
Normal file
17
Task/Range-extraction/E/range-extraction-1.e
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
def rex(numbers :List[int]) {
|
||||
var region := 0..!0
|
||||
for n in numbers { region |= n..n }
|
||||
var ranges := []
|
||||
for interval in region.getSimpleRegions() {
|
||||
def a := interval.getOptStart()
|
||||
def b := interval.getOptBound() - 1
|
||||
ranges with= if (b > a + 1) {
|
||||
`$a-$b`
|
||||
} else if (b <=> a + 1) {
|
||||
`$a,$b`
|
||||
} else { # b <=> a
|
||||
`$a`
|
||||
}
|
||||
}
|
||||
return ",".rjoin(ranges)
|
||||
}
|
||||
6
Task/Range-extraction/E/range-extraction-2.e
Normal file
6
Task/Range-extraction/E/range-extraction-2.e
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
? rex([
|
||||
> 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
> 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
> 25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
> 37, 38, 39])
|
||||
# value: "0-2,4,6-8,11,12,14-25,27-33,35-39"
|
||||
32
Task/Range-extraction/Euphoria/range-extraction.euphoria
Normal file
32
Task/Range-extraction/Euphoria/range-extraction.euphoria
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
function extract_ranges(sequence s)
|
||||
integer first
|
||||
sequence out
|
||||
out = ""
|
||||
if length(s) = 0 then
|
||||
return out
|
||||
end if
|
||||
first = 1
|
||||
for i = 2 to length(s) do
|
||||
if s[i] != s[i-1]+1 then
|
||||
if first = i-1 then
|
||||
out &= sprintf("%d,", s[first])
|
||||
elsif first = i-2 then
|
||||
out &= sprintf("%d,%d,", {s[first],s[i-1]})
|
||||
else
|
||||
out &= sprintf("%d-%d,", {s[first],s[i-1]})
|
||||
end if
|
||||
first = i
|
||||
end if
|
||||
end for
|
||||
if first = length(s) then
|
||||
out &= sprintf("%d", s[first])
|
||||
elsif first = length(s)-1 then
|
||||
out &= sprintf("%d,%d", {s[first],s[$]})
|
||||
else
|
||||
out &= sprintf("%d-%d", {s[first],s[$]})
|
||||
end if
|
||||
return out
|
||||
end function
|
||||
|
||||
puts(1, extract_ranges({0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39}))
|
||||
27
Task/Range-extraction/Forth/range-extraction.fth
Normal file
27
Task/Range-extraction/Forth/range-extraction.fth
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
create values
|
||||
here
|
||||
0 , 1 , 2 , 4 , 6 , 7 , 8 , 11 , 12 , 14 ,
|
||||
15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 ,
|
||||
25 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 35 , 36 ,
|
||||
37 , 38 , 39 ,
|
||||
here swap - 1 cells / constant /values
|
||||
|
||||
: clip 1- swap cell+ swap ; \ reduce array
|
||||
: .range2 0 .r ." -" 0 .r ; \ difference two or more
|
||||
: .range1 0 .r ." , " 0 .r ; \ difference one
|
||||
: .range0 drop 0 .r ; \ no difference
|
||||
\ select printing routine
|
||||
create .range ' .range0 , ' .range1 , ' .range2 ,
|
||||
does> >r over over - 2 min cells r> + @ execute ;
|
||||
|
||||
: .ranges ( a n --)
|
||||
over @ dup >r >r \ setup first value
|
||||
begin
|
||||
clip dup \ check length array
|
||||
while
|
||||
over @ dup r@ 1+ = \ check if range breaks
|
||||
if r> drop >r else r> r> .range ." , " dup >r >r then
|
||||
repeat 2drop r> r> .range cr \ print last range
|
||||
;
|
||||
|
||||
values /values .ranges
|
||||
55
Task/Range-extraction/Go/range-extraction.go
Normal file
55
Task/Range-extraction/Go/range-extraction.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rf, err := rangeFormat([]int{
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
fmt.Println("range format:", rf)
|
||||
}
|
||||
|
||||
func rangeFormat(a []int) (string, error) {
|
||||
if len(a) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
var parts []string
|
||||
for n1 := 0; ; {
|
||||
n2 := n1 + 1
|
||||
for n2 < len(a) && a[n2] == a[n2-1]+1 {
|
||||
n2++
|
||||
}
|
||||
s := strconv.Itoa(a[n1])
|
||||
if n2 == n1+2 {
|
||||
s += "," + strconv.Itoa(a[n2-1])
|
||||
} else if n2 > n1+2 {
|
||||
s += "-" + strconv.Itoa(a[n2-1])
|
||||
}
|
||||
parts = append(parts, s)
|
||||
if n2 == len(a) {
|
||||
break
|
||||
}
|
||||
if a[n2] == a[n2-1] {
|
||||
return "", errors.New(fmt.Sprintf(
|
||||
"sequence repeats value %d", a[n2]))
|
||||
}
|
||||
if a[n2] < a[n2-1] {
|
||||
return "", errors.New(fmt.Sprintf(
|
||||
"sequence not ordered: %d < %d", a[n2], a[n2-1]))
|
||||
}
|
||||
n1 = n2
|
||||
}
|
||||
return strings.Join(parts, ","), nil
|
||||
}
|
||||
12
Task/Range-extraction/Groovy/range-extraction-1.groovy
Normal file
12
Task/Range-extraction/Groovy/range-extraction-1.groovy
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
def range = { s, e -> s == e ? "${s}," : s == e - 1 ? "${s},${e}," : "${s}-${e}," }
|
||||
|
||||
def compressList = { list ->
|
||||
def sb, start, end
|
||||
(sb, start, end) = [''<<'', list[0], list[0]]
|
||||
for (i in list[1..-1]) {
|
||||
(sb, start, end) = i == end + 1 ? [sb, start, i] : [sb << range(start, end), i, i]
|
||||
}
|
||||
(sb << range(start, end))[0..-2].toString()
|
||||
}
|
||||
|
||||
def compressRanges = { expanded -> compressList(Eval.me('[' + expanded + ']')) }
|
||||
7
Task/Range-extraction/Groovy/range-extraction-2.groovy
Normal file
7
Task/Range-extraction/Groovy/range-extraction-2.groovy
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
def s = '''
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39
|
||||
'''
|
||||
println (compressRanges(s))
|
||||
13
Task/Range-extraction/Haskell/range-extraction-1.hs
Normal file
13
Task/Range-extraction/Haskell/range-extraction-1.hs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import Data.List (intercalate)
|
||||
|
||||
extractRange :: [Int] -> String
|
||||
extractRange = intercalate "," . f
|
||||
where f :: [Int] -> [String]
|
||||
f (x1 : x2 : x3 : xs) | x1 + 1 == x2 && x2 + 1 == x3
|
||||
= (show x1 ++ '-' : show xn) : f xs'
|
||||
where (xn, xs') = g (x3 + 1) xs
|
||||
g a (n : ns) | a == n = g (a + 1) ns
|
||||
| otherwise = (a - 1, n : ns)
|
||||
g a [] = (a - 1, [])
|
||||
f (x : xs) = show x : f xs
|
||||
f [] = []
|
||||
2
Task/Range-extraction/Haskell/range-extraction-2.hs
Normal file
2
Task/Range-extraction/Haskell/range-extraction-2.hs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
> extractRange $ [0..2] ++ 4 : [6..8] ++ 11 : 12 : [14..25] ++ [27..33] ++ [35..39]
|
||||
"0-2,4,6-8,11,12,14-25,27-33,35-39"
|
||||
33
Task/Range-extraction/Icon/range-extraction.icon
Normal file
33
Task/Range-extraction/Icon/range-extraction.icon
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
procedure main()
|
||||
|
||||
R := [ 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39 ]
|
||||
|
||||
write("Input list := ",list2string(R))
|
||||
write("Extracted sting := ",s := range_extract(R) | "FAILED")
|
||||
end
|
||||
|
||||
procedure range_extract(R) #: return string/range representation of a list of unique integers
|
||||
local s,sep,low,high,x
|
||||
|
||||
every if integer(x:= !R) ~= x then fail # ensure all are integers,
|
||||
R := sort(set(R)) # unique, and sorted
|
||||
|
||||
s := sep := ""
|
||||
while s ||:= sep || ( low := high := get(R) ) do { # lower bound of range
|
||||
sep := ","
|
||||
while high := ( R[1] = high + 1 ) do get(R) # find the end of range
|
||||
if high > low+1 then s ||:= "-" || high # - record range of 3+
|
||||
else if high = low+1 then push(R,high) # - range of 2, high becomes new low
|
||||
}
|
||||
return s
|
||||
end
|
||||
|
||||
procedure list2string(L) #: helper to convert list to string
|
||||
local s
|
||||
|
||||
every (s := "[ ") ||:= !L || " "
|
||||
return s || "]"
|
||||
end
|
||||
4
Task/Range-extraction/J/range-extraction-1.j
Normal file
4
Task/Range-extraction/J/range-extraction-1.j
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
require 'strings'
|
||||
fmt=: [: ;@(8!:0) [`]`({. ; (',-' {~ 2 < #) ; {:)@.(2 <. #)
|
||||
group=: <@fmt;.1~ 1 ~: 0 , 2 -~/\ ]
|
||||
extractRange=: ',' joinstring group
|
||||
2
Task/Range-extraction/J/range-extraction-2.j
Normal file
2
Task/Range-extraction/J/range-extraction-2.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
extractRange 0 1 2 4 6 7 8 11 12 14 15 16 17 18 19 20 21 22 23 24 25 27 28 29 30 31 32 33 35 36 37 38 39
|
||||
0-2,4,6-8,11,12,14-25,27-33,35-39
|
||||
41
Task/Range-extraction/Java/range-extraction.java
Normal file
41
Task/Range-extraction/Java/range-extraction.java
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
public class Range{
|
||||
public static void main(String[] args){
|
||||
System.out.println(compress2Range("-6, -3, -2, -1, 0, 1, 3, 4, 5, 7," +
|
||||
" 8, 9, 10, 11, 14, 15, 17, 18, 19, 20"));
|
||||
System.out.println(compress2Range(
|
||||
"0, 1, 2, 4, 6, 7, 8, 11, 12, 14, " +
|
||||
"15, 16, 17, 18, 19, 20, 21, 22, 23, 24," +
|
||||
"25, 27, 28, 29, 30, 31, 32, 33, 35, 36," +
|
||||
"37, 38, 39"));
|
||||
}
|
||||
|
||||
private static String compress2Range(String expanded){
|
||||
StringBuilder result = new StringBuilder();
|
||||
String[] nums = expanded.replace(" ", "").split(",");
|
||||
int firstNum = Integer.parseInt(nums[0]);
|
||||
int rangeSize = 0;
|
||||
for(int i = 1; i < nums.length; i++){
|
||||
int thisNum = Integer.parseInt(nums[i]);
|
||||
if(thisNum - firstNum - rangeSize == 1){
|
||||
rangeSize++;
|
||||
}else{
|
||||
if(rangeSize != 0){
|
||||
result.append(firstNum).append((rangeSize == 1) ? ",": "-")
|
||||
.append(firstNum+rangeSize).append(",");
|
||||
rangeSize = 0;
|
||||
}else{
|
||||
result.append(firstNum).append(",");
|
||||
}
|
||||
firstNum = thisNum;
|
||||
}
|
||||
}
|
||||
if(rangeSize != 0){
|
||||
result.append(firstNum).append((rangeSize == 1) ? "," : "-").
|
||||
append(firstNum + rangeSize);
|
||||
rangeSize = 0;
|
||||
} else {
|
||||
result.append(firstNum);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
35
Task/Range-extraction/JavaScript/range-extraction.js
Normal file
35
Task/Range-extraction/JavaScript/range-extraction.js
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
function rangeExtraction(list) {
|
||||
var len = list.length;
|
||||
var out = [];
|
||||
var i, j;
|
||||
|
||||
for (i = 0; i < len; i = j + 1) {
|
||||
// beginning of range or single
|
||||
out.push(list[i]);
|
||||
|
||||
// find end of range
|
||||
for (var j = i + 1; j < len && list[j] == list[j-1] + 1; j++);
|
||||
j--;
|
||||
|
||||
if (i == j) {
|
||||
// single number
|
||||
out.push(",");
|
||||
} else if (i + 1 == j) {
|
||||
// two numbers
|
||||
out.push(",", list[j], ",");
|
||||
} else {
|
||||
// range
|
||||
out.push("-", list[j], ",");
|
||||
}
|
||||
}
|
||||
out.pop(); // remove trailing comma
|
||||
return out.join("");
|
||||
}
|
||||
|
||||
// using print function as supplied by Rhino standalone
|
||||
print(rangeExtraction([
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39
|
||||
]));
|
||||
3
Task/Range-extraction/K/range-extraction-1.k
Normal file
3
Task/Range-extraction/K/range-extraction-1.k
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
grp : {(&~1=0,-':x)_ x}
|
||||
fmt : {:[1=#s:$x;s;(*s),:[3>#s;",";"-"],*|s]}
|
||||
erng: {{x,",",y}/,//'fmt'grp x}
|
||||
2
Task/Range-extraction/K/range-extraction-2.k
Normal file
2
Task/Range-extraction/K/range-extraction-2.k
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
erng 0 1 2 4 6 7 8 11 12 14 15 16 17 18 19 20 21 22 23 24 25 27 28 29 30 31 32 33 35 36 37 38 39
|
||||
"0-2,4,6-8,11,12,14-25,27-33,35-39"
|
||||
33
Task/Range-extraction/Liberty-BASIC/range-extraction.liberty
Normal file
33
Task/Range-extraction/Liberty-BASIC/range-extraction.liberty
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
s$ = "0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24," + _
|
||||
"25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39"
|
||||
print ExtractRange$( s$)
|
||||
end
|
||||
|
||||
function ExtractRange$( range$)
|
||||
n = 1
|
||||
count = ItemCount( range$, ",")
|
||||
while n <= count
|
||||
startValue = val( word$( range$, n, ","))
|
||||
m = n + 1
|
||||
while m <= count
|
||||
nextValue = val( word$( range$, m, ","))
|
||||
if nextValue - startValue <> m - n then exit while
|
||||
m = m + 1
|
||||
wend
|
||||
if m - n > 2 then
|
||||
ExtractRange$ = ExtractRange$ + str$( startValue) + "-" + str$( startValue + m - n - 1) + ","
|
||||
else
|
||||
for i = n to m - 1
|
||||
ExtractRange$ = ExtractRange$ + str$( startValue + i - n) + ","
|
||||
next i
|
||||
end if
|
||||
n = m
|
||||
wend
|
||||
ExtractRange$ = left$( ExtractRange$, len( ExtractRange$) - 1)
|
||||
end function
|
||||
|
||||
function ItemCount( list$, separator$)
|
||||
while word$( list$, ItemCount + 1, separator$) <> ""
|
||||
ItemCount = ItemCount + 1
|
||||
wend
|
||||
end function
|
||||
17
Task/Range-extraction/MUMPS/range-extraction.mumps
Normal file
17
Task/Range-extraction/MUMPS/range-extraction.mumps
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
RANGCONT(X) ;Integer range contraction
|
||||
NEW Y,I,CONT,NOTFIRST,CURR,PREV,NEXT,SEQ SET Y="",SEQ=0,PREV="",CONT=0
|
||||
FOR I=1:1:$LENGTH(X,",") DO
|
||||
.SET NOTFIRST=$LENGTH(Y),CURR=$PIECE(X,",",I),NEXT=$PIECE(X,",",I+1)
|
||||
.FOR Q:$EXTRACT(CURR)'=" " S CURR=$EXTRACT(CURR,2,$LENGTH(CURR)) ;clean up leading spaces
|
||||
.S SEQ=((CURR-1)=PREV)&((CURR+1)=NEXT)
|
||||
.IF 'NOTFIRST SET Y=CURR
|
||||
.IF NOTFIRST DO
|
||||
..;Order matters due to flags
|
||||
..IF CONT&SEQ ;Do nothing
|
||||
..IF 'CONT&'SEQ SET Y=Y_","_CURR
|
||||
..IF CONT&'SEQ SET Y=Y_CURR,CONT=0
|
||||
..IF 'CONT&SEQ SET Y=Y_"-",CONT=1
|
||||
.SET PREV=CURR
|
||||
IF CONT SET Y=Y_PREV
|
||||
K I,CONT,NOTFIRST,CURR,PREV,NEXT,SEQ
|
||||
QUIT Y
|
||||
5
Task/Range-extraction/Mathematica/range-extraction.math
Normal file
5
Task/Range-extraction/Mathematica/range-extraction.math
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
rangeExtract[data_List] := ToString[Row[
|
||||
Riffle[
|
||||
Flatten[Split[Sort[data], #2 - #1 == 1 &] /. {a_Integer, __, b_} :> Row[{a, "-", b}]],
|
||||
","]
|
||||
]];
|
||||
37
Task/Range-extraction/NetRexx/range-extraction.netrexx
Normal file
37
Task/Range-extraction/NetRexx/range-extraction.netrexx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*NetRexx program to test range extraction. ***************************
|
||||
* 07.08.2012 Walter Pachl derived from my Rexx Version
|
||||
* Changes: line continuation in aaa assignment changed
|
||||
* 1e99 -> 999999999
|
||||
* Do -> Loop
|
||||
* words(aaa) -> aaa.words()
|
||||
* word(aaa,i) -> aaa.word(i)
|
||||
**********************************************************************/
|
||||
Say 'NetRexx program derived from Rexx'
|
||||
aaa='0 1 2 4 6 7 8 11 12 14 15 16 17 18 19 20 21 22 23 24 25 27 28 29'
|
||||
aaa=aaa' 30 31 32 33 35 36 37 38 39'
|
||||
say 'old='aaa;
|
||||
aaa=aaa 999999999 /* artificial number at the end */
|
||||
i=0 /* initialize index */
|
||||
ol='' /* initialize output string */
|
||||
comma='' /* will become a ',' lateron */
|
||||
inrange=0
|
||||
Loop While i<=aaa.words /* loop for all numbers */
|
||||
i=i+1 /* index of next number */
|
||||
n=aaa.word(i) /* the now current number */
|
||||
If n=999999999 Then Leave /* we are at the end */
|
||||
If inrange Then Do /* range was opened */
|
||||
If aaa.word(i+1)<>n+1 Then Do /* following word not in range */
|
||||
ol=ol||n /* so this number is the end */
|
||||
inrange=0 /* and the range is over */
|
||||
End /* else ignore current number */
|
||||
End
|
||||
Else Do /* not in a range */
|
||||
ol=ol||comma||n /* add number (with comma) */
|
||||
comma=',' /* to the output string */
|
||||
If aaa.word(i+2)=n+2 Then Do /* if the nr after the next fits */
|
||||
inrange=1 /* open a range */
|
||||
ol=ol'-' /* append the range connector */
|
||||
End
|
||||
End
|
||||
End
|
||||
Say 'new='ol
|
||||
21
Task/Range-extraction/OCaml/range-extraction.ocaml
Normal file
21
Task/Range-extraction/OCaml/range-extraction.ocaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
let range_extract = function
|
||||
| [] -> []
|
||||
| x::xs ->
|
||||
let f (i,j,ret) k =
|
||||
if k = succ j then (i,k,ret) else (k,k,(i,j)::ret) in
|
||||
let (m,n,ret) = List.fold_left f (x,x,[]) xs in
|
||||
List.rev ((m,n)::ret)
|
||||
|
||||
let string_of_range rng =
|
||||
let str (a,b) =
|
||||
if a = b then string_of_int a
|
||||
else Printf.sprintf "%d%c%d" a (if b = succ a then ',' else '-') b in
|
||||
String.concat "," (List.map str rng)
|
||||
|
||||
let () =
|
||||
let li =
|
||||
[ 0; 1; 2; 4; 6; 7; 8; 11; 12; 14; 15; 16; 17; 18; 19; 20; 21;
|
||||
22; 23; 24; 25; 27; 28; 29; 30; 31; 32; 33; 35; 36; 37; 38; 39 ]
|
||||
in
|
||||
let rng = range_extract li in
|
||||
print_endline(string_of_range rng)
|
||||
92
Task/Range-extraction/Oberon-2/range-extraction.oberon-2
Normal file
92
Task/Range-extraction/Oberon-2/range-extraction.oberon-2
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
MODULE RangeExtraction;
|
||||
IMPORT Out;
|
||||
|
||||
PROCEDURE Range(s: ARRAY OF INTEGER);
|
||||
VAR
|
||||
i,j: INTEGER;
|
||||
|
||||
PROCEDURE Emit(sep: CHAR);
|
||||
BEGIN
|
||||
IF i > 2 THEN
|
||||
Out.Int(s[j],3);Out.Char('-');Out.Int(s[j + i - 1],3);Out.Char(sep);
|
||||
INC(j,i)
|
||||
ELSE
|
||||
Out.Int(s[j],3);Out.Char(sep);
|
||||
INC(j)
|
||||
END;
|
||||
END Emit;
|
||||
|
||||
BEGIN
|
||||
j := 0;i := -1;
|
||||
LOOP
|
||||
INC(i);
|
||||
IF j + i >= LEN(s) THEN
|
||||
Emit(0AX);
|
||||
EXIT
|
||||
ELSIF s[j + i] # (s[j] + i) THEN
|
||||
Emit(',');
|
||||
i := 0;
|
||||
END
|
||||
END
|
||||
END Range;
|
||||
|
||||
VAR
|
||||
seq0: ARRAY 33 OF INTEGER;
|
||||
seq1: ARRAY 20 OF INTEGER;
|
||||
BEGIN
|
||||
seq0[0] := 0;
|
||||
seq0[1] := 1;
|
||||
seq0[2] := 2;
|
||||
seq0[3] := 4;
|
||||
seq0[4] := 6;
|
||||
seq0[5] := 7;
|
||||
seq0[6] := 8;
|
||||
seq0[7] := 11;
|
||||
seq0[8] := 12;
|
||||
seq0[9] := 14;
|
||||
seq0[10] := 15;
|
||||
seq0[11] := 16;
|
||||
seq0[12] := 17;
|
||||
seq0[13] := 18;
|
||||
seq0[14] := 19;
|
||||
seq0[15] := 20;
|
||||
seq0[16] := 21;
|
||||
seq0[17] := 22;
|
||||
seq0[18] := 23;
|
||||
seq0[19] := 24;
|
||||
seq0[20] := 25;
|
||||
seq0[21] := 27;
|
||||
seq0[22] := 28;
|
||||
seq0[23] := 29;
|
||||
seq0[24] := 30;
|
||||
seq0[25] := 31;
|
||||
seq0[26] := 32;
|
||||
seq0[27] := 33;
|
||||
seq0[28] := 35;
|
||||
seq0[29] := 36;
|
||||
seq0[30] := 37;
|
||||
seq0[31] := 38;
|
||||
seq0[32] := 39;
|
||||
Range(seq0);
|
||||
seq1[0] := -6;
|
||||
seq1[1] := -3;
|
||||
seq1[2] := -2;
|
||||
seq1[3] := -1;
|
||||
seq1[4] := 0;
|
||||
seq1[5] := 1;
|
||||
seq1[6] := 3;
|
||||
seq1[7] := 4;
|
||||
seq1[8] := 5;
|
||||
seq1[9] := 7;
|
||||
seq1[10] := 8;
|
||||
seq1[11] := 9;
|
||||
seq1[12] := 10;
|
||||
seq1[13] := 11;
|
||||
seq1[14] := 14;
|
||||
seq1[15] := 15;
|
||||
seq1[16] := 17;
|
||||
seq1[17] := 18;
|
||||
seq1[18] := 19;
|
||||
seq1[19] := 20;
|
||||
Range(seq1)
|
||||
END RangeExtraction.
|
||||
38
Task/Range-extraction/OxygenBasic/range-extraction.oxy
Normal file
38
Task/Range-extraction/OxygenBasic/range-extraction.oxy
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
dim sys ints(100)
|
||||
ints=>
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39
|
||||
|
||||
function ShowRange(sys*i) as string
|
||||
'==================================
|
||||
pr=""
|
||||
n=0
|
||||
e=0
|
||||
j=0
|
||||
k=-1
|
||||
do
|
||||
j++
|
||||
n=i(j)
|
||||
e=i(j+1)
|
||||
if e<j then
|
||||
exit do
|
||||
end if
|
||||
if e=n+1 and i(j+2)=n+2 then 'LOOKAHEAD
|
||||
if k=-1 then k=n
|
||||
else
|
||||
if k>=0 then
|
||||
pr+=k "-" i(j+1) ", " 'RANGE OF VALUES
|
||||
j++
|
||||
k=-1
|
||||
else
|
||||
pr+=n ", " 'SINGLE VALUES
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
return left pr, len(pr)-2
|
||||
end function
|
||||
|
||||
|
||||
print ShowRange ints
|
||||
47
Task/Range-extraction/Oz/range-extraction-1.oz
Normal file
47
Task/Range-extraction/Oz/range-extraction-1.oz
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
declare
|
||||
fun {Extract Xs}
|
||||
{CommaSeparated
|
||||
{Map {ExtractRanges Xs} RangeToString}}
|
||||
end
|
||||
|
||||
fun {ExtractRanges Xs}
|
||||
fun {Loop Ys Start End}
|
||||
case Ys
|
||||
of Y|Yr andthen Y == End+1 then {Loop Yr Start Y}
|
||||
[] Y|Yr then Start#End|{Loop Yr Y Y}
|
||||
[] nil then [Start#End]
|
||||
end
|
||||
end
|
||||
in
|
||||
case Xs
|
||||
of X|Xr then {Loop Xr X X}
|
||||
[] nil then nil
|
||||
end
|
||||
end
|
||||
|
||||
fun {RangeToString S#E}
|
||||
if E-S >= 2 then
|
||||
{VirtualString.toString S#"-"#E}
|
||||
else
|
||||
{CommaSeparated
|
||||
{Map {List.number S E 1} Int.toString}}
|
||||
end
|
||||
end
|
||||
|
||||
fun {CommaSeparated Xs}
|
||||
{Flatten {Intersperse "," Xs}}
|
||||
end
|
||||
|
||||
fun {Intersperse Sep Xs}
|
||||
case Xs of X|Y|Xr then
|
||||
X|Sep|{Intersperse Sep Y|Xr}
|
||||
else
|
||||
Xs
|
||||
end
|
||||
end
|
||||
in
|
||||
{System.showInfo
|
||||
{Extract [ 0 1 2 4 6 7 8 11 12 14
|
||||
15 16 17 18 19 20 21 22 23 24
|
||||
25 27 28 29 30 31 32 33 35 36
|
||||
37 38 39 ]}}
|
||||
1
Task/Range-extraction/Oz/range-extraction-2.oz
Normal file
1
Task/Range-extraction/Oz/range-extraction-2.oz
Normal file
|
|
@ -0,0 +1 @@
|
|||
0-2,4,6-8,11,12,14-25,27-33,35-39
|
||||
48
Task/Range-extraction/PL-I/range-extraction-1.pli
Normal file
48
Task/Range-extraction/PL-I/range-extraction-1.pli
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* Modified 19 November 2011 to meet requirement that there be at */
|
||||
/* least 3 items in a run. */
|
||||
range_extraction: /* 17 August 2010 */
|
||||
procedure options (main);
|
||||
declare (c, d) character (1);
|
||||
declare (old, new, initial) fixed binary (31);
|
||||
declare in file;
|
||||
declare out file output;
|
||||
|
||||
open file (in) title ('/range2.dat,type(text),recsize(80)' );
|
||||
open file (out) output title ('/range2.out,type(text),recsize(70)');
|
||||
|
||||
c = ' '; d = ',';
|
||||
get file (in) list (old);
|
||||
do forever;
|
||||
initial = old;
|
||||
on endfile (in) begin;
|
||||
put file (out) edit (c, trim(old)) (a);
|
||||
stop;
|
||||
end;
|
||||
get file (in) list (new);
|
||||
if new = old+1 then
|
||||
do; /* we have a run. */
|
||||
on endfile (in) begin;
|
||||
if old > initial+1 then d = '-';
|
||||
put file (out) edit (c, trim(initial), d, trim(old) ) (a);
|
||||
stop;
|
||||
end;
|
||||
do while (new = old+1);
|
||||
old = new;
|
||||
get file (in) list (new);
|
||||
end;
|
||||
/* At this point, old holds the last in a run; */
|
||||
/* initial holds the first in a run. */
|
||||
/* if there are only two members in a run, don't use the */
|
||||
/* range notation. */
|
||||
if old > initial+1 then d = '-';
|
||||
put file (out) edit (c, trim(initial), d, trim(old) ) (a);
|
||||
old = new;
|
||||
end;
|
||||
else /* we have an isolated value. */
|
||||
do;
|
||||
put file (out) edit (c, trim(old)) (a);
|
||||
old = new;
|
||||
end;
|
||||
c, d = ',';
|
||||
end;
|
||||
end range_extraction;
|
||||
1
Task/Range-extraction/PL-I/range-extraction-2.pli
Normal file
1
Task/Range-extraction/PL-I/range-extraction-2.pli
Normal file
|
|
@ -0,0 +1 @@
|
|||
0-2,4,6-8,11-12,14-25,27-33,35-39
|
||||
1
Task/Range-extraction/PL-I/range-extraction-3.pli
Normal file
1
Task/Range-extraction/PL-I/range-extraction-3.pli
Normal file
|
|
@ -0,0 +1 @@
|
|||
0-2,4,6-8,11,12,14-25,27-33,35-39
|
||||
24
Task/Range-extraction/Perl-6/range-extraction.pl6
Normal file
24
Task/Range-extraction/Perl-6/range-extraction.pl6
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
sub range-extraction (*@ints) {
|
||||
my $prev = NaN;
|
||||
my @ranges;
|
||||
|
||||
for @ints -> $int {
|
||||
if $int == $prev + 1 {
|
||||
@ranges[*-1].push: $int;
|
||||
}
|
||||
else {
|
||||
@ranges.push: [$int];
|
||||
}
|
||||
$prev = $int;
|
||||
}
|
||||
join ',', @ranges.map: -> @r { @r > 2 ?? "@r[0]-@r[*-1]" !! @r }
|
||||
}
|
||||
|
||||
say range-extraction
|
||||
-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20;
|
||||
|
||||
say range-extraction
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39;
|
||||
15
Task/Range-extraction/Perl/range-extraction.pl
Normal file
15
Task/Range-extraction/Perl/range-extraction.pl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
sub rangext {
|
||||
my $str = join ' ', @_;
|
||||
1 while $str =~ s{([+-]?\d+) ([+-]?\d+)}
|
||||
{$1.(abs($2 - $1) == 1 ? '~' : ',').$2}eg; # abs for neg ranges
|
||||
$str =~ s/(\d+)~(?:[+-]?\d+~)+([+-]?\d+)/$1-$2/g;
|
||||
$str =~ tr/~/,/;
|
||||
return $str;
|
||||
}
|
||||
|
||||
# Test and display
|
||||
my @test = qw(0 1 2 4 6 7 8 11 12 14,
|
||||
15 16 17 18 19 20 21 22 23 24,
|
||||
25 27 28 29 30 31 32 33 35 36,
|
||||
37 38 39);
|
||||
print rangext(@test), "\n";
|
||||
11
Task/Range-extraction/PicoLisp/range-extraction.l
Normal file
11
Task/Range-extraction/PicoLisp/range-extraction.l
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
(de rangeextract (Lst)
|
||||
(glue ","
|
||||
(make
|
||||
(while Lst
|
||||
(let (N (pop 'Lst) M N)
|
||||
(while (= (inc M) (car Lst))
|
||||
(setq M (pop 'Lst)) )
|
||||
(cond
|
||||
((= N M) (link N))
|
||||
((= (inc N) M) (link N M))
|
||||
(T (link (list N '- M))) ) ) ) ) ) )
|
||||
89
Task/Range-extraction/Prolog/range-extraction.pro
Normal file
89
Task/Range-extraction/Prolog/range-extraction.pro
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
range_extract :-
|
||||
L = [0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39] ,
|
||||
writeln(L),
|
||||
pack_Range(L, LP),
|
||||
maplist(study_Range, R, LP),
|
||||
extract_Range(LA, R),
|
||||
atom_chars(A, LA),
|
||||
writeln(A).
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% extract_Range(?In, ?Out)
|
||||
% In : '-6,-3--1,3-5,7-11,14,15,17-20' =>
|
||||
% Out : [-6], [-3--1], [3-5],[7-11], [14],[15], [17-20]
|
||||
%
|
||||
extract_Range([], []).
|
||||
|
||||
|
||||
extract_Range(X , [Range | Y1]) :-
|
||||
get_Range(X, U-U, Range, X1),
|
||||
extract_Range(X1, Y1).
|
||||
|
||||
|
||||
|
||||
get_Range([], Range-[], Range, []).
|
||||
get_Range([','|B], Range-[], Range, B) :- !.
|
||||
|
||||
get_Range([A | B], EC, Range, R) :-
|
||||
append_dl(EC, [A | U]-U, NEC),
|
||||
get_Range(B, NEC, Range, R).
|
||||
|
||||
|
||||
append_dl(X-Y, Y-Z, X-Z).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% study Range(?In, ?Out)
|
||||
% In : [-6]
|
||||
% Out : [-6,-6]
|
||||
%
|
||||
% In : [-3--1]
|
||||
% Out : [-3, -1]
|
||||
%
|
||||
study_Range(Range1, [Deb, Deb]) :-
|
||||
catch(number_chars(Deb, Range1), Deb, false).
|
||||
|
||||
study_Range(Range1, [Deb, Fin]) :-
|
||||
append(A, ['-'|B], Range1),
|
||||
A \= [],
|
||||
number_chars(Deb, A),
|
||||
number_chars(Fin, B).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
:- use_module(library(clpfd)).
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Pack Range(?In, ?Out)
|
||||
% In : -6,
|
||||
% Out : [-6]
|
||||
%
|
||||
% In : -3, -2,-1
|
||||
% Out : [-3,-1]
|
||||
%
|
||||
pack_Range([],[]).
|
||||
|
||||
pack_Range([X|Rest],[[X | V]|Packed]):-
|
||||
run(X,Rest, [X|V], RRest),
|
||||
pack_Range(RRest,Packed).
|
||||
|
||||
|
||||
|
||||
run(Fin,[Other|RRest], [Deb, Fin],[Other|RRest]):-
|
||||
Fin #\= Deb,
|
||||
Fin #\= Deb + 1,
|
||||
Other #\= Fin+1.
|
||||
|
||||
run(Fin,[],[_Var, Fin],[]).
|
||||
|
||||
run(Var,[Var1|LRest],[Deb, Fin], RRest):-
|
||||
Fin #\= Deb,
|
||||
Fin #\= Deb + 1,
|
||||
Var1 #= Var + 1,
|
||||
run(Var1,LRest,[Deb, Fin], RRest).
|
||||
|
||||
run(Val,[Other|RRest], [Val, Val],[Other|RRest]).
|
||||
70
Task/Range-extraction/PureBasic/range-extraction.purebasic
Normal file
70
Task/Range-extraction/PureBasic/range-extraction.purebasic
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
DataSection
|
||||
Data.i 33 ;count of elements to be read
|
||||
Data.i 0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
|
||||
Data.i 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39
|
||||
EndDataSection
|
||||
|
||||
NewList values()
|
||||
;setup list
|
||||
Define elementCount, i
|
||||
Read.i elementCount
|
||||
For i = 1 To elementCount
|
||||
AddElement(values()): Read.i values()
|
||||
Next
|
||||
|
||||
Procedure.s rangeExtract(List values())
|
||||
Protected listSize = ListSize(values()) - 1
|
||||
Protected rangeMarker, rangeStart, rangeIncrement, retraceSteps, rangeSize, endOfRange, output.s, sub.s
|
||||
|
||||
ForEach values()
|
||||
rangeStart = values():
|
||||
sub = Str(rangeStart)
|
||||
If NextElement(values())
|
||||
retraceSteps = 1
|
||||
rangeIncrement = values() - rangeStart
|
||||
If rangeIncrement = 1 Or rangeIncrement = -1
|
||||
;found start of possible range
|
||||
If ListIndex(values()) <> listSize
|
||||
retraceSteps = 2
|
||||
rangeSize = 2
|
||||
endOfRange = #False
|
||||
rangeMarker = values()
|
||||
While NextElement(values())
|
||||
If values() - rangeMarker <> rangeIncrement
|
||||
endOfRange = #True
|
||||
Break
|
||||
EndIf
|
||||
rangeSize + 1
|
||||
rangeMarker = values()
|
||||
Wend
|
||||
|
||||
If rangeSize > 2
|
||||
sub = Str(rangeStart) + "-" + Str(rangeMarker)
|
||||
If Not endOfRange
|
||||
retraceSteps = 0 ;at end of list
|
||||
Else
|
||||
retraceSteps = 1
|
||||
EndIf
|
||||
EndIf
|
||||
EndIf
|
||||
EndIf
|
||||
|
||||
;return to the value before look-aheads
|
||||
While retraceSteps > 0
|
||||
PreviousElement(values()): retraceSteps - 1
|
||||
Wend
|
||||
EndIf
|
||||
|
||||
output + sub + ","
|
||||
Next
|
||||
|
||||
ProcedureReturn RTrim(output, ",")
|
||||
EndProcedure
|
||||
|
||||
If OpenConsole()
|
||||
PrintN(rangeExtract(values()))
|
||||
|
||||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
|
||||
Input()
|
||||
CloseConsole()
|
||||
EndIf
|
||||
19
Task/Range-extraction/Python/range-extraction-1.py
Normal file
19
Task/Range-extraction/Python/range-extraction-1.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
def rangeextract(lst):
|
||||
lenlst = len(lst)
|
||||
i, ranges = 0, []
|
||||
while i< lenlst:
|
||||
low = lst[i]
|
||||
while i <lenlst-1 and lst[i]+1 == lst[i+1]: i +=1
|
||||
hi = lst[i]
|
||||
ranges.append(
|
||||
'%i-%i' % (low, hi) if hi - low >= 2 else
|
||||
('%i,%i' % (low, hi) if hi - low == 1 else
|
||||
'%i' % low) )
|
||||
i += 1
|
||||
return ','.join(ranges)
|
||||
|
||||
lst = [ 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39]
|
||||
print(rangeextract(lst))
|
||||
26
Task/Range-extraction/Python/range-extraction-2.py
Normal file
26
Task/Range-extraction/Python/range-extraction-2.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
def grouper(lst):
|
||||
src = iter(lst)
|
||||
acc = [ next(src) ]
|
||||
for i in src:
|
||||
if i == acc[-1] + 1: acc.append(i)
|
||||
else:
|
||||
yield acc
|
||||
acc = [i]
|
||||
yield acc
|
||||
raise StopIteration()
|
||||
|
||||
def rangegrouper(lst):
|
||||
for g in grouper(lst):
|
||||
if len(g) == 2:
|
||||
# satisfy rule that only runs longer than 2 are grouped
|
||||
a,b = g
|
||||
yield [a]
|
||||
yield [b]
|
||||
else: yield g
|
||||
raise StopIteration()
|
||||
|
||||
input= [0, 1, 2, 4, 6, 7, 8, 11, 12, 14,15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36,37, 38, 39]
|
||||
print list(rangegrouper(input)) # print groups
|
||||
as_strings= ['%s%s%s' % ((g[0],'-',g[-1]) if len(g) > 1 else (g[0],'','')) for g in rangegrouper(input)]
|
||||
print as_strings
|
||||
print ', '.join(as_strings)
|
||||
17
Task/Range-extraction/Qi/range-extraction.qi
Normal file
17
Task/Range-extraction/Qi/range-extraction.qi
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
(define make-range
|
||||
Start Start -> ["," Start]
|
||||
Start End -> ["," Start "," End] where (= End (+ Start 1))
|
||||
Start End -> ["," Start "-" End])
|
||||
|
||||
(define range-extract-0
|
||||
Start End [] -> (make-range Start End)
|
||||
Start End [A|As] -> (range-extract-0 Start A As) where (= (+ 1 End) A)
|
||||
Start End [A|As] -> (append (make-range Start End) (range-extract-0 A A As)))
|
||||
|
||||
(define range-extract
|
||||
[A |As] -> (FORMAT NIL "~{~a~}" (tail (range-extract-0 A A As))))
|
||||
|
||||
(range-extract [ 0 1 2 4 6 7 8 11 12 14
|
||||
15 16 17 18 19 20 21 22 23 24
|
||||
25 27 28 29 30 31 32 33 35 36
|
||||
37 38 39])
|
||||
30
Task/Range-extraction/REXX/range-extraction-1.rexx
Normal file
30
Task/Range-extraction/REXX/range-extraction-1.rexx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*REXX program to test range extraction. */
|
||||
aaa='0 1 2 4 6 7 8 11 12 14 15 16 17 18 19 20 21 22',
|
||||
'23 24 25 27 28 29 30 31 32 33 35 36 37 38 39'
|
||||
say 'old =' aaa; say /*show the old range of numbers. */
|
||||
new= /*new list (maybe with ranges). */
|
||||
w=words(aaa) /*number of numbers in the list. */
|
||||
/*Note: index of DO (J) gets modified within loop !.*/
|
||||
do j=1 to w /*step through num word in list.*/
|
||||
_=word(aaa,j) /*get the Jth number in the list.*/
|
||||
new=new',' _ /*append Jth number to new list.*/
|
||||
inc=1 /*start with an increment of one.*/
|
||||
|
||||
do k=j+1 to w /*now, search for end of range. */
|
||||
__=word(aaa,k) /*get the Kth number in the list.*/
|
||||
if __ \== _+inc then leave /*this number 1 > than prev? */
|
||||
inc=inc+1 /*yes, then increase the range. */
|
||||
g_ = __ /*placeholder for last good num. */
|
||||
end /*k*/
|
||||
|
||||
k=k-1 /*fudge the Kth word (subtract 1)*/
|
||||
if k == j then iterate /*no range? Then keep truckin'.*/
|
||||
if g_ == _+1 then iterate /*range of 1? Then keep truckin'.*/
|
||||
new=new'-'g_ /*indicate a range of numbers. */
|
||||
j=k /*Bad practice!! Change DO index.*/
|
||||
end /*j*/
|
||||
|
||||
new=substr(new,3) /*remove extraneous leading comma*/
|
||||
new=space(new,0) /*remove all spaces (blanks). */
|
||||
say 'new =' new /*display new list of numbers. */
|
||||
/*stick a fork in it, we're done.*/
|
||||
31
Task/Range-extraction/REXX/range-extraction-2.rexx
Normal file
31
Task/Range-extraction/REXX/range-extraction-2.rexx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*REXX program to test range extraction. ******************************
|
||||
* 07.08.2012 Walter Pachl
|
||||
**********************************************************************/
|
||||
aaa='0 1 2 4 6 7 8 11 12 14 15 16 17 18 19 20 21 22 23 24 25 27 28 29',
|
||||
'30 31 32 33 35 36 37 38 39'
|
||||
say 'old='aaa;
|
||||
aaa=aaa 1e99 /* artificial number at the end */
|
||||
i=0 /* initialize index */
|
||||
ol='' /* initialize output string */
|
||||
comma='' /* will become a ',' lateron */
|
||||
inrange=0
|
||||
Do While i<=words(aaa) /* loop for all numbers */
|
||||
i=i+1 /* index of next number */
|
||||
n=word(aaa,i) /* the now current number */
|
||||
If n=1e99 Then Leave /* we are at the end */
|
||||
If inrange Then Do /* range was opened */
|
||||
If word(aaa,i+1)<>n+1 Then Do /* following word not in range */
|
||||
ol=ol||n /* so this number is the end */
|
||||
inrange=0 /* and the range is over */
|
||||
End /* else ignore current number */
|
||||
End
|
||||
Else Do /* not in a range */
|
||||
ol=ol||comma||n /* add number (with comma) */
|
||||
comma=',' /* to the output string */
|
||||
If word(aaa,i+2)=n+2 Then Do /* if the nr after the next fits */
|
||||
inrange=1 /* open a range */
|
||||
ol=ol'-' /* append the range connector */
|
||||
End
|
||||
End
|
||||
End
|
||||
Say 'new='ol
|
||||
27
Task/Range-extraction/Ruby/range-extraction.rb
Normal file
27
Task/Range-extraction/Ruby/range-extraction.rb
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
def range_extract(l)
|
||||
sorted = l.sort
|
||||
range = []
|
||||
start = sorted.first
|
||||
# pad the list with a big value, so that the last loop iteration will
|
||||
# appended something to the range
|
||||
sorted.concat([Float::MAX]).each_cons(2) do |prev,n|
|
||||
if prev.succ < n
|
||||
if start == prev
|
||||
range << start.to_s
|
||||
else
|
||||
range << "%d%s%d" % [start, (start.succ == prev ? "," : "-"), prev]
|
||||
end
|
||||
start = n
|
||||
end
|
||||
end
|
||||
range.join(',')
|
||||
end
|
||||
|
||||
lst = [
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39
|
||||
]
|
||||
|
||||
p rng = range_extract(lst)
|
||||
22
Task/Range-extraction/SNOBOL4/range-extraction.sno
Normal file
22
Task/Range-extraction/SNOBOL4/range-extraction.sno
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
* # Absolute value
|
||||
define('abs(n)') :(abs_end)
|
||||
abs abs = ~(abs = lt(n,0) -n) n :(return)
|
||||
abs_end
|
||||
|
||||
define('rangext(str)d1,d2') :(rangext_end)
|
||||
rangext num = ('+' | '-' | '') span('0123456789')
|
||||
rxt1 str ',' span(' ') = ' ' :s(rxt1)
|
||||
rxt2 str num . d1 ' ' num . d2 =
|
||||
+ d1 ('~,' ? *eq(abs(d2 - d1),1) '~' | ',') d2 :s(rxt2)
|
||||
rxt3 str ('~' | '-') num '~' = '-' :s(rxt3)
|
||||
rxt4 str '~' = ',' :s(rxt4)
|
||||
rangext = str :(return)
|
||||
rangext_end
|
||||
|
||||
* # Test and display
|
||||
test = '0, 1, 2, 4, 6, 7, 8, 11, 12, 14, '
|
||||
+ '15, 16, 17, 18, 19, 20, 21, 22, 23, 24, '
|
||||
+ '25, 27, 28, 29, 30, 31, 32, 33, 35, 36, '
|
||||
+ '37, 38, 39'
|
||||
output = rangext(test)
|
||||
end
|
||||
25
Task/Range-extraction/Scala/range-extraction.scala
Normal file
25
Task/Range-extraction/Scala/range-extraction.scala
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
object Range {
|
||||
def spanRange(ls:List[Int])={
|
||||
var last=ls.head
|
||||
ls span {x => val b=x<=last+1; last=x; b}
|
||||
}
|
||||
|
||||
def toRangeList(ls:List[Int]):List[List[Int]]=ls match {
|
||||
case Nil => List()
|
||||
case _ => spanRange(ls) match {
|
||||
case (range, Nil) => List(range)
|
||||
case (range, rest) => range :: toRangeList(rest)
|
||||
}
|
||||
}
|
||||
|
||||
def toRangeString(ls:List[List[Int]])=ls map {r=>
|
||||
if(r.size<3) r mkString ","
|
||||
else r.head + "-" + r.last
|
||||
} mkString ","
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
var l=List(0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||
27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39)
|
||||
println(toRangeString(toRangeList(l)))
|
||||
}
|
||||
}
|
||||
28
Task/Range-extraction/Scheme/range-extraction.ss
Normal file
28
Task/Range-extraction/Scheme/range-extraction.ss
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
(define (make-range start end)
|
||||
(cond ((= start end)
|
||||
`("," ,start))
|
||||
((= end (+ start 1))
|
||||
`("," ,start "," ,end))
|
||||
(else
|
||||
`("," ,start "-" ,end))))
|
||||
|
||||
(define (range-extract-0 start end a)
|
||||
(cond ((null? a)
|
||||
(make-range start end))
|
||||
((= (+ 1 end) (car a))
|
||||
(range-extract-0 start (car a) (cdr a)))
|
||||
(else
|
||||
(append (make-range start end)
|
||||
(range-extract-0 (car a) (car a) (cdr a))))))
|
||||
|
||||
(define (range-extract a)
|
||||
(apply string-append (map (lambda (x)
|
||||
(if (number? x)
|
||||
(number->string x)
|
||||
x))
|
||||
(cdr (range-extract-0 (car a) (car a) (cdr a))))))
|
||||
|
||||
(range-extract '( 0 1 2 4 6 7 8 11 12 14
|
||||
15 16 17 18 19 20 21 22 23 24
|
||||
25 27 28 29 30 31 32 33 35 36
|
||||
37 38 39))
|
||||
32
Task/Range-extraction/Seed7/range-extraction.seed7
Normal file
32
Task/Range-extraction/Seed7/range-extraction.seed7
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
$ include "seed7_05.s7i";
|
||||
|
||||
const func string: rangeExtraction (in array integer: numbers) is func
|
||||
result
|
||||
var string: rangeStri is "";
|
||||
local
|
||||
var integer: index is 1;
|
||||
var integer: index2 is 1;
|
||||
begin
|
||||
while index <= length(numbers) do
|
||||
while index2 <= pred(length(numbers)) and numbers[succ(index2)] = succ(numbers[index2]) do
|
||||
incr(index2);
|
||||
end while;
|
||||
if succ(index) < index2 then
|
||||
rangeStri &:= "," <& numbers[index] <& "-" <& numbers[index2];
|
||||
else
|
||||
while index <= index2 do
|
||||
rangeStri &:= "," <& numbers[index];
|
||||
incr(index);
|
||||
end while;
|
||||
end if;
|
||||
incr(index2);
|
||||
index := index2;
|
||||
end while;
|
||||
rangeStri := rangeStri[2 ..];
|
||||
end func;
|
||||
|
||||
const proc: main is func
|
||||
begin
|
||||
writeln(rangeExtraction([] (0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39)));
|
||||
end func;
|
||||
13
Task/Range-extraction/TUSCRIPT/range-extraction-1.tuscript
Normal file
13
Task/Range-extraction/TUSCRIPT/range-extraction-1.tuscript
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
$$ MODE TUSCRIPT
|
||||
MODE DATA
|
||||
$$ numbers=*
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39
|
||||
$$ MODE TUSCRIPT
|
||||
numbers=EXCHANGE (numbers,":,><<> :':")
|
||||
unrangednrs=JOIN (numbers,"")
|
||||
rangednrs=COMBINE (unrangednrs,"")
|
||||
rangednrs=EXCHANGE (rangednrs,":':,:")
|
||||
PRINT rangednrs
|
||||
31
Task/Range-extraction/TUSCRIPT/range-extraction-2.tuscript
Normal file
31
Task/Range-extraction/TUSCRIPT/range-extraction-2.tuscript
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
$$ MODE TUSCRIPT
|
||||
MODE DATA
|
||||
$$ numbers=*
|
||||
0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
||||
37, 38, 39
|
||||
$$ MODE TUSCRIPT
|
||||
numbers=EXCHANGE (numbers,":,><<> :':")
|
||||
unrangednrs=JOIN (numbers,"")
|
||||
|
||||
help = APPEND (unrangednrs, "999999999")
|
||||
rest = REMOVE (help, 1, n_1)
|
||||
n_2 = n_1, n_3= n_2 + 1,rangednrs= ""
|
||||
LOOP n= rest
|
||||
IF (n!=n_3) THEN
|
||||
rangednrs = APPEND (rangednrs, n_1)
|
||||
IF (n_1!=n_2) THEN
|
||||
range=n_1+1
|
||||
IF (range==n_2) THEN
|
||||
rangednrs = APPEND (rangednrs,n_2)
|
||||
ELSE
|
||||
rangednrs = CONCAT (rangednrs, "-", n_2)
|
||||
ENDIF
|
||||
ENDIF
|
||||
n_1 = n
|
||||
ENDIF
|
||||
n_2 = n, n_3 = n_2 + 1
|
||||
ENDLOOP
|
||||
rangednrs=EXCHANGE (rangednrs,":':,:")
|
||||
PRINT rangednrs
|
||||
29
Task/Range-extraction/Tcl/range-extraction.tcl
Normal file
29
Task/Range-extraction/Tcl/range-extraction.tcl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
proc rangeExtract list {
|
||||
set result [lindex $list 0]
|
||||
set first [set last [lindex $list 0]]
|
||||
foreach term [lrange $list 1 end] {
|
||||
if {$term == $last+1} {
|
||||
set last $term
|
||||
continue
|
||||
}
|
||||
if {$last > $first} {
|
||||
append result [expr {$last == $first+1 ? "," : "-"}] $last
|
||||
}
|
||||
append result "," $term
|
||||
set first [set last $term]
|
||||
}
|
||||
if {$last == $first+1} {
|
||||
append result "," $last
|
||||
} elseif {$last > $first} {
|
||||
append result "-" $last
|
||||
}
|
||||
return $result
|
||||
}
|
||||
|
||||
# Commas already removed so it is a natural Tcl list
|
||||
puts [rangeExtract {
|
||||
0 1 2 4 6 7 8 11 12 14
|
||||
15 16 17 18 19 20 21 22 23 24
|
||||
25 27 28 29 30 31 32 33 35 36
|
||||
37 38 39
|
||||
}]
|
||||
10
Task/Range-extraction/Ursala/range-extraction.ursala
Normal file
10
Task/Range-extraction/Ursala/range-extraction.ursala
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#import std
|
||||
#import int
|
||||
|
||||
x = <0,1,2,4,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39>
|
||||
|
||||
f = mat`,+ ==?(~&l,^|T/~& :/`-)*bhPS+ %zP~~hzX*titZBPiNCSiNCQSL+ rlc ^|E/~& predecessor
|
||||
|
||||
#show+
|
||||
|
||||
t = <f x>
|
||||
70
Task/Range-extraction/VBA/range-extraction.vba
Normal file
70
Task/Range-extraction/VBA/range-extraction.vba
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
Public Function RangeExtraction(AList) As String
|
||||
'AList is a variant that is an array, assumed filled with numbers in ascending order
|
||||
Const RangeDelim = "-" 'range delimiter
|
||||
Dim result As String
|
||||
Dim InRange As Boolean
|
||||
Dim Posn, ub, lb, rangestart, rangelen As Integer
|
||||
|
||||
result = ""
|
||||
'find dimensions of AList
|
||||
ub = UBound(AList)
|
||||
lb = LBound(AList)
|
||||
Posn = lb
|
||||
While Posn < ub
|
||||
rangestart = Posn
|
||||
rangelen = 0
|
||||
InRange = True
|
||||
'try to extend the range
|
||||
While InRange
|
||||
rangelen = rangelen + 1
|
||||
If Posn = ub Then
|
||||
InRange = False
|
||||
Else
|
||||
InRange = (AList(Posn + 1) = AList(Posn) + 1)
|
||||
Posn = Posn + 1
|
||||
End If
|
||||
Wend
|
||||
If rangelen > 2 Then 'output the range if it has more than 2 elements
|
||||
result = result & "," & Format$(AList(rangestart)) & RangeDelim & Format$(AList(rangestart + rangelen - 1))
|
||||
Else 'output the separate elements
|
||||
For i = rangestart To rangestart + rangelen - 1
|
||||
result = result & "," & Format$(AList(i))
|
||||
Next
|
||||
End If
|
||||
Posn = rangestart + rangelen
|
||||
Wend
|
||||
RangeExtraction = Mid$(result, 2) 'get rid of first comma!
|
||||
End Function
|
||||
|
||||
|
||||
Public Sub RangeTest()
|
||||
'test function RangeExtraction
|
||||
'first test with a Variant array
|
||||
Dim MyList As Variant
|
||||
MyList = Array(0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39)
|
||||
Debug.Print "a) "; RangeExtraction(MyList)
|
||||
|
||||
'next test with an array of integers
|
||||
Dim MyOtherList(1 To 20) As Integer
|
||||
MyOtherList(1) = -6
|
||||
MyOtherList(2) = -3
|
||||
MyOtherList(3) = -2
|
||||
MyOtherList(4) = -1
|
||||
MyOtherList(5) = 0
|
||||
MyOtherList(6) = 1
|
||||
MyOtherList(7) = 3
|
||||
MyOtherList(8) = 4
|
||||
MyOtherList(9) = 5
|
||||
MyOtherList(10) = 7
|
||||
MyOtherList(11) = 8
|
||||
MyOtherList(12) = 9
|
||||
MyOtherList(13) = 10
|
||||
MyOtherList(14) = 11
|
||||
MyOtherList(15) = 14
|
||||
MyOtherList(16) = 15
|
||||
MyOtherList(17) = 17
|
||||
MyOtherList(18) = 18
|
||||
MyOtherList(19) = 19
|
||||
MyOtherList(20) = 20
|
||||
Debug.Print "b) "; RangeExtraction(MyOtherList)
|
||||
End Sub
|
||||
Loading…
Add table
Add a link
Reference in a new issue