Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Range-expansion/00-META.yaml
Normal file
2
Task/Range-expansion/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Range_expansion
|
||||
15
Task/Range-expansion/00-TASK.txt
Normal file
15
Task/Range-expansion/00-TASK.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{{:Range extraction/Format}}
|
||||
|
||||
|
||||
;Task:
|
||||
Expand the range description:
|
||||
<big> -6,-3--1,3-5,7-11,14,15,17-20 </big>
|
||||
|
||||
<small>Note that the second element above,
|
||||
is the '''range from minus 3 to ''minus'' 1'''. </small>
|
||||
|
||||
|
||||
;Related task:
|
||||
* [[Range extraction]]
|
||||
<br><br>
|
||||
|
||||
11
Task/Range-expansion/11l/range-expansion.11l
Normal file
11
Task/Range-expansion/11l/range-expansion.11l
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
F rangeexpand(txt)
|
||||
[Int] lst
|
||||
L(r) txt.split(‘,’)
|
||||
I ‘-’ C r[1..]
|
||||
V rr = r[1..].split(‘-’, 2)
|
||||
lst [+]= Int(r[0]‘’rr[0]) .. Int(rr[1])
|
||||
E
|
||||
lst.append(Int(r))
|
||||
R lst
|
||||
|
||||
print(rangeexpand(‘-6,-3--1,3-5,7-11,14,15,17-20’))
|
||||
61
Task/Range-expansion/8th/range-expansion.8th
Normal file
61
Task/Range-expansion/8th/range-expansion.8th
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
\ Given a low and high limit, create an array containing the numbers in the
|
||||
\ range, inclusive:
|
||||
: n:gen-range \ low hi -- a
|
||||
\ make sure they are in order:
|
||||
2dup n:> if swap then
|
||||
\ fill the array with the values:
|
||||
[] ' a:push
|
||||
2swap loop ;
|
||||
|
||||
\ Take a string, either "X" or "X-Y", and correctly return either a number (if
|
||||
\ "X") or an array of numbers (if "X-Y"):
|
||||
: n:expand-one \ s -- n | a[n,..m]
|
||||
\ First see if we can parse a number. This works in the "X" case:
|
||||
dup >n null? if
|
||||
\ Failed >n because it's (possibly) "X-Y"
|
||||
drop
|
||||
\ not a valid number, might be a range
|
||||
\ We'll use a capturing regex to handle the different cases correctly:
|
||||
/(-?[0-9]+)-(-?[0-9]+)/ tuck r:match
|
||||
|
||||
\ If the regex matches three (the whole string, plus the two captured
|
||||
\ expressions) then it's a valid "X-Y":
|
||||
3 n:= if
|
||||
1 r:@ >n swap 2 r:@ >n nip
|
||||
\ generate the range:
|
||||
n:gen-range
|
||||
else
|
||||
\ The regex didn't match, so we got garbage. Therefore, return a 'null':
|
||||
drop null
|
||||
then
|
||||
else
|
||||
\ It was a "X", just drop the original string:
|
||||
nip
|
||||
then
|
||||
;
|
||||
|
||||
\ Take an array (possibly) containing other arrays, and flatten any contained
|
||||
\ arrays so the result is a simple array:
|
||||
: a:flatten \ a1 -- a2
|
||||
[] >r
|
||||
(
|
||||
nip
|
||||
array? if
|
||||
a:flatten r> swap a:+ >r
|
||||
else
|
||||
r> swap a:push >r
|
||||
then
|
||||
) a:each drop r> ;
|
||||
|
||||
\ Take a comma-delimited string of ranges, and expand it into an array of
|
||||
\ numbers:
|
||||
: n:range-expand \ str -- a
|
||||
"," s:/
|
||||
' n:expand-one a:map
|
||||
a:flatten ;
|
||||
|
||||
\ Process a list:
|
||||
"-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
n:range-expand
|
||||
\ print the expanded list:
|
||||
. cr bye
|
||||
169
Task/Range-expansion/ALGOL-68/range-expansion.alg
Normal file
169
Task/Range-expansion/ALGOL-68/range-expansion.alg
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
MODE YIELDINT = PROC(INT)VOID;
|
||||
|
||||
MODE RANGE = STRUCT(INT lwb, upb);
|
||||
MODE RANGEINT = UNION(RANGE, INT);
|
||||
|
||||
OP SIZEOF = ([]RANGEINT list)INT: (
|
||||
# determine the length of the output array #
|
||||
INT upb := LWB list - 1;
|
||||
FOR key FROM LWB list TO UPB list DO
|
||||
CASE list[key] IN
|
||||
(RANGE value): upb +:= upb OF value - lwb OF value + 1,
|
||||
(INT): upb +:= 1
|
||||
ESAC
|
||||
OD;
|
||||
upb
|
||||
);
|
||||
|
||||
PROC gen range expand = ([]RANGEINT list, YIELDINT yield)VOID:
|
||||
FOR key FROM LWB list TO UPB list DO
|
||||
CASE list[key] IN
|
||||
(RANGE range): FOR value FROM lwb OF range TO upb OF range DO yield(value) OD,
|
||||
(INT int): yield(int)
|
||||
ESAC
|
||||
OD;
|
||||
|
||||
PROC range expand = ([]RANGEINT list)[]INT: (
|
||||
[LWB list: LWB list + SIZEOF list - 1]INT out;
|
||||
INT upb := LWB out - 1;
|
||||
# FOR INT value IN # gen range expand(list, # ) DO #
|
||||
## (INT value)VOID:
|
||||
out[upb +:= 1] := value
|
||||
# OD #);
|
||||
out
|
||||
);
|
||||
|
||||
#
|
||||
test:(
|
||||
[]RANGEINT list = (-6, RANGE(-3, -1), RANGE(3, 5), RANGE(7, 11), 14, 15, RANGE(17, 20));
|
||||
print((range expand(list), new line))
|
||||
)
|
||||
#
|
||||
|
||||
|
||||
# converts string containing a comma-separated list of ranges and values to a []RANGEINT #
|
||||
OP TORANGE = ( STRING s )[]RANGEINT:
|
||||
BEGIN
|
||||
|
||||
# counts the number of elements - one more than the number of commas #
|
||||
# and so assumes there is always at least one element #
|
||||
PROC count elements = INT:
|
||||
BEGIN
|
||||
|
||||
INT elements := 1;
|
||||
|
||||
FOR pos FROM LWB s TO UPB s
|
||||
DO
|
||||
IF s[ pos ] = ","
|
||||
THEN
|
||||
elements +:= 1
|
||||
FI
|
||||
OD;
|
||||
|
||||
# RESULT #
|
||||
elements
|
||||
END; # count elements #
|
||||
|
||||
REF[]RANGEINT result = HEAP [ 1 : count elements ]RANGEINT;
|
||||
|
||||
# does the actual parsing - assumes the string is syntatically valid and doesn't check for errors #
|
||||
# - in particular, a string with no elements will cause problems, as will space characters in the string #
|
||||
PROC parse range string = []RANGEINT:
|
||||
BEGIN
|
||||
|
||||
INT element := 0;
|
||||
INT str pos := 1;
|
||||
|
||||
PROC next = VOID: str pos +:= 1;
|
||||
PROC curr char = CHAR: IF str pos > UPB s THEN "?" ELSE s[ str pos ] FI;
|
||||
PROC have minus = BOOL: curr char = "-";
|
||||
PROC have digit = BOOL: curr char >= "0" AND curr char <= "9";
|
||||
|
||||
|
||||
# parses a number out of the string #
|
||||
# the number must be a sequence of digits with an optional leading minus sign #
|
||||
PROC get number = INT:
|
||||
BEGIN
|
||||
|
||||
INT number := 0;
|
||||
|
||||
INT sign multiplier = IF have minus
|
||||
THEN
|
||||
# negaive number #
|
||||
# skip the sign #
|
||||
next;
|
||||
-1
|
||||
ELSE
|
||||
# positive number #
|
||||
1
|
||||
FI;
|
||||
|
||||
WHILE curr char >= "0" AND curr char <= "9"
|
||||
DO
|
||||
number *:= 10;
|
||||
number +:= ( ABS curr char - ABS "0" );
|
||||
next
|
||||
OD;
|
||||
|
||||
# RESULT #
|
||||
number * sign multiplier
|
||||
END; # get number #
|
||||
|
||||
|
||||
# main parsing #
|
||||
WHILE str pos <= UPB s
|
||||
DO
|
||||
CHAR c = curr char;
|
||||
|
||||
IF have minus OR have digit
|
||||
THEN
|
||||
# have the start of a number #
|
||||
INT from value = get number;
|
||||
element +:= 1;
|
||||
IF NOT have minus
|
||||
THEN
|
||||
# not a range #
|
||||
result[ element ] := from value
|
||||
ELSE
|
||||
# have a range #
|
||||
next;
|
||||
INT to value = get number;
|
||||
result[ element ] := RANGE( from value, to value )
|
||||
FI
|
||||
ELSE
|
||||
# should be a comma #
|
||||
next
|
||||
FI
|
||||
OD;
|
||||
|
||||
# RESULT #
|
||||
result
|
||||
END; # parse range string #
|
||||
|
||||
|
||||
# RESULT #
|
||||
parse range string
|
||||
END; # TORANGE #
|
||||
|
||||
|
||||
# converts a []INT to a comma separated string of the elements #
|
||||
OP TOSTRING = ( []INT values )STRING:
|
||||
BEGIN
|
||||
|
||||
STRING result := "";
|
||||
STRING separator := "";
|
||||
|
||||
FOR pos FROM LWB values TO UPB values
|
||||
DO
|
||||
result +:= ( separator + whole( values[ pos ], 0 ) );
|
||||
separator := ","
|
||||
OD;
|
||||
|
||||
# RESULT #
|
||||
result
|
||||
END; # TOSTRING #
|
||||
|
||||
|
||||
test:(
|
||||
print( ( TOSTRING range expand( TORANGE "-6,-3--1,3-5,7-11,14,15,17-20" ), newline ) )
|
||||
)
|
||||
9
Task/Range-expansion/APL/range-expansion.apl
Normal file
9
Task/Range-expansion/APL/range-expansion.apl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
range←{
|
||||
aplnum←{⍎('¯',⎕D)[('-',⎕D)⍳⍵]}
|
||||
∊{ 0::('Invalid range: ''',⍵,'''')⎕SIGNAL 11
|
||||
n←aplnum¨(~<\(⊢≠∨\)⍵∊⎕D)⊆⍵
|
||||
1=≢n:n
|
||||
s e←n
|
||||
(s+(⍳e-s-1))-1
|
||||
}¨(⍵≠',')⊆⍵
|
||||
}
|
||||
22
Task/Range-expansion/AWK/range-expansion.awk
Normal file
22
Task/Range-expansion/AWK/range-expansion.awk
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/awk -f
|
||||
BEGIN { FS=","; }
|
||||
|
||||
{ s="";
|
||||
for (i=1; i<=NF; i++) { expand($i); }
|
||||
print substr(s,2);
|
||||
}
|
||||
|
||||
function expand(a) {
|
||||
idx = match(a,/[0-9]-/);
|
||||
if (idx==0) {
|
||||
s = s","a;
|
||||
return;
|
||||
}
|
||||
|
||||
start= substr(a,1, idx)+0;
|
||||
stop = substr(a,idx+2)+0;
|
||||
for (m = start; m <= stop; m++) {
|
||||
s = s","m;
|
||||
}
|
||||
return;
|
||||
}
|
||||
72
Task/Range-expansion/Action-/range-expansion.action
Normal file
72
Task/Range-expansion/Action-/range-expansion.action
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
BYTE FUNC Find(CHAR ARRAY text CHAR c BYTE start)
|
||||
BYTE i
|
||||
|
||||
i=start
|
||||
WHILE i<=text(0)
|
||||
DO
|
||||
IF text(i)=c THEN
|
||||
RETURN (i)
|
||||
FI
|
||||
i==+1
|
||||
OD
|
||||
RETURN (0)
|
||||
|
||||
PROC ProcessItem(CHAR ARRAY text INT ARRAY res INT POINTER size)
|
||||
BYTE pos
|
||||
INT start,end,i
|
||||
CHAR ARRAY tmp(200)
|
||||
|
||||
pos=Find(text,'-,2)
|
||||
IF pos=0 THEN
|
||||
res(size^)=ValI(text)
|
||||
size^==+1
|
||||
ELSE
|
||||
SCopyS(tmp,text,1,pos-1)
|
||||
start=ValI(tmp)
|
||||
SCopyS(tmp,text,pos+1,text(0))
|
||||
end=ValI(tmp)
|
||||
FOR i=start TO end
|
||||
DO
|
||||
res(size^)=i
|
||||
size^==+1
|
||||
OD
|
||||
FI
|
||||
RETURN
|
||||
|
||||
PROC RangeExtraction(CHAR ARRAY text INT ARRAY res INT POINTER size)
|
||||
BYTE i,pos
|
||||
CHAR ARRAY tmp(200)
|
||||
|
||||
i=1 size^=0
|
||||
WHILE i<=text(0)
|
||||
DO
|
||||
pos=Find(text,',,i)
|
||||
IF pos=0 THEN
|
||||
SCopyS(tmp,text,i,text(0))
|
||||
i=text(0)+1
|
||||
ELSE
|
||||
SCopyS(tmp,text,i,pos-1)
|
||||
i=pos+1
|
||||
FI
|
||||
ProcessItem(tmp,res,size)
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC PrintArray(INT ARRAY a INT size)
|
||||
INT i
|
||||
|
||||
Put('[)
|
||||
FOR i=0 TO size-1
|
||||
DO
|
||||
IF i>0 THEN Put(' ) FI
|
||||
PrintI(a(i))
|
||||
OD
|
||||
Put(']) PutE()
|
||||
RETURN
|
||||
|
||||
PROC Main()
|
||||
INT ARRAY res(100)
|
||||
INT size
|
||||
RangeExtraction("-6,-3--1,3-5,7-11,14,15,17-20",res,@size)
|
||||
PrintArray(res,size)
|
||||
RETURN
|
||||
66
Task/Range-expansion/Ada/range-expansion.ada
Normal file
66
Task/Range-expansion/Ada/range-expansion.ada
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
procedure Test_Range_Expansion is
|
||||
type Sequence is array (Positive range <>) of Integer;
|
||||
function Expand (Text : String) return Sequence is
|
||||
To : Integer := Text'First;
|
||||
Count : Natural := 0;
|
||||
Low : Integer;
|
||||
function Get return Integer is
|
||||
From : Integer := To;
|
||||
begin
|
||||
if Text (To) = '-' then
|
||||
To := To + 1;
|
||||
end if;
|
||||
while To <= Text'Last loop
|
||||
case Text (To) is
|
||||
when ',' | '-' => exit;
|
||||
when others => To := To + 1;
|
||||
end case;
|
||||
end loop;
|
||||
return Integer'Value (Text (From..To - 1));
|
||||
end Get;
|
||||
begin
|
||||
while To <= Text'Last loop -- Counting items of the list
|
||||
Low := Get;
|
||||
if To > Text'Last or else Text (To) = ',' then
|
||||
Count := Count + 1;
|
||||
else
|
||||
To := To + 1;
|
||||
Count := Count + Get - Low + 1;
|
||||
end if;
|
||||
To := To + 1;
|
||||
end loop;
|
||||
return Result : Sequence (1..Count) do
|
||||
Count := 0;
|
||||
To := Text'First;
|
||||
while To <= Text'Last loop -- Filling the list
|
||||
Low := Get;
|
||||
if To > Text'Last or else Text (To) = ',' then
|
||||
Count := Count + 1;
|
||||
Result (Count) := Low;
|
||||
else
|
||||
To := To + 1;
|
||||
for Item in Low..Get loop
|
||||
Count := Count + 1;
|
||||
Result (Count) := Item;
|
||||
end loop;
|
||||
end if;
|
||||
To := To + 1;
|
||||
end loop;
|
||||
end return;
|
||||
end Expand;
|
||||
procedure Put (S : Sequence) is
|
||||
First : Boolean := True;
|
||||
begin
|
||||
for I in S'Range loop
|
||||
if First then
|
||||
First := False;
|
||||
else
|
||||
Put (',');
|
||||
end if;
|
||||
Put (Integer'Image (S (I)));
|
||||
end loop;
|
||||
end Put;
|
||||
begin
|
||||
Put (Expand ("-6,-3--1,3-5,7-11,14,15,17-20"));
|
||||
end Test_Range_Expansion;
|
||||
20
Task/Range-expansion/Aime/range-expansion-1.aime
Normal file
20
Task/Range-expansion/Aime/range-expansion-1.aime
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
list l;
|
||||
|
||||
file().b_affix("-6,-3--1,3-5,7-11,14,15,17-20").news(l, 0, 0, ",");
|
||||
for (, text s in l) {
|
||||
integer a, b, p;
|
||||
|
||||
p = b_frame(s, '-');
|
||||
if (p < 1) {
|
||||
o_(s, ",");
|
||||
} else {
|
||||
p -= s[p - 1] == '-' ? 1 : 0;
|
||||
a = s.cut(0, p).atoi;
|
||||
b = s.erase(0, p).atoi;
|
||||
do {
|
||||
o_(a, ",");
|
||||
} while ((a += 1) <= b);
|
||||
}
|
||||
}
|
||||
|
||||
o_("\n");
|
||||
14
Task/Range-expansion/Aime/range-expansion-2.aime
Normal file
14
Task/Range-expansion/Aime/range-expansion-2.aime
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
integer p;
|
||||
list l;
|
||||
|
||||
file().b_affix("-6,-3--1,3-5,7-11,14,15,17-20").news(l, 0, 0, ",");
|
||||
for (, text s in l) {
|
||||
if ((p = b_frame(s, '-')) < 1) {
|
||||
o_(s, ",");
|
||||
} else {
|
||||
p -= s[p - 1] == '-' ? 1 : 0;
|
||||
call_s(o_, 0, s.cut(0, p).atoi, s.erase(0, p).atoi + 1, 1, ",");
|
||||
}
|
||||
}
|
||||
|
||||
o_("\n");
|
||||
156
Task/Range-expansion/AppleScript/range-expansion-1.applescript
Normal file
156
Task/Range-expansion/AppleScript/range-expansion-1.applescript
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
-- Each comma-delimited string is mapped to a list of integers,
|
||||
-- and these integer lists are concatenated together into a single list
|
||||
|
||||
|
||||
---------------------- RANGE EXPANSION ---------------------
|
||||
|
||||
-- expansion :: String -> [Int]
|
||||
on expansion(strExpr)
|
||||
-- The string (between commas) is split on hyphens,
|
||||
-- and this segmentation is rewritten to ranges or minus signs
|
||||
-- and evaluated to lists of integer values
|
||||
|
||||
-- signedRange :: String -> [Int]
|
||||
script signedRange
|
||||
-- After the first character, numbers preceded by an
|
||||
-- empty string (resulting from splitting on hyphens)
|
||||
-- and interpreted as negative
|
||||
|
||||
-- signedIntegerAppended:: [Int] -> String -> Int -> [Int] -> [Int]
|
||||
on signedIntegerAppended(acc, strNum, iPosn, xs)
|
||||
if strNum ≠ "" then
|
||||
if iPosn > 1 then
|
||||
set strSign to |λ|(0 < length of (item (iPosn - 1) of xs)) ¬
|
||||
of bool("", "-")
|
||||
else
|
||||
set strSign to "+"
|
||||
end if
|
||||
|
||||
acc & ((strSign & strNum) as integer)
|
||||
else
|
||||
acc
|
||||
end if
|
||||
end signedIntegerAppended
|
||||
|
||||
on |λ|(strHyphenated)
|
||||
tupleRange(foldl(signedIntegerAppended, {}, ¬
|
||||
splitOn("-", strHyphenated)))
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
concatMap(signedRange, splitOn(",", strExpr))
|
||||
end expansion
|
||||
|
||||
|
||||
---------------------------- TEST --------------------------
|
||||
on run
|
||||
|
||||
expansion("-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
|
||||
--> {-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20}
|
||||
end run
|
||||
|
||||
|
||||
--------------------- GENERIC FUNCTIONS --------------------
|
||||
|
||||
|
||||
-- bool :: a -> a -> Bool -> a
|
||||
on bool(tf, ff)
|
||||
-- The evaluation of either tf or ff,
|
||||
-- depending on a boolean value.
|
||||
script
|
||||
on |λ|(bln)
|
||||
if bln then
|
||||
set e to tf
|
||||
else
|
||||
set e to ff
|
||||
end if
|
||||
set c to class of e
|
||||
if {script, handler} contains c then
|
||||
|λ|() of mReturn(e)
|
||||
else
|
||||
e
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
end bool
|
||||
|
||||
-- concatMap :: (a -> [b]) -> [a] -> [b]
|
||||
on concatMap(f, xs)
|
||||
script append
|
||||
on |λ|(a, b)
|
||||
a & b
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
foldl(append, {}, map(f, xs))
|
||||
end concatMap
|
||||
|
||||
-- enumFromTo :: Int -> Int -> [Int]
|
||||
on enumFromTo(m, n)
|
||||
if n < m then
|
||||
set d to -1
|
||||
else
|
||||
set d to 1
|
||||
end if
|
||||
set lst to {}
|
||||
repeat with i from m to n by d
|
||||
set end of lst to i
|
||||
end repeat
|
||||
return lst
|
||||
end enumFromTo
|
||||
|
||||
-- foldl :: (a -> b -> a) -> a -> [b] -> a
|
||||
on foldl(f, startValue, xs)
|
||||
tell mReturn(f)
|
||||
set v to startValue
|
||||
set lng to length of xs
|
||||
repeat with i from 1 to lng
|
||||
set v to |λ|(v, item i of xs, i, xs)
|
||||
end repeat
|
||||
return v
|
||||
end tell
|
||||
end foldl
|
||||
|
||||
-- map :: (a -> b) -> [a] -> [b]
|
||||
on map(f, xs)
|
||||
tell mReturn(f)
|
||||
set lng to length of xs
|
||||
set lst to {}
|
||||
repeat with i from 1 to lng
|
||||
set end of lst to |λ|(item i of xs, i, xs)
|
||||
end repeat
|
||||
return lst
|
||||
end tell
|
||||
end map
|
||||
|
||||
-- Lift 2nd class handler function into 1st class script wrapper
|
||||
-- mReturn :: Handler -> Script
|
||||
on mReturn(f)
|
||||
if class of f is script then
|
||||
f
|
||||
else
|
||||
script
|
||||
property |λ| : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
|
||||
-- splitOn :: Text -> Text -> [Text]
|
||||
on splitOn(strDelim, strMain)
|
||||
set {dlm, my text item delimiters} to {my text item delimiters, strDelim}
|
||||
set xs to text items of strMain
|
||||
set my text item delimiters to dlm
|
||||
return xs
|
||||
end splitOn
|
||||
|
||||
-- range :: (Int, Int) -> [Int]
|
||||
on tupleRange(tuple)
|
||||
if tuple = {} then
|
||||
{}
|
||||
else if length of tuple > 1 then
|
||||
enumFromTo(item 1 of tuple, item 2 of tuple)
|
||||
else
|
||||
item 1 of tuple
|
||||
end if
|
||||
end tupleRange
|
||||
|
|
@ -0,0 +1 @@
|
|||
{-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
on rangeExpansion(rangeExpression)
|
||||
-- Split the expression at the commas, if any.
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to ","
|
||||
set theRanges to rangeExpression's text items
|
||||
|
||||
set integerList to {}
|
||||
set AppleScript's text item delimiters to "-"
|
||||
repeat with thisRange in theRanges
|
||||
-- Split each range or integer text at its dash(es), if any.
|
||||
set rangeParts to thisRange's text items
|
||||
-- A minus before the first integer will make leading text item "".
|
||||
-- If this happens, insert the negative first value at the beginning of the parts list.
|
||||
-- (AppleScript automatically coerces numeric text to number when the context demands.)
|
||||
if (rangeParts begins with "") then set beginning of rangeParts to -(item 2 of rangeParts)
|
||||
-- A minus before the second (or only) integer will make the penultimate text item "".
|
||||
-- In this case, insert the negative last value at the end of the parts list.
|
||||
if (((count rangeParts) > 1) and (item -2 of rangeParts is "")) then set end of rangeParts to -(end of rangeParts)
|
||||
-- Append all the integers implied by the range to the integer list.
|
||||
repeat with i from (beginning of rangeParts) to (end of rangeParts)
|
||||
set end of integerList to i
|
||||
end repeat
|
||||
end repeat
|
||||
set AppleScript's text item delimiters to astid
|
||||
|
||||
return integerList
|
||||
end rangeExpansion
|
||||
|
||||
-- Demo code:
|
||||
set rangeExpression to "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
return rangeExpansion(rangeExpression)
|
||||
|
|
@ -0,0 +1 @@
|
|||
{-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20}
|
||||
9
Task/Range-expansion/Arturo/range-expansion.arturo
Normal file
9
Task/Range-expansion/Arturo/range-expansion.arturo
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
expandRange: function [rng][
|
||||
flatten @ to :block
|
||||
join.with:" " map split.by:"," rng 'x ->
|
||||
replace replace replace x
|
||||
{/^\-(\d+)/} "(neg $1)" {/\-\-(\d+)/}
|
||||
"-(neg $1)" "-" ".."
|
||||
]
|
||||
|
||||
print expandRange {-6,-3--1,3-5,7-11,14,15,17-20}
|
||||
9
Task/Range-expansion/AutoHotkey/range-expansion.ahk
Normal file
9
Task/Range-expansion/AutoHotkey/range-expansion.ahk
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
msgbox % expand("-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
|
||||
expand( range ) {
|
||||
p := 0
|
||||
while p := RegExMatch(range, "\s*(-?\d++)(?:\s*-\s*(-?\d++))?", f, p+1+StrLen(f))
|
||||
loop % (f2 ? f2-f1 : 0) + 1
|
||||
ret .= "," (A_Index-1) + f1
|
||||
return SubStr(ret, 2)
|
||||
}
|
||||
23
Task/Range-expansion/BBC-BASIC/range-expansion.basic
Normal file
23
Task/Range-expansion/BBC-BASIC/range-expansion.basic
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
PRINT FNrangeexpand("-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
END
|
||||
|
||||
DEF FNrangeexpand(r$)
|
||||
LOCAL i%, j%, k%, t$
|
||||
REPEAT
|
||||
i% = INSTR(r$, "-", i%+1)
|
||||
IF i% THEN
|
||||
j% = i%
|
||||
WHILE MID$(r$,j%-1,1)<>"," AND j%<>1
|
||||
j% -= 1
|
||||
ENDWHILE
|
||||
IF i%>j% IF MID$(r$,j%,i%-j%)<>STRING$(i%-j%," ") THEN
|
||||
t$ = ""
|
||||
FOR k% = VALMID$(r$,j%) TO VALMID$(r$,i%+1)-1
|
||||
t$ += STR$(k%) + ","
|
||||
NEXT
|
||||
r$ = LEFT$(r$,j%-1) + t$ + MID$(r$,i%+1)
|
||||
i% = j% + LEN(t$) + 2
|
||||
ENDIF
|
||||
ENDIF
|
||||
UNTIL i% = 0
|
||||
= r$
|
||||
15
Task/Range-expansion/Bracmat/range-expansion.bracmat
Normal file
15
Task/Range-expansion/Bracmat/range-expansion.bracmat
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
( expandRanges
|
||||
= a b L
|
||||
. @( !arg
|
||||
: (#(?a:?b)|#?a "-" #?b)
|
||||
(:?L|"," [%(expandRanges$!sjt:?L))
|
||||
)
|
||||
& whl
|
||||
' ( (!L:&!b|(!b,!L))
|
||||
: ?L
|
||||
& -1+!b:~<!a:?b
|
||||
)
|
||||
& !L
|
||||
|
|
||||
)
|
||||
& out$(str$(expandRanges$"-6,-3--1,3-5,7-11,14,15,17-20"))
|
||||
74
Task/Range-expansion/C++/range-expansion.cpp
Normal file
74
Task/Range-expansion/C++/range-expansion.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include <climits>
|
||||
#include <deque>
|
||||
|
||||
// parse a list of numbers with ranges
|
||||
//
|
||||
// arguments:
|
||||
// is: the stream to parse
|
||||
// out: the output iterator the parsed list is written to.
|
||||
//
|
||||
// returns true if the parse was successful. false otherwise
|
||||
template<typename OutIter>
|
||||
bool parse_number_list_with_ranges(std::istream& is, OutIter out)
|
||||
{
|
||||
int number;
|
||||
// the list always has to start with a number
|
||||
while (is >> number)
|
||||
{
|
||||
*out++ = number;
|
||||
|
||||
char c;
|
||||
if (is >> c)
|
||||
switch(c)
|
||||
{
|
||||
case ',':
|
||||
continue;
|
||||
case '-':
|
||||
{
|
||||
int number2;
|
||||
if (is >> number2)
|
||||
{
|
||||
if (number2 < number)
|
||||
return false;
|
||||
while (number < number2)
|
||||
*out++ = ++number;
|
||||
char c2;
|
||||
if (is >> c2)
|
||||
if (c2 == ',')
|
||||
continue;
|
||||
else
|
||||
return false;
|
||||
else
|
||||
return is.eof();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return is.eof();
|
||||
}
|
||||
else
|
||||
return is.eof();
|
||||
}
|
||||
// if we get here, something went wrong (otherwise we would have
|
||||
// returned from inside the loop)
|
||||
return false;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::istringstream example("-6,-3--1,3-5,7-11,14,15,17-20");
|
||||
std::deque<int> v;
|
||||
bool success = parse_number_list_with_ranges(example, std::back_inserter(v));
|
||||
if (success)
|
||||
{
|
||||
std::copy(v.begin(), v.end()-1,
|
||||
std::ostream_iterator<int>(std::cout, ","));
|
||||
std::cout << v.back() << "\n";
|
||||
}
|
||||
else
|
||||
std::cout << "an error occured.";
|
||||
}
|
||||
30
Task/Range-expansion/C-sharp/range-expansion-1.cs
Normal file
30
Task/Range-expansion/C-sharp/range-expansion-1.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var rangeString = "-6,-3--1,3-5,7-11,14,15,17-20";
|
||||
var matches = Regex.Matches(rangeString, @"(?<f>-?\d+)-(?<s>-?\d+)|(-?\d+)");
|
||||
var values = new List<string>();
|
||||
|
||||
foreach (var m in matches.OfType<Match>())
|
||||
{
|
||||
if (m.Groups[1].Success)
|
||||
{
|
||||
values.Add(m.Value);
|
||||
continue;
|
||||
}
|
||||
|
||||
var start = Convert.ToInt32(m.Groups["f"].Value);
|
||||
var end = Convert.ToInt32(m.Groups["s"].Value) + 1;
|
||||
|
||||
values.AddRange(Enumerable.Range(start, end - start).Select(v => v.ToString()));
|
||||
}
|
||||
|
||||
Console.WriteLine(string.Join(", ", values));
|
||||
}
|
||||
}
|
||||
31
Task/Range-expansion/C-sharp/range-expansion-2.cs
Normal file
31
Task/Range-expansion/C-sharp/range-expansion-2.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace RangeExpansion {
|
||||
internal static class StringExtensions {
|
||||
internal static IEnumerable<int> ExpandRange(this string s) {
|
||||
return s.Split(',')
|
||||
.Select(rstr => {
|
||||
int start;
|
||||
if (int.TryParse(rstr, out start))
|
||||
return new {Start = start, End = start};
|
||||
var istr = new string(("+-".Any(_ => rstr[0] == _)
|
||||
? rstr.Take(1).Concat(rstr.Skip(1).TakeWhile(char.IsDigit))
|
||||
: rstr.TakeWhile(char.IsDigit)
|
||||
).ToArray());
|
||||
rstr = rstr.Substring(istr.Length + 1, (rstr.Length - istr.Length) - 1);
|
||||
return new {Start = int.Parse(istr), End = int.Parse(rstr)};
|
||||
}).SelectMany(_ => Enumerable.Range(_.Start, _.End - _.Start + 1));
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Program {
|
||||
private static void Main() {
|
||||
const string RANGE_STRING = "-6,-3--1,3-5,7-11,14,15,17-20";
|
||||
var values = RANGE_STRING.ExpandRange().ToList();
|
||||
var vstr = string.Join(", ", values.Select(_ => _.ToString()));
|
||||
Console.WriteLine(vstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Task/Range-expansion/C/range-expansion.c
Normal file
78
Task/Range-expansion/C/range-expansion.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* BNFesque
|
||||
rangelist := (range | number) [',' rangelist]
|
||||
range := number '-' number */
|
||||
|
||||
int get_list(const char *, char **);
|
||||
int get_rnge(const char *, char **);
|
||||
|
||||
/* parser only parses; what to do with parsed items is up to
|
||||
* the add_number and and_range functions */
|
||||
void add_number(int x);
|
||||
int add_range(int x, int y);
|
||||
|
||||
#define skip_space while(isspace(*s)) s++
|
||||
#define get_number(x, s, e) (x = strtol(s, e, 10), *e != s)
|
||||
int get_list(const char *s, char **e)
|
||||
{
|
||||
int x;
|
||||
while (1) {
|
||||
skip_space;
|
||||
if (!get_rnge(s, e) && !get_number(x, s, e)) break;
|
||||
s = *e;
|
||||
|
||||
skip_space;
|
||||
if ((*s) == '\0') { putchar('\n'); return 1; }
|
||||
if ((*s) == ',') { s++; continue; }
|
||||
break;
|
||||
}
|
||||
*(const char **)e = s;
|
||||
printf("\nSyntax error at %s\n", s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_rnge(const char *s, char **e)
|
||||
{
|
||||
int x, y;
|
||||
char *ee;
|
||||
if (!get_number(x, s, &ee)) return 0;
|
||||
s = ee;
|
||||
|
||||
skip_space;
|
||||
if (*s != '-') {
|
||||
*(const char **)e = s;
|
||||
return 0;
|
||||
}
|
||||
s++;
|
||||
if(!get_number(y, s, e)) return 0;
|
||||
return add_range(x, y);
|
||||
}
|
||||
|
||||
void add_number(int x)
|
||||
{
|
||||
printf("%d ", x);
|
||||
}
|
||||
|
||||
int add_range(int x, int y)
|
||||
{
|
||||
if (y <= x) return 0;
|
||||
while (x <= y) printf("%d ", x++);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char *end;
|
||||
|
||||
/* this is correct */
|
||||
if (get_list("-6,-3--1,3-5,7-11,14,15,17-20", &end)) puts("Ok");
|
||||
|
||||
/* this is not. note the subtle error: "-6 -3" is parsed
|
||||
* as range(-6, 3), so synax error comes after that */
|
||||
get_list("-6 -3--1,3-5,7-11,14,15,17-20", &end);
|
||||
|
||||
return 0;
|
||||
}
|
||||
93
Task/Range-expansion/COBOL/range-expansion.cobol
Normal file
93
Task/Range-expansion/COBOL/range-expansion.cobol
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
>>SOURCE FREE
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. expand-range.
|
||||
|
||||
DATA DIVISION.
|
||||
WORKING-STORAGE SECTION.
|
||||
01 comma-pos PIC 99 COMP VALUE 1.
|
||||
01 dash-pos PIC 99 COMP.
|
||||
01 end-num PIC S9(3).
|
||||
01 Max-Part-Len CONSTANT 10.
|
||||
01 num PIC S9(3).
|
||||
01 edited-num PIC -(3)9.
|
||||
01 part PIC X(10).
|
||||
|
||||
01 part-flag PIC X.
|
||||
88 last-part VALUE "Y".
|
||||
|
||||
01 range-str PIC X(80).
|
||||
01 Range-Str-Len CONSTANT 80.
|
||||
01 start-pos PIC 99 COMP.
|
||||
01 start-num PIC S9(3).
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
ACCEPT range-str
|
||||
|
||||
PERFORM WITH TEST AFTER UNTIL last-part
|
||||
UNSTRING range-str DELIMITED BY "," INTO part WITH POINTER comma-pos
|
||||
PERFORM check-if-last
|
||||
|
||||
PERFORM find-range-dash
|
||||
|
||||
IF dash-pos > Max-Part-Len
|
||||
PERFORM display-num
|
||||
ELSE
|
||||
PERFORM display-range
|
||||
END-IF
|
||||
END-PERFORM
|
||||
|
||||
DISPLAY SPACES
|
||||
|
||||
GOBACK
|
||||
.
|
||||
check-if-last SECTION.
|
||||
IF comma-pos > Range-Str-Len
|
||||
SET last-part TO TRUE
|
||||
END-IF
|
||||
.
|
||||
find-range-dash SECTION.
|
||||
IF part (1:1) <> "-"
|
||||
MOVE 1 TO start-pos
|
||||
ELSE
|
||||
MOVE 2 TO start-pos
|
||||
END-IF
|
||||
|
||||
MOVE 1 TO dash-pos
|
||||
INSPECT part (start-pos:) TALLYING dash-pos FOR CHARACTERS BEFORE "-"
|
||||
COMPUTE dash-pos = dash-pos + start-pos - 1
|
||||
.
|
||||
display-num SECTION.
|
||||
MOVE part TO edited-num
|
||||
CALL "display-edited-num" USING CONTENT part-flag, edited-num
|
||||
.
|
||||
display-range SECTION.
|
||||
MOVE part (1:dash-pos - 1) TO start-num
|
||||
MOVE part (dash-pos + 1:) TO end-num
|
||||
|
||||
PERFORM VARYING num FROM start-num BY 1 UNTIL num = end-num
|
||||
MOVE num TO edited-num
|
||||
CALL "display-edited-num" USING CONTENT "N", edited-num
|
||||
END-PERFORM
|
||||
|
||||
MOVE end-num TO edited-num
|
||||
CALL "display-edited-num" USING CONTENT part-flag, edited-num
|
||||
.
|
||||
END PROGRAM expand-range.
|
||||
|
||||
|
||||
IDENTIFICATION DIVISION.
|
||||
PROGRAM-ID. display-edited-num.
|
||||
|
||||
DATA DIVISION.
|
||||
LINKAGE SECTION.
|
||||
01 hide-comma-flag PIC X.
|
||||
88 hide-comma VALUE "Y".
|
||||
01 edited-num PIC -(3)9.
|
||||
|
||||
PROCEDURE DIVISION USING hide-comma-flag, edited-num.
|
||||
DISPLAY FUNCTION TRIM(edited-num) NO ADVANCING
|
||||
IF NOT hide-comma
|
||||
DISPLAY ", " NO ADVANCING
|
||||
END-IF
|
||||
.
|
||||
END PROGRAM display-edited-num.
|
||||
24
Task/Range-expansion/Clojure/range-expansion.clj
Normal file
24
Task/Range-expansion/Clojure/range-expansion.clj
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
(defn split [s sep]
|
||||
(defn skipFirst [[x & xs :as s]]
|
||||
(cond (empty? s) [nil nil]
|
||||
(= x sep) [x xs]
|
||||
true [nil s]))
|
||||
(loop [lst '(), s s]
|
||||
(if (empty? s) (reverse lst)
|
||||
(let [[hd trunc] (skipFirst s)
|
||||
[word news] (split-with #(not= % sep) trunc)
|
||||
cWord (cons hd word)]
|
||||
(recur (cons (apply str cWord) lst)
|
||||
(apply str (rest news)))))))
|
||||
|
||||
(defn parseRange [[x & xs :as s]]
|
||||
(if (some #(= % \-) xs)
|
||||
(let [[r0 r1] (split s \-)]
|
||||
(range (read-string r0) (inc (read-string r1))))
|
||||
(list (read-string (str s))))))
|
||||
|
||||
(defn rangeexpand [s]
|
||||
(flatten (map parseRange (split s \,))))
|
||||
|
||||
> (rangeexpand "-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
(-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20)
|
||||
23
Task/Range-expansion/Common-Lisp/range-expansion.lisp
Normal file
23
Task/Range-expansion/Common-Lisp/range-expansion.lisp
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
(defun expand-ranges (string)
|
||||
(loop
|
||||
with prevnum = nil
|
||||
for idx = 0 then (1+ nextidx)
|
||||
for (number nextidx) = (multiple-value-list
|
||||
(parse-integer string
|
||||
:start idx :junk-allowed t))
|
||||
append (cond
|
||||
(prevnum
|
||||
(prog1
|
||||
(loop for i from prevnum to number
|
||||
collect i)
|
||||
(setf prevnum nil)))
|
||||
((and (< nextidx (length string))
|
||||
(char= (aref string nextidx) #\-))
|
||||
(setf prevnum number)
|
||||
nil)
|
||||
(t
|
||||
(list number)))
|
||||
while (< nextidx (length string))))
|
||||
|
||||
CL-USER> (expand-ranges "-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
(-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20)
|
||||
94
Task/Range-expansion/Cowgol/range-expansion.cowgol
Normal file
94
Task/Range-expansion/Cowgol/range-expansion.cowgol
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
include "cowgol.coh";
|
||||
|
||||
# Callback interface
|
||||
interface RangeCb(n: int32);
|
||||
|
||||
# This will call `cb' for each number in the range, in ascending order.
|
||||
# It will return NULL on success, or the location of an error if
|
||||
# there is one.
|
||||
sub Expand(ranges: [uint8], cb: RangeCb): (err: [uint8]) is
|
||||
err := 0 as [uint8];
|
||||
loop
|
||||
# Grab first number
|
||||
var n1: int32;
|
||||
var next: [uint8];
|
||||
(n1, next) := AToI(ranges);
|
||||
|
||||
if next == ranges then
|
||||
# No number here!
|
||||
err := ranges;
|
||||
break;
|
||||
elseif [next] == ',' or [next] == 0 then
|
||||
# Only one number, not a range
|
||||
cb(n1);
|
||||
elseif [next] != '-' then
|
||||
# No dash!
|
||||
err := ranges;
|
||||
break;
|
||||
else
|
||||
# Grab second number
|
||||
ranges := @next next;
|
||||
var n2: int32;
|
||||
(n2, next) := AToI(ranges);
|
||||
if next == ranges or n1 >= n2 then
|
||||
# No second number, or first not before second
|
||||
err := ranges;
|
||||
break;
|
||||
end if;
|
||||
|
||||
# We need all numbers from n1 to n2 inclusive
|
||||
while n1 <= n2 loop
|
||||
cb(n1);
|
||||
n1 := n1 + 1;
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
# stop if end reached
|
||||
if [next] == 0 then break;
|
||||
elseif [next] != ',' then
|
||||
err := ranges;
|
||||
break;
|
||||
end if;
|
||||
ranges := @next next;
|
||||
end loop;
|
||||
end sub;
|
||||
|
||||
# This function will use `Expand' above to expand a comma-separated
|
||||
# range list, and reformat it as a comma-separated list of integers.
|
||||
sub ExpandFmt(ranges: [uint8], buf: [uint8]): (err: [uint8]) is
|
||||
# Format and add number to buffer
|
||||
sub AddNum implements RangeCb is
|
||||
buf := IToA(n, 10, buf);
|
||||
[buf] := ',';
|
||||
buf := @next buf;
|
||||
end sub;
|
||||
|
||||
# Expand range, adding numbers to buffer
|
||||
err := Expand(ranges, AddNum);
|
||||
[@prev buf] := 0;
|
||||
end sub;
|
||||
|
||||
# Expand and print, and/or give error
|
||||
sub PrintExpansion(ranges: [uint8]) is
|
||||
var buf: uint8[256];
|
||||
var err := ExpandFmt(ranges, &buf[0]);
|
||||
print(ranges);
|
||||
print_nl();
|
||||
print(" >> ");
|
||||
if err == 0 as [uint8] then
|
||||
# everything is OK
|
||||
print(&buf[0]);
|
||||
else
|
||||
# error
|
||||
print("error at: ");
|
||||
print(err);
|
||||
end if;
|
||||
print_nl();
|
||||
end sub;
|
||||
|
||||
# Try it on the given input
|
||||
PrintExpansion("-6,-3--1,3-5,7-11,14,15,17-20");
|
||||
|
||||
# Try it on a couple of wrong ones
|
||||
PrintExpansion("-6-3--1,3-5,7-11,14,15,17-20"); # misformatted range
|
||||
PrintExpansion("-6,-3--1,5-3,7-11,14,15,17-20"); # numbers not in order
|
||||
12
Task/Range-expansion/Crystal/range-expansion.crystal
Normal file
12
Task/Range-expansion/Crystal/range-expansion.crystal
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
def range_expand(range)
|
||||
range.split(',').flat_map do |part|
|
||||
match = /^(-?\d+)-(-?\d+)$/.match(part)
|
||||
if match
|
||||
(match[1].to_i .. match[2].to_i).to_a
|
||||
else
|
||||
part.to_i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
puts range_expand("-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
8
Task/Range-expansion/D/range-expansion.d
Normal file
8
Task/Range-expansion/D/range-expansion.d
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import std.stdio, std.regex, std.conv, std.range, std.algorithm;
|
||||
|
||||
enum rangeEx = (string s) /*pure*/ => s.matchAll(`(-?\d+)-?(-?\d+)?,?`)
|
||||
.map!q{ a[1].to!int.iota(a[1 + !a[2].empty].to!int + 1) }.join;
|
||||
|
||||
void main() {
|
||||
"-6,-3--1,3-5,7-11,14,15,17-20".rangeEx.writeln;
|
||||
}
|
||||
15
Task/Range-expansion/DWScript/range-expansion.dw
Normal file
15
Task/Range-expansion/DWScript/range-expansion.dw
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
function ExpandRanges(ranges : String) : array of Integer;
|
||||
begin
|
||||
for var range in ranges.Split(',') do begin
|
||||
var separator = range.IndexOf('-', 2);
|
||||
if separator > 0 then begin
|
||||
for var i := range.Left(separator-1).ToInteger to range.Copy(separator+1).ToInteger do
|
||||
Result.Add(i);
|
||||
end else begin
|
||||
Result.Add(range.ToInteger)
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var expanded := ExpandRanges('-6,-3--1,3-5,7-11,14,15,17-20');
|
||||
PrintLn(JSON.Stringify(expanded));
|
||||
70
Task/Range-expansion/Delphi/range-expansion.delphi
Normal file
70
Task/Range-expansion/Delphi/range-expansion.delphi
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
program Range_expansion;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
uses
|
||||
System.SysUtils;
|
||||
|
||||
const
|
||||
input = '-6,-3--1,3-5,7-11,14,15,17-20';
|
||||
|
||||
var
|
||||
r: TArray<Integer>;
|
||||
last, i, n: Integer;
|
||||
|
||||
begin
|
||||
for var part in input.Split([',']) do
|
||||
begin
|
||||
i := part.Substring(1).IndexOf('-');
|
||||
if i = -1 then
|
||||
begin
|
||||
if not TryStrToInt(part, n) then
|
||||
raise Exception.Create('Error: value invalid ' + part);
|
||||
if Length(r) > 0 then
|
||||
if last = n then
|
||||
begin
|
||||
raise Exception.Create('Error: Duplicate value:' + n.ToString);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if last > n then
|
||||
raise Exception.CreateFmt('Error: values not ordered: %s > %s', [last, n]);
|
||||
end;
|
||||
SetLength(r, Length(r) + 1);
|
||||
r[High(r)] := n;
|
||||
last := n;
|
||||
end
|
||||
else
|
||||
begin
|
||||
var n1 := 0;
|
||||
var n2 := 0;
|
||||
if not TryStrToInt(part.Substring(0, i + 1), n1) then
|
||||
raise Exception.Create('Error: value invalid ' + part);
|
||||
if not TryStrToInt(part.Substring(i + 2), n2) then
|
||||
raise Exception.Create('Error: value invalid ' + part);
|
||||
if n2 < n1 + 2 then
|
||||
raise Exception.Create('Error: Invalid range' + part);
|
||||
if Length(r) > 0 then
|
||||
begin
|
||||
if last = n1 then
|
||||
raise Exception.Create('Error: Duplicate value: ' + n1.ToString);
|
||||
if last > n1 then
|
||||
raise Exception.CreateFmt('Error: Values not ordened: %d > %d', [last, n1]);
|
||||
end;
|
||||
|
||||
for i := n1 to n2 do
|
||||
begin
|
||||
SetLength(r, Length(r) + 1);
|
||||
r[High(r)] := i;
|
||||
end;
|
||||
|
||||
last := n2;
|
||||
end;
|
||||
end;
|
||||
write('expanded: ');
|
||||
for var rr in r do
|
||||
begin
|
||||
write(rr, ',');
|
||||
end;
|
||||
readln;
|
||||
end.
|
||||
36
Task/Range-expansion/Dyalect/range-expansion.dyalect
Normal file
36
Task/Range-expansion/Dyalect/range-expansion.dyalect
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
func main() {
|
||||
let input = "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
print("range: \(input)")
|
||||
var r = []
|
||||
var last = 0
|
||||
for part in input.Split(',') {
|
||||
var i = part[1..].IndexOf('-')
|
||||
if i == -1 {
|
||||
var n = Integer(part)
|
||||
if r.Length() > 0 {
|
||||
return print("duplicate value: \(n)") when last == n
|
||||
return print("values not ordered: \(last) > \(n)") when last > n
|
||||
}
|
||||
r.Add(n)
|
||||
last = n
|
||||
} else {
|
||||
var n1 = Integer(part[..i])
|
||||
var n2 = Integer(part[(i + 2)..])
|
||||
return print("invalid range: \(part)") when n2 < n1 + 2
|
||||
|
||||
if r.Length() > 0 {
|
||||
return print("duplicate value: \(n1)") when last == n1
|
||||
return print("values not ordered: \(last) > \(n1)") when last > n1
|
||||
}
|
||||
|
||||
for i in n1..n2 {
|
||||
r.Add(i)
|
||||
}
|
||||
last = n2
|
||||
}
|
||||
}
|
||||
|
||||
print("expanded: \(r)")
|
||||
}
|
||||
|
||||
main()
|
||||
25
Task/Range-expansion/EchoLisp/range-expansion.l
Normal file
25
Task/Range-expansion/EchoLisp/range-expansion.l
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
;; parsing [spaces][-]digit(s)-[-]digit(s)[spaces]
|
||||
(define R (make-regexp "^ *(\-?\\d+)\-(\-?\\d+) *$" ))
|
||||
|
||||
;; the native (range a b) is [a ... b[
|
||||
;; (range+ a b) is [a ... b]
|
||||
(define (range+ a b)
|
||||
(if (< a b) (range a (1+ b))
|
||||
(if (> a b) (range a (1- b) -1)
|
||||
(list a))))
|
||||
|
||||
;; in : string : "number" or "number-number"
|
||||
;; out : a range = list of integer(s)
|
||||
(define (do-range str)
|
||||
(define from-to (regexp-exec R str)) ;; "1-3" --> ("1" "3")
|
||||
(if from-to
|
||||
(range+ (string->number (first from-to)) (string->number (second from-to)))
|
||||
(list (string->number str))))
|
||||
|
||||
(define (ranges str)
|
||||
(apply append (map do-range (string-split str ","))))
|
||||
|
||||
|
||||
(define task "-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
(ranges task)
|
||||
→ (-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20)
|
||||
12
Task/Range-expansion/Elixir/range-expansion.elixir
Normal file
12
Task/Range-expansion/Elixir/range-expansion.elixir
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
defmodule RC do
|
||||
def expansion(range) do
|
||||
Enum.flat_map(String.split(range, ","), fn part ->
|
||||
case Regex.scan(~r/^(-?\d+)-(-?\d+)$/, part) do
|
||||
[[_,a,b]] -> Enum.to_list(String.to_integer(a) .. String.to_integer(b))
|
||||
[] -> [String.to_integer(part)]
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
IO.inspect RC.expansion("-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
14
Task/Range-expansion/Erlang/range-expansion.erl
Normal file
14
Task/Range-expansion/Erlang/range-expansion.erl
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
-module( range ).
|
||||
|
||||
-export( [expansion/1, task/0] ).
|
||||
|
||||
expansion( String ) ->
|
||||
lists:flatten( [expansion_individual(io_lib:fread("~d", X)) || X <- string:tokens(String, ",")] ).
|
||||
|
||||
task() ->
|
||||
io:fwrite( "~p~n", [expansion("-6,-3--1,3-5,7-11,14,15,17-20")] ).
|
||||
|
||||
|
||||
|
||||
expansion_individual( {ok, [N], []} ) -> N;
|
||||
expansion_individual( {ok, [Start], "-" ++ Stop_string} ) -> lists:seq( Start, erlang:list_to_integer(Stop_string) ).
|
||||
23
Task/Range-expansion/F-Sharp/range-expansion.fs
Normal file
23
Task/Range-expansion/F-Sharp/range-expansion.fs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
open System.Text.RegularExpressions
|
||||
|
||||
// simplify regex matching with an active pattern
|
||||
let (|Regexp|_|) pattern txt =
|
||||
match Regex.Match(txt, pattern) with
|
||||
| m when m.Success -> [for g in m.Groups -> g.Value] |> List.tail |> Some
|
||||
| _ -> None
|
||||
|
||||
// Parse and expand a single range description.
|
||||
// string -> int list
|
||||
let parseRange r =
|
||||
match r with
|
||||
| Regexp @"^(-?\d+)-(-?\d+)$" [first; last] -> [int first..int last]
|
||||
| Regexp @"^(-?\d+)$" [single] -> [int single]
|
||||
| _ -> failwithf "illegal range format: %s" r
|
||||
|
||||
|
||||
let expand (desc:string) =
|
||||
desc.Split(',')
|
||||
|> List.ofArray
|
||||
|> List.collect parseRange
|
||||
|
||||
printfn "%A" (expand "-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
10
Task/Range-expansion/Factor/range-expansion.factor
Normal file
10
Task/Range-expansion/Factor/range-expansion.factor
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
USING: kernel math.parser math.ranges prettyprint regexp
|
||||
sequences sequences.extras splitting ;
|
||||
|
||||
: expand ( str -- seq )
|
||||
"," split [
|
||||
R/ (?<=\d)-/ re-split [ string>number ] map
|
||||
dup length 2 = [ first2 [a,b] ] when
|
||||
] map-concat ;
|
||||
|
||||
"-6,-3--1,3-5,7-11,14,15,17-20" expand .
|
||||
25
Task/Range-expansion/Forth/range-expansion.fth
Normal file
25
Task/Range-expansion/Forth/range-expansion.fth
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
: >snumber ( str len -- 'str 'len n )
|
||||
0. 2swap
|
||||
over c@ [char] - = if
|
||||
1 /string
|
||||
>number 2swap drop
|
||||
negate
|
||||
else
|
||||
>number 2swap drop
|
||||
then ;
|
||||
|
||||
: expand ( str len -- )
|
||||
begin dup while
|
||||
>snumber >r
|
||||
dup if over c@ [char] - = if
|
||||
1 /string
|
||||
>snumber r> over >r
|
||||
do i . loop
|
||||
then then
|
||||
dup if over c@ [char] , = if
|
||||
1 /string
|
||||
then then
|
||||
r> .
|
||||
repeat 2drop ;
|
||||
|
||||
s" -6,-3--1,3-5,7-11,14,15,17-20" expand
|
||||
100
Task/Range-expansion/Fortran/range-expansion.f
Normal file
100
Task/Range-expansion/Fortran/range-expansion.f
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
MODULE HOMEONTHERANGE
|
||||
CONTAINS !The key function.
|
||||
CHARACTER*200 FUNCTION ERANGE(TEXT) !Expands integer ranges in a list.
|
||||
Can't return a character value of variable size.
|
||||
CHARACTER*(*) TEXT !The list on input.
|
||||
CHARACTER*200 ALINE !Scratchpad for output.
|
||||
INTEGER N,N1,N2 !Numbers in a range.
|
||||
INTEGER I,I1 !Steppers.
|
||||
ALINE = "" !Scrub the scratchpad.
|
||||
L = 0 !No text has been placed.
|
||||
I = 1 !Start at the start.
|
||||
CALL FORASIGN !Find something to look at.
|
||||
Chug through another number or number - number range.
|
||||
R:DO WHILE(EATINT(N1)) !If I can grab a first number, a term has begun.
|
||||
N2 = N1 !Make the far end the same.
|
||||
IF (PASSBY("-")) CALL EATINT(N2) !A hyphen here is not a minus sign.
|
||||
IF (L.GT.0) CALL EMIT(",") !Another, after what went before?
|
||||
DO N = N1,N2,SIGN(+1,N2 - N1) !Step through the range, possibly backwards.
|
||||
CALL SPLOT(N) !Roll a number.
|
||||
IF (N.NE.N2) CALL EMIT(",") !Perhaps another follows.
|
||||
END DO !On to the next number.
|
||||
IF (.NOT.PASSBY(",")) EXIT R !More to come?
|
||||
END DO R !So much for a range.
|
||||
Completed the scan. Just return the result.
|
||||
ERANGE = ALINE(1:L) !Present the result. Fiddling ERANGE is bungled by some compilers.
|
||||
CONTAINS !Some assistants for the scan to save on repetition and show intent.
|
||||
SUBROUTINE FORASIGN !Look for one.
|
||||
1 IF (I.LE.LEN(TEXT)) THEN !After a thingy,
|
||||
IF (TEXT(I:I).LE." ") THEN !There may follow spaces.
|
||||
I = I + 1 !So,
|
||||
GO TO 1 !Speed past any.
|
||||
END IF !So that the caller can see
|
||||
END IF !Whatever substantive character follows.
|
||||
END SUBROUTINE FORASIGN !Simple enough.
|
||||
|
||||
LOGICAL FUNCTION PASSBY(C) !Advances the scan if a certain character is seen.
|
||||
Could consider or ignore case for letters, but this is really for single symbols.
|
||||
CHARACTER*1 C !The character.
|
||||
PASSBY = .FALSE. !Pessimism.
|
||||
IF (I.LE.LEN(TEXT)) THEN !Can't rely on I.LE.LEN(TEXT) .AND. TEXT(I:I)...
|
||||
IF (TEXT(I:I).EQ.C) THEN !Curse possible full evaluation.
|
||||
PASSBY = .TRUE. !Righto, C is seen.
|
||||
I = I + 1 !So advance the scan.
|
||||
CALL FORASIGN !And see what follows.
|
||||
END IF !So much for a match.
|
||||
END IF !If there is something to be uinspected.
|
||||
END FUNCTION PASSBY !Can't rely on testing PASSBY within PASSBY either.
|
||||
|
||||
LOGICAL FUNCTION EATINT(N) !Convert text into an integer.
|
||||
INTEGER N !The value to be ascertained.
|
||||
INTEGER D !A digit.
|
||||
LOGICAL NEG !In case of a minus sign.
|
||||
EATINT = .FALSE. !Pessimism.
|
||||
IF (I.GT.LEN(TEXT)) RETURN !Anything to look at?
|
||||
N = 0 !Scrub to start with.
|
||||
IF (PASSBY("+")) THEN !A plus sign here can be ignored.
|
||||
NEG = .FALSE. !So, there's no minus sign.
|
||||
ELSE !And if there wasn't a plus,
|
||||
NEG = PASSBY("-") !A hyphen here is a minus sign.
|
||||
END IF !One way or another, NEG is initialised.
|
||||
IF (I.GT.LEN(TEXT)) RETURN !Nothing further! We wuz misled!
|
||||
Chug through digits. Can develop -2147483648, thanks to the workings of two's complement.
|
||||
10 D = ICHAR(TEXT(I:I)) - ICHAR("0") !Hope for a digit.
|
||||
IF (0.LE.D .AND. D.LE.9) THEN !Is it one?
|
||||
N = N*10 + D !Yes! Assimilate it, negatively.
|
||||
I = I + 1 !Advance one.
|
||||
IF (I.LE.LEN(TEXT)) GO TO 10 !And see what comes next.
|
||||
END IF !So much for a sequence of digits.
|
||||
IF (NEG) N = -N !Apply the minus sign.
|
||||
EATINT = .TRUE. !Should really check for at least one digit.
|
||||
CALL FORASIGN !Ram into whatever follows.
|
||||
END FUNCTION EATINT !Integers are easy. Could check for no digits seen.
|
||||
|
||||
SUBROUTINE EMIT(C) !Rolls forth one character.
|
||||
CHARACTER*1 C !The character.
|
||||
L = L + 1 !Advance the finger.
|
||||
IF (L.GT.LEN(ALINE)) STOP "Ran out of ALINE!" !Maybe not.
|
||||
ALINE(L:L) = C !And place the character.
|
||||
END SUBROUTINE EMIT !That was simple.
|
||||
|
||||
SUBROUTINE SPLOT(N) !Rolls forth a signed number.
|
||||
INTEGER N !The number.
|
||||
CHARACTER*12 FIELD !Sufficient for 32-bit integers.
|
||||
INTEGER I !A stepper.
|
||||
WRITE (FIELD,"(I0)") N !Roll the number, with trailing spaces.
|
||||
DO I = 1,12 !Now transfer the ALINE of the number.
|
||||
IF (FIELD(I:I).LE." ") EXIT !Up to the first space.
|
||||
CALL EMIT(FIELD(I:I)) !One by one.
|
||||
END DO !On to the end.
|
||||
END SUBROUTINE SPLOT !Not so difficult either.
|
||||
END FUNCTION ERANGE !A bit tricky.
|
||||
END MODULE HOMEONTHERANGE
|
||||
|
||||
PROGRAM POKE
|
||||
USE HOMEONTHERANGE
|
||||
CHARACTER*(200) SOME
|
||||
SOME = "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
SOME = ERANGE(SOME)
|
||||
WRITE (6,*) SOME !If ERANGE(SOME) then the function usually can't write output also.
|
||||
END
|
||||
75
Task/Range-expansion/FreeBASIC/range-expansion.basic
Normal file
75
Task/Range-expansion/FreeBASIC/range-expansion.basic
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
' FB 1.05.0 Win64
|
||||
|
||||
Sub split (s As Const String, sepList As Const String, result() As String)
|
||||
If s = "" OrElse sepList = "" Then
|
||||
Redim result(0)
|
||||
result(0) = s
|
||||
Return
|
||||
End If
|
||||
Dim As Integer i, j, count = 0, empty = 0, length
|
||||
Dim As Integer position(Len(s) + 1)
|
||||
position(0) = 0
|
||||
|
||||
For i = 0 To len(s) - 1
|
||||
For j = 0 to Len(sepList) - 1
|
||||
If s[i] = sepList[j] Then
|
||||
count += 1
|
||||
position(count) = i + 1
|
||||
End If
|
||||
Next j
|
||||
Next i
|
||||
|
||||
Redim result(count)
|
||||
If count = 0 Then
|
||||
result(0) = s
|
||||
Return
|
||||
End If
|
||||
|
||||
position(count + 1) = len(s) + 1
|
||||
|
||||
For i = 1 To count + 1
|
||||
length = position(i) - position(i - 1) - 1
|
||||
result(i - 1) = Mid(s, position(i - 1) + 1, length)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Function expandRange(s As Const String) As String
|
||||
If s = "" Then Return ""
|
||||
Dim b() As String
|
||||
Dim c() As String
|
||||
Dim result As String = ""
|
||||
Dim As Integer start = 0, finish = 0, length
|
||||
split s, ",", b()
|
||||
For i As Integer = LBound(b) To UBound(b)
|
||||
split b(i), "-", c()
|
||||
length = UBound(c) - LBound(c) + 1
|
||||
If length = 1 Then
|
||||
start = ValLng(c(LBound(c)))
|
||||
finish = start
|
||||
ElseIf length = 2 Then
|
||||
If Left(b(i), 1) = "-" Then
|
||||
start = -ValLng(c(UBound(c)))
|
||||
finish = start
|
||||
Else
|
||||
start = ValLng(c(LBound(c)))
|
||||
finish = ValLng(c(UBound(c)))
|
||||
End If
|
||||
ElseIf length = 3 Then
|
||||
start = -ValLng(c(LBound(c) + 1))
|
||||
finish = ValLng(c(UBound(c)))
|
||||
Else
|
||||
start = -ValLng(c(LBound(c) + 1))
|
||||
finish = -ValLng(c(UBound(c)))
|
||||
End If
|
||||
For j As Integer = start To finish
|
||||
result += Str(j) + ", "
|
||||
Next j
|
||||
Next i
|
||||
Return Left(result, Len(result) - 2) '' get rid of final ", "
|
||||
End Function
|
||||
|
||||
Dim s As String = "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
Print expandRange(s)
|
||||
Print
|
||||
Print "Press any key to quit"
|
||||
Sleep
|
||||
64
Task/Range-expansion/Go/range-expansion.go
Normal file
64
Task/Range-expansion/Go/range-expansion.go
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const input = "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
|
||||
func main() {
|
||||
fmt.Println("range:", input)
|
||||
var r []int
|
||||
var last int
|
||||
for _, part := range strings.Split(input, ",") {
|
||||
if i := strings.Index(part[1:], "-"); i == -1 {
|
||||
n, err := strconv.Atoi(part)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if len(r) > 0 {
|
||||
if last == n {
|
||||
fmt.Println("duplicate value:", n)
|
||||
return
|
||||
} else if last > n {
|
||||
fmt.Println("values not ordered:", last, ">", n)
|
||||
return
|
||||
}
|
||||
}
|
||||
r = append(r, n)
|
||||
last = n
|
||||
} else {
|
||||
n1, err := strconv.Atoi(part[:i+1])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
n2, err := strconv.Atoi(part[i+2:])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if n2 < n1+2 {
|
||||
fmt.Println("invalid range:", part)
|
||||
return
|
||||
}
|
||||
if len(r) > 0 {
|
||||
if last == n1 {
|
||||
fmt.Println("duplicate value:", n1)
|
||||
return
|
||||
} else if last > n1 {
|
||||
fmt.Println("values not ordered:", last, ">", n1)
|
||||
return
|
||||
}
|
||||
}
|
||||
for i = n1; i <= n2; i++ {
|
||||
r = append(r, i)
|
||||
}
|
||||
last = n2
|
||||
}
|
||||
}
|
||||
fmt.Println("expanded:", r)
|
||||
}
|
||||
3
Task/Range-expansion/Groovy/range-expansion-1.groovy
Normal file
3
Task/Range-expansion/Groovy/range-expansion-1.groovy
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
def expandRanges = { compressed ->
|
||||
Eval.me('['+compressed.replaceAll(~/(\d)-/, '$1..')+']').flatten().toString()[1..-2]
|
||||
}
|
||||
2
Task/Range-expansion/Groovy/range-expansion-2.groovy
Normal file
2
Task/Range-expansion/Groovy/range-expansion-2.groovy
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
def s = '-6,-3--1,3-5,7-11,14,15,17-20'
|
||||
println (expandRanges(s))
|
||||
2
Task/Range-expansion/Haskell/range-expansion-1.hs
Normal file
2
Task/Range-expansion/Haskell/range-expansion-1.hs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
> expandRange "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
[-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20]
|
||||
10
Task/Range-expansion/Haskell/range-expansion-2.hs
Normal file
10
Task/Range-expansion/Haskell/range-expansion-2.hs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
expandRange :: String -> [Int]
|
||||
expandRange = concatMap f . split ','
|
||||
where f str@(c : cs) | '-' `elem` cs = [read (c : a) .. read b]
|
||||
| otherwise = [read str]
|
||||
where (a, _ : b) = break (== '-') cs
|
||||
|
||||
split :: Eq a => a -> [a] -> [[a]]
|
||||
split delim [] = []
|
||||
split delim l = a : split delim (dropWhile (== delim) b)
|
||||
where (a, b) = break (== delim) l
|
||||
27
Task/Range-expansion/Haskell/range-expansion-3.hs
Normal file
27
Task/Range-expansion/Haskell/range-expansion-3.hs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{-# LANGUAGE FlexibleContexts #-}
|
||||
|
||||
import Text.Parsec
|
||||
|
||||
expandRange :: String -> Maybe [Int]
|
||||
expandRange =
|
||||
either
|
||||
(const Nothing)
|
||||
Just
|
||||
. parse rangeParser ""
|
||||
|
||||
rangeParser ::
|
||||
(Enum a, Read a, Stream s m Char) =>
|
||||
ParsecT s u m [a]
|
||||
rangeParser = concat <$> (item `sepBy` char ',')
|
||||
where
|
||||
item = do
|
||||
n1 <- num
|
||||
n2 <- option n1 (char '-' *> num)
|
||||
return [n1 .. n2]
|
||||
num =
|
||||
read `dot` (<>) <$> option "" (string "-")
|
||||
<*> many1 digit
|
||||
dot = (.) . (.)
|
||||
|
||||
main :: IO ()
|
||||
main = print $ expandRange "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
25
Task/Range-expansion/Icon/range-expansion.icon
Normal file
25
Task/Range-expansion/Icon/range-expansion.icon
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
procedure main()
|
||||
s := "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
write("Input string := ",s)
|
||||
write("Expanded list := ", list2string(range_expand(s)) | "FAILED")
|
||||
end
|
||||
|
||||
procedure range_expand(s) #: return list of integers extracted from an ordered string representation
|
||||
local R,low,high
|
||||
R := []
|
||||
|
||||
s ? until pos(0) do {
|
||||
put(R,low := integer(tab(upto(',-')|0))| fail) # get lower bound
|
||||
if ="-" || (high := integer(tab(find(",")|0))|fail) then
|
||||
until low = high do put(R,low +:= 1) # find range
|
||||
=","
|
||||
}
|
||||
return R
|
||||
end
|
||||
|
||||
procedure list2string(L) #: helper function to convert a list to a string
|
||||
local s
|
||||
|
||||
every (s := "[ ") ||:= !L || " "
|
||||
return s || "]"
|
||||
end
|
||||
6
Task/Range-expansion/J/range-expansion-1.j
Normal file
6
Task/Range-expansion/J/range-expansion-1.j
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
require'strings'
|
||||
thru=: <. + i.@(+*)@-~
|
||||
num=: _&".
|
||||
normaliz=: rplc&(',-';',_';'--';'-_')@,~&','
|
||||
subranges=:<@(thru/)@(num;._2)@,&'-';._1
|
||||
rngexp=: ;@subranges@normaliz
|
||||
2
Task/Range-expansion/J/range-expansion-2.j
Normal file
2
Task/Range-expansion/J/range-expansion-2.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
rngexp '-6,-3--1,3-5,7-11,14,15,17-20'
|
||||
_6 _3 _2 _1 3 4 5 7 8 9 10 11 14 15 17 18 19 20
|
||||
65
Task/Range-expansion/Java/range-expansion.java
Normal file
65
Task/Range-expansion/Java/range-expansion.java
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import java.util.*;
|
||||
|
||||
class RangeExpander implements Iterator<Integer>, Iterable<Integer> {
|
||||
|
||||
private static final Pattern TOKEN_PATTERN = Pattern.compile("([+-]?\\d+)-([+-]?\\d+)");
|
||||
|
||||
private final Iterator<String> tokensIterator;
|
||||
|
||||
private boolean inRange;
|
||||
private int upperRangeEndpoint;
|
||||
private int nextRangeValue;
|
||||
|
||||
public RangeExpander(String range) {
|
||||
String[] tokens = range.split("\\s*,\\s*");
|
||||
this.tokensIterator = Arrays.asList(tokens).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return hasNextRangeValue() || this.tokensIterator.hasNext();
|
||||
}
|
||||
|
||||
private boolean hasNextRangeValue() {
|
||||
return this.inRange && this.nextRangeValue <= this.upperRangeEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
if (hasNextRangeValue()) {
|
||||
return this.nextRangeValue++;
|
||||
}
|
||||
|
||||
String token = this.tokensIterator.next();
|
||||
|
||||
Matcher matcher = TOKEN_PATTERN.matcher(token);
|
||||
if (matcher.find()) {
|
||||
this.inRange = true;
|
||||
this.upperRangeEndpoint = Integer.valueOf(matcher.group(2));
|
||||
this.nextRangeValue = Integer.valueOf(matcher.group(1));
|
||||
return this.nextRangeValue++;
|
||||
}
|
||||
|
||||
this.inRange = false;
|
||||
return Integer.valueOf(token);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Integer> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RangeExpanderTest {
|
||||
public static void main(String[] args) {
|
||||
RangeExpander re = new RangeExpander("-6,-3--1,3-5,7-11,14,15,17-20");
|
||||
for (int i : re) {
|
||||
System.out.print(i + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Task/Range-expansion/JavaScript/range-expansion-1.js
Normal file
34
Task/Range-expansion/JavaScript/range-expansion-1.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env js
|
||||
|
||||
function main() {
|
||||
print(rangeExpand('-6,-3--1,3-5,7-11,14,15,17-20'));
|
||||
}
|
||||
|
||||
function rangeExpand(rangeExpr) {
|
||||
|
||||
function getFactors(term) {
|
||||
var matches = term.match(/(-?[0-9]+)-(-?[0-9]+)/);
|
||||
if (!matches) return {first:Number(term)};
|
||||
return {first:Number(matches[1]), last:Number(matches[2])};
|
||||
}
|
||||
|
||||
function expandTerm(term) {
|
||||
var factors = getFactors(term);
|
||||
if (factors.length < 2) return [factors.first];
|
||||
var range = [];
|
||||
for (var n = factors.first; n <= factors.last; n++) {
|
||||
range.push(n);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
var result = [];
|
||||
var terms = rangeExpr.split(/,/);
|
||||
for (var t in terms) {
|
||||
result = result.concat(expandTerm(terms[t]));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
main();
|
||||
39
Task/Range-expansion/JavaScript/range-expansion-2.js
Normal file
39
Task/Range-expansion/JavaScript/range-expansion-2.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
(function (strTest) {
|
||||
'use strict';
|
||||
|
||||
// s -> [n]
|
||||
function expansion(strExpr) {
|
||||
|
||||
// concat map yields flattened output list
|
||||
return [].concat.apply([], strExpr.split(',')
|
||||
.map(function (x) {
|
||||
return x.split('-')
|
||||
.reduce(function (a, s, i, l) {
|
||||
|
||||
// negative (after item 0) if preceded by an empty string
|
||||
// (i.e. a hyphen-split artefact, otherwise ignored)
|
||||
return s.length ? i ? a.concat(
|
||||
parseInt(l[i - 1].length ? s :
|
||||
'-' + s, 10)
|
||||
) : [+s] : a;
|
||||
}, []);
|
||||
|
||||
// two-number lists are interpreted as ranges
|
||||
})
|
||||
.map(function (r) {
|
||||
return r.length > 1 ? range.apply(null, r) : r;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
// [m..n]
|
||||
function range(m, n) {
|
||||
return Array.apply(null, Array(n - m + 1))
|
||||
.map(function (x, i) {
|
||||
return m + i;
|
||||
});
|
||||
}
|
||||
|
||||
return expansion(strTest);
|
||||
|
||||
})('-6,-3--1,3-5,7-11,14,15,17-20');
|
||||
1
Task/Range-expansion/JavaScript/range-expansion-3.js
Normal file
1
Task/Range-expansion/JavaScript/range-expansion-3.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]
|
||||
64
Task/Range-expansion/JavaScript/range-expansion-4.js
Normal file
64
Task/Range-expansion/JavaScript/range-expansion-4.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
(() => {
|
||||
"use strict";
|
||||
|
||||
// ----------------- RANGE EXPANSION -----------------
|
||||
|
||||
// rangeExpansion :: String -> [Int]
|
||||
const rangeExpansion = rangeString =>
|
||||
// A list of integers parsed from a
|
||||
// comma-delimited string which may include
|
||||
// (rising) hyphenated ranges.
|
||||
rangeString.split(",")
|
||||
.flatMap(x => {
|
||||
const ns = x.split("-")
|
||||
.reduce((a, s, i, xs) =>
|
||||
Boolean(s) ? (
|
||||
0 < i ? a.concat(
|
||||
parseInt(
|
||||
xs[i - 1].length ? (
|
||||
s
|
||||
) : `-${s}`,
|
||||
10
|
||||
)
|
||||
) : [Number(s)]
|
||||
) : a,
|
||||
[]
|
||||
);
|
||||
|
||||
return 2 === ns.length ? (
|
||||
uncurry(enumFromTo)(ns)
|
||||
) : ns;
|
||||
});
|
||||
|
||||
|
||||
// ---------------------- TEST -----------------------
|
||||
// main :: IO ()
|
||||
const main = () =>
|
||||
rangeExpansion("-6,-3--1,3-5,7-11,14,15,17-20");
|
||||
|
||||
|
||||
// --------------------- GENERIC ---------------------
|
||||
|
||||
// enumFromTo :: Int -> Int -> [Int]
|
||||
const enumFromTo = m =>
|
||||
n => Array.from({
|
||||
length: 1 + n - m
|
||||
}, (_, i) => m + i);
|
||||
|
||||
|
||||
// uncurry :: (a -> b -> c) -> ((a, b) -> c)
|
||||
const uncurry = f =>
|
||||
// A function over a pair, derived
|
||||
// from a curried function.
|
||||
(...args) => {
|
||||
const [x, y] = Boolean(args.length % 2) ? (
|
||||
args[0]
|
||||
) : args;
|
||||
|
||||
return f(x)(y);
|
||||
};
|
||||
|
||||
|
||||
// MAIN ---
|
||||
return JSON.stringify(main());
|
||||
})();
|
||||
11
Task/Range-expansion/Jq/range-expansion-1.jq
Normal file
11
Task/Range-expansion/Jq/range-expansion-1.jq
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
def expand_range:
|
||||
def number: "-?[0-9]+";
|
||||
def expand: [range(.[0]; .[1] + 1)];
|
||||
|
||||
split(",")
|
||||
| reduce .[] as $r
|
||||
( []; . +
|
||||
($r | if test("^\(number)$") then [tonumber]
|
||||
else sub( "(?<x>\(number))-(?<y>\(number))"; "\(.x):\(.y)")
|
||||
| split(":") | map(tonumber) | expand
|
||||
end));
|
||||
1
Task/Range-expansion/Jq/range-expansion-2.jq
Normal file
1
Task/Range-expansion/Jq/range-expansion-2.jq
Normal file
|
|
@ -0,0 +1 @@
|
|||
"-6,-3--1,3-5,7-11,14,15,17-20" | expand_range
|
||||
40
Task/Range-expansion/Jsish/range-expansion.jsish
Normal file
40
Task/Range-expansion/Jsish/range-expansion.jsish
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env jsish
|
||||
"use strict";
|
||||
|
||||
/* Range expansion, in Jsish */
|
||||
function rangeExpand(rangeExpr) {
|
||||
|
||||
function getFactors(term) {
|
||||
var matches = term.match(/(-?[0-9]+)-(-?[0-9]+)/);
|
||||
if (!matches) return {first:Number(term)};
|
||||
return {first:Number(matches[1]), last:Number(matches[2])};
|
||||
}
|
||||
|
||||
function expandTerm(term) {
|
||||
var factors = getFactors(term);
|
||||
if (factors.length < 2) return [factors.first];
|
||||
var range = [];
|
||||
for (var n = factors.first; n <= factors.last; n++) {
|
||||
range.push(n);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
var result = [];
|
||||
var terms = rangeExpr.split(",");
|
||||
for (var t in terms) {
|
||||
result = result.concat(expandTerm(terms[t]));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (Interp.conf('unitTest')) {
|
||||
; rangeExpand('-6,-3--1,3-5,7-11,14,15,17-20');
|
||||
}
|
||||
|
||||
/*
|
||||
=!EXPECTSTART!=
|
||||
rangeExpand('-6,-3--1,3-5,7-11,14,15,17-20') ==> [ -6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20 ]
|
||||
=!EXPECTEND!=
|
||||
*/
|
||||
5
Task/Range-expansion/Julia/range-expansion.julia
Normal file
5
Task/Range-expansion/Julia/range-expansion.julia
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
slurp(s) = readcsv(IOBuffer(s))
|
||||
|
||||
conv(s)= colon(map(x->parse(Int,x),match(r"^(-?\d+)-(-?\d+)$", s).captures)...)
|
||||
|
||||
expand(s) = mapreduce(x -> isa(x,Number)? Int(x) : conv(x), vcat, slurp(s))
|
||||
5
Task/Range-expansion/K/range-expansion-1.k
Normal file
5
Task/Range-expansion/K/range-expansion-1.k
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
grp : {1_'(&x=*x)_ x:",",x}
|
||||
pos : {:[3=l:#p:&"-"=x;0,p@1;2=l;p;0=*p;,0;0,p]}
|
||||
conv: 0${(x;1_ y)}/'{(pos x)_ x}'
|
||||
expd: {,/@[x;&2=#:'x;{(*x)+!1+,/-':x}]}
|
||||
rnge: {expd@conv grp x}
|
||||
2
Task/Range-expansion/K/range-expansion-2.k
Normal file
2
Task/Range-expansion/K/range-expansion-2.k
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
rnge "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20
|
||||
35
Task/Range-expansion/Kotlin/range-expansion.kotlin
Normal file
35
Task/Range-expansion/Kotlin/range-expansion.kotlin
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// version 1.0.6
|
||||
|
||||
fun expandRange(s: String): MutableList<Int> {
|
||||
val list = mutableListOf<Int>()
|
||||
val items = s.split(',')
|
||||
var first: Int
|
||||
var last: Int
|
||||
for (item in items) {
|
||||
val count = item.count { it == '-' }
|
||||
if (count == 0 || (count == 1 && item[0] == '-'))
|
||||
list.add(item.toInt())
|
||||
else {
|
||||
val items2 = item.split('-')
|
||||
if (count == 1) {
|
||||
first = items2[0].toInt()
|
||||
last = items2[1].toInt()
|
||||
}
|
||||
else if (count == 2) {
|
||||
first = items2[1].toInt() * -1
|
||||
last = items2[2].toInt()
|
||||
}
|
||||
else {
|
||||
first = items2[1].toInt() * -1
|
||||
last = items2[3].toInt() * -1
|
||||
}
|
||||
for (i in first..last) list.add(i)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val s = "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
println(expandRange(s))
|
||||
}
|
||||
13
Task/Range-expansion/Lasso/range-expansion.lasso
Normal file
13
Task/Range-expansion/Lasso/range-expansion.lasso
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
define range_expand(expression::string) => {
|
||||
local(parts) = regexp(`^(-?\d+)-(-?\d+)$`)
|
||||
|
||||
return (
|
||||
with elm in #expression->split(`,`)
|
||||
let isRange = #parts->setInput(#elm)&matches
|
||||
select #isRange
|
||||
? (integer(#parts->matchString(1)) to integer(#parts->matchString(2)))->asString
|
||||
| integer(#elm)->asString
|
||||
)->join(', ')
|
||||
}
|
||||
|
||||
range_expand(`-6,-3--1,3-5,7-11,14,15,17-20`)
|
||||
23
Task/Range-expansion/Liberty-BASIC/range-expansion.basic
Normal file
23
Task/Range-expansion/Liberty-BASIC/range-expansion.basic
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
print ExpandRange$( "-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
end
|
||||
|
||||
function ExpandRange$( compressed$)
|
||||
for i = 1 to ItemCount( compressed$, ",")
|
||||
item$ = word$( compressed$, i, ",")
|
||||
dash = instr( item$, "-", 2) 'dash that is not the first character, is a separator
|
||||
if dash then
|
||||
for k = val( left$( item$, dash - 1)) to val( mid$( item$, dash + 1))
|
||||
ExpandRange$ = ExpandRange$ + str$( k) + ","
|
||||
next k
|
||||
else
|
||||
ExpandRange$ = ExpandRange$ + item$ + ","
|
||||
end if
|
||||
next i
|
||||
ExpandRange$ = left$( ExpandRange$, len( ExpandRange$) - 1)
|
||||
end function
|
||||
|
||||
function ItemCount( list$, separator$)
|
||||
while word$(list$, ItemCount + 1, separator$) <> ""
|
||||
ItemCount = ItemCount + 1
|
||||
wend
|
||||
end function
|
||||
21
Task/Range-expansion/Lingo/range-expansion-1.lingo
Normal file
21
Task/Range-expansion/Lingo/range-expansion-1.lingo
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
-- Note: currently does not support extra white space in input string
|
||||
on expandRange (str)
|
||||
res = ""
|
||||
_player.itemDelimiter = ","
|
||||
cnt = str.item.count
|
||||
repeat with i = 1 to cnt
|
||||
part = str.item[i]
|
||||
pos = offset("-", part.char[2..part.length])
|
||||
if pos>0 then
|
||||
a = integer(part.char[1..pos])
|
||||
b = integer(part.char[pos+2..part.length])
|
||||
repeat with j = a to b
|
||||
put j&"," after res
|
||||
end repeat
|
||||
else
|
||||
put part&"," after res
|
||||
end if
|
||||
end repeat
|
||||
delete the last char of res
|
||||
return res
|
||||
end
|
||||
2
Task/Range-expansion/Lingo/range-expansion-2.lingo
Normal file
2
Task/Range-expansion/Lingo/range-expansion-2.lingo
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
put expandRange("-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
-- "-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20"
|
||||
38
Task/Range-expansion/LiveCode/range-expansion-1.livecode
Normal file
38
Task/Range-expansion/LiveCode/range-expansion-1.livecode
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
function range beginning ending stepping
|
||||
local tRange, tBegin, tEnd, tstep
|
||||
if stepping is empty or stepping is 0 then
|
||||
put 1 into tstep
|
||||
else
|
||||
put abs(stepping) into tstep
|
||||
end if
|
||||
|
||||
if ending is empty or isNumber(ending) is not true then
|
||||
put 0 into tEnd
|
||||
else
|
||||
put ending into tEnd
|
||||
end if
|
||||
|
||||
if beginning is empty or isNumber(beginning) is not true then
|
||||
put 0 into tBegin
|
||||
else
|
||||
put beginning into tBegin
|
||||
end if
|
||||
|
||||
repeat with r = tBegin to tEnd step tstep
|
||||
put space & r after tRange
|
||||
end repeat
|
||||
return word 1 to -1 of tRange
|
||||
end range
|
||||
|
||||
function expandRange rangeExpr
|
||||
put rangeExpr into tRange
|
||||
split tRange by comma
|
||||
repeat with n = 1 to the number of elements of tRange
|
||||
if matchText(tRange[n],"^(\-*\d+)\-(\-*\d+)",beginning, ending) then
|
||||
put range(beginning, ending, 1) & space after z
|
||||
else
|
||||
put tRange[n] & space after z
|
||||
end if
|
||||
end repeat
|
||||
return z
|
||||
end expandRange
|
||||
2
Task/Range-expansion/LiveCode/range-expansion-2.livecode
Normal file
2
Task/Range-expansion/LiveCode/range-expansion-2.livecode
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
expandRange("-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20
|
||||
28
Task/Range-expansion/Lua/range-expansion.lua
Normal file
28
Task/Range-expansion/Lua/range-expansion.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
function range(i, j)
|
||||
local t = {}
|
||||
for n = i, j, i<j and 1 or -1 do
|
||||
t[#t+1] = n
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function expand_ranges(rspec)
|
||||
local ptn = "([-+]?%d+)%s?-%s?([-+]?%d+)"
|
||||
local t = {}
|
||||
|
||||
for v in string.gmatch(rspec, '[^,]+') do
|
||||
local s, e = v:match(ptn)
|
||||
|
||||
if s == nil then
|
||||
t[#t+1] = tonumber(v)
|
||||
else
|
||||
for i, n in ipairs(range(tonumber(s), tonumber(e))) do
|
||||
t[#t+1] = n
|
||||
end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local ranges = "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
print(table.concat(expand_ranges(ranges), ', '))
|
||||
13
Task/Range-expansion/MATLAB/range-expansion.m
Normal file
13
Task/Range-expansion/MATLAB/range-expansion.m
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
function L=range_expansion(S)
|
||||
% Range expansion
|
||||
if nargin < 1;
|
||||
S='[]';
|
||||
end
|
||||
|
||||
if ~all(isdigit(S) | (S=='-') | (S==',') | isspace(S))
|
||||
error 'invalid input';
|
||||
end
|
||||
ixr = find(isdigit(S(1:end-1)) & S(2:end) == '-')+1;
|
||||
S(ixr)=':';
|
||||
S=['[',S,']'];
|
||||
L=eval(S);
|
||||
10
Task/Range-expansion/MUMPS/range-expansion.mumps
Normal file
10
Task/Range-expansion/MUMPS/range-expansion.mumps
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
RANGEXP(X) ;Integer range expansion
|
||||
NEW Y,I,J,X1,H SET Y=""
|
||||
FOR I=1:1:$LENGTH(X,",") DO
|
||||
.S X1=$PIECE(X,",",I) FOR Q:$EXTRACT(X1)'=" " S X1=$EXTRACT(X1,2,$LENGTH(X1)) ;clean up leading spaces
|
||||
.SET H=$FIND(X1,"-")-1
|
||||
.IF H=1 SET H=$FIND(X1,"-",(H+1))-1 ;If the first value is negative ignore that "-"
|
||||
.IF H<0 SET Y=$SELECT($LENGTH(Y)=0:Y_X1,1:Y_","_X1)
|
||||
.IF '(H<0) FOR J=+$EXTRACT(X1,1,(H-1)):1:+$EXTRACT(X1,(H+1),$LENGTH(X1)) SET Y=$SELECT($LENGTH(Y)=0:J,1:Y_","_J)
|
||||
KILL I,J,X1,H
|
||||
QUIT Y
|
||||
37
Task/Range-expansion/Maple/range-expansion-1.maple
Normal file
37
Task/Range-expansion/Maple/range-expansion-1.maple
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
ExpandRanges := proc( s :: string )
|
||||
uses StringTools;
|
||||
local DoOne := proc( input )
|
||||
uses StringTools;
|
||||
local lo, hi, pos;
|
||||
if IsDigit( input ) or input[ 1 ] = "-"
|
||||
and IsDigit( input[ 2 .. -1 ] ) then
|
||||
parse( input )
|
||||
else
|
||||
pos := Search( "--", input );
|
||||
if pos > 0 then
|
||||
lo := input[ 1 .. pos - 1 ];
|
||||
hi := input[ 1 + pos .. -1 ];
|
||||
elif input[ 1 ] = "-" then
|
||||
pos := FirstFromLeft( "-", input[ 2 .. -1 ] );
|
||||
if pos = 0 then
|
||||
lo := input;
|
||||
hi := lo
|
||||
else
|
||||
lo := input[ 1 .. pos ];
|
||||
hi := input[ 2 + pos .. -1 ];
|
||||
end if;
|
||||
else
|
||||
pos := FirstFromLeft( "-", input );
|
||||
if pos = 0 then
|
||||
error "incorrect syntax"
|
||||
end if;
|
||||
lo := input[ 1 .. pos - 1 ];
|
||||
hi := input[ 1 + pos .. -1 ];
|
||||
end if;
|
||||
lo := parse( lo );
|
||||
hi := parse( hi );
|
||||
seq( lo .. hi )
|
||||
end if
|
||||
end proc:
|
||||
map( DoOne, map( Trim, Split( s, "," ) ) )
|
||||
end proc:
|
||||
3
Task/Range-expansion/Maple/range-expansion-2.maple
Normal file
3
Task/Range-expansion/Maple/range-expansion-2.maple
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
> rng := "-6,-3--1,3-5,7-11,14,15,17-20":
|
||||
> ExpandRanges( rng );
|
||||
[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]
|
||||
3
Task/Range-expansion/Maple/range-expansion-3.maple
Normal file
3
Task/Range-expansion/Maple/range-expansion-3.maple
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
> rng := "-6,-3-1,3-5,7-11,14,15,17-20":
|
||||
> ExpandRanges( rng );
|
||||
[-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]
|
||||
3
Task/Range-expansion/Mathematica/range-expansion.math
Normal file
3
Task/Range-expansion/Mathematica/range-expansion.math
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
rangeexpand[ rng_ ] := Module[ { step1 },
|
||||
step1 = StringSplit[StringReplacePart[rng,"S",StringPosition[ rng,DigitCharacter~~"-"] /. {x_,y_} -> {y,y}],","];
|
||||
Flatten@ToExpression/@Quiet@StringReplace[step1,x__~~"S"~~y__->"Range["<>x<>","<>y<>"]"] ]
|
||||
24
Task/Range-expansion/MiniScript/range-expansion.mini
Normal file
24
Task/Range-expansion/MiniScript/range-expansion.mini
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
pullInt = function(chars)
|
||||
numstr = chars.pull
|
||||
while chars and chars[0] != "," and chars[0] != "-"
|
||||
numstr = numstr + chars.pull
|
||||
end while
|
||||
return val(numstr)
|
||||
end function
|
||||
|
||||
expandRange = function(s)
|
||||
result = []
|
||||
chars = s.split("")
|
||||
while chars
|
||||
num = pullInt(chars)
|
||||
if not chars or chars.pull == "," then
|
||||
result.push num
|
||||
else
|
||||
result = result + range(num, pullInt(chars))
|
||||
chars.pull // skip "," after range
|
||||
end if
|
||||
end while
|
||||
return result
|
||||
end function
|
||||
|
||||
print expandRange("-6,-3--1,3-5,7-11,14,15,17-20")
|
||||
34
Task/Range-expansion/NetRexx/range-expansion.netrexx
Normal file
34
Task/Range-expansion/NetRexx/range-expansion.netrexx
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*NetRexx program to expand a range of integers into a list. *************
|
||||
* 09.08.2012 Walter Pachl derived from my Rexx version
|
||||
* Changes: translate(old,' ',',') -> old.translate(' ',',')
|
||||
* dashpos=pos('-',x,2) -> dashpos=x.pos('-',2)
|
||||
* Do -> Loop
|
||||
* Parse Var a x a -> Parse a x a
|
||||
* Parse Var x ... -> Parse x ...
|
||||
**********************************************************************/
|
||||
|
||||
parse arg old
|
||||
if old = '' then
|
||||
old='-6,-3--1,3-5,7-11,14,15,17-20' /*original list of nums/ranges */
|
||||
|
||||
Say 'old='old /*show old list of nums/ranges. */
|
||||
a=old.translate(' ',',') /*translate commas to blanks */
|
||||
new='' /*new list of numbers (so far). */
|
||||
|
||||
comma=''
|
||||
Loop While a<>'' /* as long as there is input */
|
||||
Parse a x a /* get one element */
|
||||
dashpos=x.pos('-',2) /* find position of dash, if any */
|
||||
If dashpos>0 Then Do /* element is low-high */
|
||||
Parse x low =(dashpos) +1 high /* split the element */
|
||||
Loop j=low To high /* output all numbers in range */
|
||||
new=new||comma||j /* with separating commas */
|
||||
comma=',' /* from now on use comma */
|
||||
End
|
||||
End
|
||||
Else Do /* element is a number */
|
||||
new=new||comma||x /* append (with comma) */
|
||||
comma=',' /* from now on use comma */
|
||||
End
|
||||
End
|
||||
Say 'new='new /*show the expanded list */
|
||||
24
Task/Range-expansion/Nim/range-expansion.nim
Normal file
24
Task/Range-expansion/Nim/range-expansion.nim
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import parseutils, strutils
|
||||
|
||||
proc expandRange(input: string): string =
|
||||
var output: seq[string]
|
||||
for range in input.split(','):
|
||||
var sep = range.find('-', 1)
|
||||
if sep > 0: # parse range
|
||||
var first = -1
|
||||
if range.substr(0, sep-1).parseInt(first) == 0:
|
||||
break
|
||||
var last = -1
|
||||
if range.substr(sep+1).parseInt(last) == 0:
|
||||
break
|
||||
for i in first..last:
|
||||
output.add($i)
|
||||
else: # parse single number
|
||||
var n = -1
|
||||
if range.parseInt(n) > 0:
|
||||
output.add($n)
|
||||
else:
|
||||
break
|
||||
return output.join(",")
|
||||
|
||||
echo("-6,-3--1,3-5,7-11,14,15,17-20".expandRange)
|
||||
23
Task/Range-expansion/OCaml/range-expansion.ocaml
Normal file
23
Task/Range-expansion/OCaml/range-expansion.ocaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#load "str.cma"
|
||||
|
||||
let range a b =
|
||||
if b < a then invalid_arg "range";
|
||||
let rec aux i acc =
|
||||
if i = b then List.rev (i::acc)
|
||||
else aux (succ i) (i::acc)
|
||||
in
|
||||
aux a []
|
||||
|
||||
let parse_piece s =
|
||||
try Scanf.sscanf s "%d-%d" (fun a b -> range a b)
|
||||
with _ -> [int_of_string s]
|
||||
|
||||
let range_expand rng =
|
||||
let ps = Str.split (Str.regexp_string ",") rng in
|
||||
List.flatten (List.map parse_piece ps)
|
||||
|
||||
let () =
|
||||
let rng = "-6,-3--1,3-5,7-11,14,15,17-20" in
|
||||
let exp = range_expand rng in
|
||||
List.iter (Printf.printf " %d") exp;
|
||||
print_newline ()
|
||||
235
Task/Range-expansion/Oberon-2/range-expansion.oberon
Normal file
235
Task/Range-expansion/Oberon-2/range-expansion.oberon
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
MODULE LIVector;
|
||||
IMPORT SYSTEM;
|
||||
TYPE
|
||||
LIPool = POINTER TO ARRAY OF LONGINT;
|
||||
LIVector*= POINTER TO LIVectorDesc;
|
||||
LIVectorDesc = RECORD
|
||||
cap-: INTEGER;
|
||||
len-: INTEGER;
|
||||
LIPool: LIPool;
|
||||
END;
|
||||
|
||||
PROCEDURE (v: LIVector) Init*(cap: INTEGER);
|
||||
BEGIN
|
||||
v.cap := cap;
|
||||
v.len := 0;
|
||||
NEW(v.LIPool,cap);
|
||||
END Init;
|
||||
|
||||
PROCEDURE (v: LIVector) Add*(x: LONGINT);
|
||||
VAR
|
||||
newLIPool: LIPool;
|
||||
BEGIN
|
||||
IF v.len = LEN(v.LIPool^) THEN
|
||||
(* run out of space *)
|
||||
v.cap := v.cap + (v.cap DIV 2);
|
||||
NEW(newLIPool,v.cap);
|
||||
SYSTEM.MOVE(SYSTEM.ADR(v.LIPool^),SYSTEM.ADR(newLIPool^),v.cap * SIZE(LONGINT));
|
||||
v.LIPool := newLIPool
|
||||
END;
|
||||
v.LIPool[v.len] := x;
|
||||
INC(v.len)
|
||||
END Add;
|
||||
|
||||
PROCEDURE (v: LIVector) At*(idx: INTEGER): LONGINT;
|
||||
BEGIN
|
||||
RETURN v.LIPool[idx];
|
||||
END At;
|
||||
END LIVector.
|
||||
|
||||
MODULE LIRange;
|
||||
IMPORT Out, LIV := LIVector;
|
||||
|
||||
TYPE
|
||||
Range* = POINTER TO RangeDesc;
|
||||
RangeDesc = RECORD
|
||||
l,r: POINTER TO ARRAY 1 OF LONGINT;
|
||||
END;
|
||||
|
||||
PROCEDURE (r: Range) Init*();
|
||||
BEGIN
|
||||
r.l := NIL;
|
||||
r.r := NIL;
|
||||
END Init;
|
||||
|
||||
PROCEDURE (r: Range) IsEmpty*(): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN (r.l = NIL) & (r.l = NIL);
|
||||
END IsEmpty;
|
||||
|
||||
PROCEDURE (r: Range) SetLeft*(v: LONGINT);
|
||||
BEGIN
|
||||
IF r.l = NIL THEN NEW(r.l) END;
|
||||
r.l[0] := v;
|
||||
END SetLeft;
|
||||
|
||||
PROCEDURE (r: Range) SetRight*(v : LONGINT);
|
||||
BEGIN
|
||||
IF r.r = NIL THEN NEW(r.r) END;
|
||||
r.r[0] := v;
|
||||
END SetRight;
|
||||
|
||||
PROCEDURE (r: Range) LeftPart*(): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN r.l # NIL;
|
||||
END LeftPart;
|
||||
|
||||
PROCEDURE (r: Range) GetLeft(): LONGINT;
|
||||
BEGIN
|
||||
RETURN r.l[0];
|
||||
END GetLeft;
|
||||
|
||||
PROCEDURE (r: Range) RightPart*(): BOOLEAN;
|
||||
BEGIN
|
||||
RETURN r.l # NIL;
|
||||
END RightPart;
|
||||
|
||||
PROCEDURE (r: Range) GetRight*(): LONGINT;
|
||||
BEGIN
|
||||
RETURN r.r[0];
|
||||
END GetRight;
|
||||
|
||||
PROCEDURE (r: Range) Show*();
|
||||
BEGIN
|
||||
Out.Char('(');
|
||||
IF r.l # NIL THEN Out.LongInt(r.l[0],10) END;
|
||||
Out.String(" - ");
|
||||
IF r.r # NIL THEN Out.LongInt(r.r[0],10); END;
|
||||
Out.Char(')');Out.Ln
|
||||
END Show;
|
||||
|
||||
PROCEDURE (r: Range) Expand*(VAR liv: LIV.LIVector);
|
||||
VAR
|
||||
from, to : LONGINT;
|
||||
BEGIN
|
||||
IF r.l # NIL THEN from := r.l[0] ELSE from := 0 END;
|
||||
IF r.r # NIL THEN to := r.r[0] ELSE to := from END;
|
||||
WHILE (from <= to) DO
|
||||
liv.Add(from);INC(from)
|
||||
END
|
||||
END Expand;
|
||||
END LIRange.
|
||||
|
||||
MODULE Splitter;
|
||||
TYPE
|
||||
Splitter* = POINTER TO SplitterDesc;
|
||||
SplitterDesc = RECORD
|
||||
from: INTEGER;
|
||||
c: CHAR;
|
||||
s: POINTER TO ARRAY OF CHAR;
|
||||
END;
|
||||
|
||||
PROCEDURE (s: Splitter) Init*;
|
||||
BEGIN
|
||||
s.c := ',';
|
||||
s.from := 0;
|
||||
s.s := NIL;
|
||||
END Init;
|
||||
|
||||
PROCEDURE (s: Splitter) On*(str: ARRAY OF CHAR);
|
||||
BEGIN
|
||||
s.from := 0;
|
||||
NEW(s.s,LEN(str));
|
||||
COPY(str,s.s^)
|
||||
END On;
|
||||
|
||||
PROCEDURE (s: Splitter) OnWithChar*(str: ARRAY OF CHAR;c: CHAR);
|
||||
BEGIN
|
||||
s.from := 0;
|
||||
s.c := c;
|
||||
NEW(s.s,LEN(str));
|
||||
COPY(str,s.s^)
|
||||
END OnWithChar;
|
||||
|
||||
PROCEDURE (s: Splitter) Next*(VAR str: ARRAY OF CHAR);
|
||||
VAR
|
||||
k : INTEGER;
|
||||
BEGIN
|
||||
k := 0;
|
||||
IF (s.from < LEN(s.s^) - 1) & (s.s[s.from] = 0X) THEN str[0] := 0X END;
|
||||
WHILE (k < LEN(str) - 1) & (s.from < LEN(s.s^) - 1) & (s.s[s.from] # s.c) DO
|
||||
str[k] := s.s[s.from];
|
||||
INC(k);INC(s.from)
|
||||
END;
|
||||
IF k < LEN(str) - 1 THEN str[k] := 0X ELSE str[LEN(str) - 1] := 0X END;
|
||||
WHILE (s.from < LEN(s.s^) - 1) & (s.s[s.from] # s.c) DO INC(s.from) END;
|
||||
INC(s.from)
|
||||
END Next;
|
||||
END Splitter.
|
||||
|
||||
MODULE ExpandRange;
|
||||
IMPORT Out, LIV := LIVector, LIR := LIRange, S := Splitter;
|
||||
|
||||
PROCEDURE GetNumberFrom(s: ARRAY OF CHAR; VAR from: INTEGER; VAR done: BOOLEAN): LONGINT;
|
||||
VAR
|
||||
d,i: INTEGER;
|
||||
num,sign: LONGINT;
|
||||
BEGIN
|
||||
i := from; num := 0;sign := 1;
|
||||
CASE s[i] OF
|
||||
'-': sign := -1;INC(i)
|
||||
|'+': INC(i);
|
||||
ELSE
|
||||
END;
|
||||
WHILE (i < LEN(s) - 1) & (s[i] >= '0') & (s[i] <= '9') DO
|
||||
d := ORD(s[i]) - ORD('0');
|
||||
num := d + num * 10;
|
||||
INC(i);
|
||||
END;
|
||||
IF i = from THEN done := FALSE ELSE done := TRUE; from := i END;
|
||||
RETURN sign * num
|
||||
END GetNumberFrom;
|
||||
|
||||
PROCEDURE GetRange(s: ARRAY OF CHAR): LIR.Range;
|
||||
VAR
|
||||
r: LIR.Range;
|
||||
i: INTEGER;
|
||||
num: LONGINT;
|
||||
done: BOOLEAN;
|
||||
BEGIN
|
||||
i := 0;NEW(r);r.Init();
|
||||
WHILE (i < LEN(s) - 1) & (s[i] = 20X) DO INC(i) END;
|
||||
(* Left value *)
|
||||
done := FALSE;
|
||||
num := GetNumberFrom(s,i,done);
|
||||
IF ~done THEN RETURN r END;
|
||||
r.SetLeft(num);
|
||||
|
||||
WHILE (i < LEN(s) - 1) & (s[i] = 20X) DO INC(i) END;
|
||||
CASE s[i] OF
|
||||
'-' : INC(i);
|
||||
| 0X : RETURN r;
|
||||
ELSE
|
||||
END;
|
||||
WHILE (i < LEN(s) - 1) & (s[i] = 20X) DO INC(i) END;
|
||||
|
||||
(* Right Value *)
|
||||
done := FALSE;
|
||||
num := GetNumberFrom(s,i,done);
|
||||
IF ~done THEN RETURN r END;
|
||||
r.SetRight(num);
|
||||
RETURN r;
|
||||
END GetRange;
|
||||
|
||||
VAR
|
||||
i: INTEGER;
|
||||
r: LIR.Range;
|
||||
sp: S.Splitter;
|
||||
p : ARRAY 128 OF CHAR;
|
||||
liv: LIV.LIVector;
|
||||
BEGIN
|
||||
NEW(sp);sp.Init();
|
||||
NEW(liv);liv.Init(128);
|
||||
|
||||
sp.On("-6,-3--1,3-5,7-11,14,15,17-20");
|
||||
sp.Next(p);
|
||||
WHILE (p[0] # 0X) DO
|
||||
r := GetRange(p);
|
||||
r.Expand(liv);
|
||||
sp.Next(p);
|
||||
END;
|
||||
FOR i := 0 TO liv.len - 2 DO
|
||||
Out.LongInt(liv.At(i),3);Out.Char(',');
|
||||
END;
|
||||
Out.LongInt(liv.At(liv.len - 1),3);Out.Ln;
|
||||
END ExpandRange.
|
||||
10
Task/Range-expansion/Oforth/range-expansion.fth
Normal file
10
Task/Range-expansion/Oforth/range-expansion.fth
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
: addRange( s res -- )
|
||||
| i n |
|
||||
s asInteger dup ifNotNull: [ res add return ] drop
|
||||
s indexOfFrom('-', 2) ->i
|
||||
s left( i 1- ) asInteger s right( s size i - ) asInteger
|
||||
for: n [ n res add ]
|
||||
;
|
||||
|
||||
: rangeExpand ( s -- [ n ] )
|
||||
ArrayBuffer new s wordsWith( ',' ) apply( #[ over addRange ] ) ;
|
||||
30
Task/Range-expansion/OoRexx/range-expansion.rexx
Normal file
30
Task/Range-expansion/OoRexx/range-expansion.rexx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
list = '-6,-3--1,3-5,7-11,14,15,17-20'
|
||||
expanded = expandRanges(list)
|
||||
|
||||
say "Original list: ["list"]"
|
||||
say "Expanded list: ["expanded~tostring("l", ",")"]"
|
||||
|
||||
-- expand a string expression a range of numbers into a list
|
||||
-- of values for the range. This returns an array
|
||||
::routine expandRanges
|
||||
use strict arg list
|
||||
values = list~makearray(',')
|
||||
-- build this up using an array first. Make this at least the
|
||||
-- size of the original value set.
|
||||
expanded = .array~new(values~items)
|
||||
|
||||
-- now process each element in the range
|
||||
loop element over values
|
||||
-- if this is a valid number, it's not a range, so add it directly
|
||||
if element~datatype('whole') then expanded~append(element)
|
||||
else do
|
||||
-- search for the divider, starting from the second position
|
||||
-- to allow for the starting value to be a minus sign.
|
||||
split = element~pos('-', 2)
|
||||
parse var element start =(split) +1 finish
|
||||
loop i = start to finish
|
||||
expanded~append(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
return expanded
|
||||
30
Task/Range-expansion/Oz/range-expansion-1.oz
Normal file
30
Task/Range-expansion/Oz/range-expansion-1.oz
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
declare
|
||||
fun {Expand RangeDesc}
|
||||
{Flatten
|
||||
{Map {ParseDesc RangeDesc}
|
||||
ExpandRange}}
|
||||
end
|
||||
|
||||
fun {ParseDesc Txt}
|
||||
{Map {String.tokens Txt &,} ParseRange}
|
||||
end
|
||||
|
||||
fun {ParseRange R}
|
||||
if {Member &- R.2} then
|
||||
First Second
|
||||
in
|
||||
{String.token R.2 &- ?First ?Second}
|
||||
{String.toInt R.1|First}#{String.toInt Second}
|
||||
else
|
||||
Singleton = {String.toInt R}
|
||||
in
|
||||
Singleton#Singleton
|
||||
end
|
||||
end
|
||||
|
||||
fun {ExpandRange From#To}
|
||||
{List.number From To 1}
|
||||
end
|
||||
in
|
||||
{System.showInfo
|
||||
{Value.toVirtualString {Expand "-6,-3--1,3-5,7-11,14,15,17-20"} 100 100}}
|
||||
1
Task/Range-expansion/Oz/range-expansion-2.oz
Normal file
1
Task/Range-expansion/Oz/range-expansion-2.oz
Normal file
|
|
@ -0,0 +1 @@
|
|||
[~6 ~3 ~2 ~1 3 4 5 7 8 9 10 11 14 15 17 18 19 20]
|
||||
12
Task/Range-expansion/PHP/range-expansion.php
Normal file
12
Task/Range-expansion/PHP/range-expansion.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
function rangex($str) {
|
||||
$lst = array();
|
||||
foreach (explode(',', $str) as $e) {
|
||||
if (strpos($e, '-', 1) !== FALSE) {
|
||||
list($a, $b) = explode('-', substr($e, 1), 2);
|
||||
$lst = array_merge($lst, range($e[0] . $a, $b));
|
||||
} else {
|
||||
$lst[] = (int) $e;
|
||||
}
|
||||
}
|
||||
return $lst;
|
||||
}
|
||||
51
Task/Range-expansion/PL-I/range-expansion.pli
Normal file
51
Task/Range-expansion/PL-I/range-expansion.pli
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
range_expansion:
|
||||
procedure options (main);
|
||||
|
||||
get_number:
|
||||
procedure (Number, c, eof);
|
||||
declare number fixed binary (31), c character (1), eof bit (1) aligned;
|
||||
declare neg fixed binary (1);
|
||||
|
||||
number = 0; eof = false;
|
||||
do until (c ^= ' ');
|
||||
get edit (c) (a(1));
|
||||
end;
|
||||
if c = '-' then do; get edit (c) (a(1)); neg = -1; end; else neg = 1;
|
||||
do forever;
|
||||
select (c);
|
||||
when ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
|
||||
number = number*10 + c;
|
||||
when (',', '-') do; number = neg*number; return; end;
|
||||
otherwise signal error;
|
||||
end;
|
||||
on endfile (sysin) go to exit;
|
||||
get edit (c) (a(1));
|
||||
end;
|
||||
exit:
|
||||
number = neg*number;
|
||||
eof = true;
|
||||
end get_Number;
|
||||
|
||||
declare c character, (i, range_start, range_end) fixed binary (31);
|
||||
declare eof bit (1) aligned;
|
||||
declare true bit (1) value ('1'b), false bit (1) value ('0'b);
|
||||
declare delimiter character (1) initial (' ');
|
||||
declare out file output;
|
||||
|
||||
open file (out) output title ('/out, type(text),recsize(80)');
|
||||
do while (^eof);
|
||||
call get_number(range_start, c, eof);
|
||||
if c = '-' then /* we have a range */
|
||||
do;
|
||||
call get_number (range_end, c, eof);
|
||||
do i = range_start to range_end;
|
||||
put file (out) edit (delimiter, i) (a, f(3));
|
||||
end;
|
||||
end;
|
||||
else
|
||||
do;
|
||||
put file (out) edit (delimiter, range_start) (a, f(3));
|
||||
end;
|
||||
delimiter = ',';
|
||||
end;
|
||||
end range_expansion;
|
||||
6
Task/Range-expansion/Perl/range-expansion-1.pl
Normal file
6
Task/Range-expansion/Perl/range-expansion-1.pl
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
sub rangex {
|
||||
map { /^(.*\d)-(.+)$/ ? $1..$2 : $_ } split /,/, shift
|
||||
}
|
||||
|
||||
# Test and display
|
||||
print join(',', rangex('-6,-3--1,3-5,7-11,14,15,17-20')), "\n";
|
||||
4
Task/Range-expansion/Perl/range-expansion-2.pl
Normal file
4
Task/Range-expansion/Perl/range-expansion-2.pl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
sub rangex {
|
||||
(my $range = shift) =~ s/(?<=\d)-/../g;
|
||||
eval $range;
|
||||
}
|
||||
24
Task/Range-expansion/Phix/range-expansion.phix
Normal file
24
Task/Range-expansion/Phix/range-expansion.phix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">range_expansion</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">range</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">range</span><span style="color: #0000FF;">,</span><span style="color: #008000;">','</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">si</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">to_number</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">startrange</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">to_number</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]),</span>
|
||||
<span style="color: #000000;">endofrange</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">to_number</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$])</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">=</span><span style="color: #000000;">startrange</span> <span style="color: #008080;">to</span> <span style="color: #000000;">endofrange</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">range_expansion</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"-6,-3-1,3-5,7-11,14,15,17-20"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">range_expansion</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"-6,-3--1,3-5,7-11,14,15,17-20"</span><span style="color: #0000FF;">)</span>
|
||||
<!--
|
||||
24
Task/Range-expansion/Phixmonti/range-expansion-1.phixmonti
Normal file
24
Task/Range-expansion/Phixmonti/range-expansion-1.phixmonti
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
0 tolist var r
|
||||
|
||||
def append
|
||||
r swap 0 put var r
|
||||
enddef
|
||||
|
||||
"-6,-3--1,3-5,7-11,14,15,17-20" "," " " subst split
|
||||
|
||||
len for
|
||||
get dup tonum dup
|
||||
nan == if
|
||||
drop
|
||||
dup len 1 - 2 swap slice
|
||||
"-" find dup 2 + rot drop
|
||||
rot rot 1 swap slice tonum
|
||||
rot rot len rot swap over - 1 + slice tonum
|
||||
nip rot drop
|
||||
2 tolist for append endfor
|
||||
else
|
||||
append drop
|
||||
endif
|
||||
endfor
|
||||
r
|
||||
pstack
|
||||
23
Task/Range-expansion/Phixmonti/range-expansion-2.phixmonti
Normal file
23
Task/Range-expansion/Phixmonti/range-expansion-2.phixmonti
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
0 tolist var r
|
||||
|
||||
def append
|
||||
r swap 0 put var r
|
||||
enddef
|
||||
|
||||
"-6,-3--1,3-5,7-11,14,15,17-20" "," " " subst split
|
||||
|
||||
len for
|
||||
get dup tonum dup
|
||||
nan == if
|
||||
drop
|
||||
dup 32 1 set
|
||||
"-" find nip
|
||||
swap over 1 - 1 swap slice tonum
|
||||
rot rot len rot swap over - swap 1 + swap slice tonum
|
||||
nip 2 tolist for append endfor
|
||||
else
|
||||
append drop
|
||||
endif
|
||||
endfor
|
||||
r
|
||||
pstack
|
||||
38
Task/Range-expansion/Phixmonti/range-expansion-3.phixmonti
Normal file
38
Task/Range-expansion/Phixmonti/range-expansion-3.phixmonti
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
0 tolist var r
|
||||
|
||||
def append
|
||||
r swap 0 put var r
|
||||
enddef
|
||||
|
||||
def getSeparator /# s -- s n #/
|
||||
dup 32 1 set
|
||||
"-" find nip
|
||||
enddef
|
||||
|
||||
def first /# s n -- s n #/
|
||||
swap over 1 - 1
|
||||
swap slice tonum
|
||||
enddef
|
||||
|
||||
def last /# s n -- s n #/
|
||||
swap len rot swap over - swap 1 +
|
||||
swap slice tonum
|
||||
enddef
|
||||
|
||||
"-6,-3--1,3-5,7-11,14,15,17-20" "," " " subst split
|
||||
|
||||
len for
|
||||
get dup tonum dup
|
||||
nan == if
|
||||
drop
|
||||
getSeparator
|
||||
first
|
||||
rot rot swap
|
||||
last
|
||||
nip 2 tolist for append endfor
|
||||
else
|
||||
append drop
|
||||
endif
|
||||
endfor
|
||||
r
|
||||
pstack
|
||||
9
Task/Range-expansion/PicoLisp/range-expansion.l
Normal file
9
Task/Range-expansion/PicoLisp/range-expansion.l
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
(de rangeexpand (Str)
|
||||
(make
|
||||
(for S (split (chop Str) ",")
|
||||
(if (index "-" (cdr S))
|
||||
(chain
|
||||
(range
|
||||
(format (head @ S))
|
||||
(format (tail (- -1 @) S)) ) )
|
||||
(link (format S)) ) ) ) )
|
||||
22
Task/Range-expansion/PowerShell/range-expansion-1.psh
Normal file
22
Task/Range-expansion/PowerShell/range-expansion-1.psh
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
function range-expansion($array) {
|
||||
function expansion($arr) {
|
||||
if($arr) {
|
||||
$arr = $arr.Split(',')
|
||||
$arr | foreach{
|
||||
$a = $_
|
||||
$b, $c, $d, $e = $a.Split('-')
|
||||
switch($a) {
|
||||
$b {return $a}
|
||||
"-$c" {return $a}
|
||||
"$b-$c" {return "$(([Int]$b)..([Int]$c))"}
|
||||
"-$c-$d" {return "$(([Int]$("-$c"))..([Int]$d))"}
|
||||
"-$c--$e" {return "$(([Int]$("-$c"))..([Int]$("-$e")))"}
|
||||
}
|
||||
}
|
||||
} else {""}
|
||||
}
|
||||
$OFS = ", "
|
||||
"$(expansion $array)"
|
||||
$OFS = " "
|
||||
}
|
||||
range-expansion "-6,-3--1,3-5,7-11,14,15,17-20"
|
||||
42
Task/Range-expansion/PowerShell/range-expansion-2.psh
Normal file
42
Task/Range-expansion/PowerShell/range-expansion-2.psh
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
function Expand-Range
|
||||
{
|
||||
[CmdletBinding()]
|
||||
[OutputType([int])]
|
||||
Param
|
||||
(
|
||||
[Parameter(Mandatory=$true,
|
||||
Position=0)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[ValidatePattern('^[0-9,-]*$')]
|
||||
[string]
|
||||
$Range
|
||||
)
|
||||
|
||||
try
|
||||
{
|
||||
if ($Range -match '-,') # I'm not good enough to weed this case out with Regex
|
||||
{
|
||||
throw "Input string was not in a correct format."
|
||||
}
|
||||
|
||||
[int[]]$output = $Range -split ',' | ForEach-Object {
|
||||
|
||||
[int[]]$array = $_ -split '(?<=\d)-'
|
||||
|
||||
if ($array.Count -gt 1) # $array contains one or two elements
|
||||
{
|
||||
$array[0]..$array[1] # two elements = start and end of range
|
||||
}
|
||||
else
|
||||
{
|
||||
$array # one element = an integer
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw "Input string was not in a correct format."
|
||||
}
|
||||
|
||||
$output
|
||||
}
|
||||
1
Task/Range-expansion/PowerShell/range-expansion-3.psh
Normal file
1
Task/Range-expansion/PowerShell/range-expansion-3.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
(Expand-Range "-6,-3--1,3-5,7-11,14,15,17-20") -join ", "
|
||||
81
Task/Range-expansion/Prolog/range-expansion.pro
Normal file
81
Task/Range-expansion/Prolog/range-expansion.pro
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
range_expand :-
|
||||
L = '-6,-3--1,3-5,7-11,14,15,17-20',
|
||||
writeln(L),
|
||||
atom_chars(L, LA),
|
||||
extract_Range(LA, R),
|
||||
maplist(study_Range, R, LR),
|
||||
pack_Range(LX, LR),
|
||||
writeln(LX).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% 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]).
|
||||
46
Task/Range-expansion/PureBasic/range-expansion.basic
Normal file
46
Task/Range-expansion/PureBasic/range-expansion.basic
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
Procedure rangeexpand(txt.s, List outputList())
|
||||
Protected rangesCount = CountString(txt, ",") + 1
|
||||
Protected subTxt.s, r, rangeMarker, rangeStart, rangeFinish, rangeIncrement, i
|
||||
|
||||
LastElement(outputList())
|
||||
For r = 1 To rangesCount
|
||||
subTxt = StringField(txt, r, ",")
|
||||
rangeMarker = FindString(subTxt, "-", 2)
|
||||
If rangeMarker
|
||||
rangeStart = Val(Mid(subTxt, 1, rangeMarker - 1))
|
||||
rangeFinish = Val(Mid(subTxt, rangeMarker + 1))
|
||||
|
||||
If rangeStart > rangeFinish
|
||||
rangeIncrement = -1
|
||||
Else
|
||||
rangeIncrement = 1
|
||||
EndIf
|
||||
|
||||
i = rangeStart - rangeIncrement
|
||||
Repeat
|
||||
i + rangeIncrement
|
||||
AddElement(outputList()): outputList() = i
|
||||
Until i = rangeFinish
|
||||
Else
|
||||
AddElement(outputList()): outputList() = Val(subTxt)
|
||||
EndIf
|
||||
Next
|
||||
EndProcedure
|
||||
|
||||
Procedure outputListValues(List values())
|
||||
Print("[ ")
|
||||
ForEach values()
|
||||
Print(Str(values()) + " ")
|
||||
Next
|
||||
PrintN("]")
|
||||
EndProcedure
|
||||
|
||||
If OpenConsole()
|
||||
NewList values()
|
||||
rangeexpand("-6,-3--1,3-5,7-11,14,15,17-20", values())
|
||||
outputListValues(values())
|
||||
|
||||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
|
||||
Input()
|
||||
CloseConsole()
|
||||
EndIf
|
||||
11
Task/Range-expansion/Python/range-expansion-1.py
Normal file
11
Task/Range-expansion/Python/range-expansion-1.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
def rangeexpand(txt):
|
||||
lst = []
|
||||
for r in txt.split(','):
|
||||
if '-' in r[1:]:
|
||||
r0, r1 = r[1:].split('-', 1)
|
||||
lst += range(int(r[0] + r0), int(r1) + 1)
|
||||
else:
|
||||
lst.append(int(r))
|
||||
return lst
|
||||
|
||||
print(rangeexpand('-6,-3--1,3-5,7-11,14,15,17-20'))
|
||||
11
Task/Range-expansion/Python/range-expansion-2.py
Normal file
11
Task/Range-expansion/Python/range-expansion-2.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import re
|
||||
|
||||
def rangeexpand(txt):
|
||||
lst = []
|
||||
for rng in txt.split(','):
|
||||
start,end = re.match('^(-?\d+)(?:-(-?\d+))?$', rng).groups()
|
||||
if end:
|
||||
lst.extend(xrange(int(start),int(end)+1))
|
||||
else:
|
||||
lst.append(int(start))
|
||||
return lst
|
||||
102
Task/Range-expansion/Python/range-expansion-3.py
Normal file
102
Task/Range-expansion/Python/range-expansion-3.py
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
'''Range expansion'''
|
||||
|
||||
from functools import (reduce)
|
||||
|
||||
|
||||
# ------------------- EXPANSION FUNCTION -------------------
|
||||
|
||||
# rangeExpansion :: String -> [Int]
|
||||
def rangeExpansion(s):
|
||||
'''List of integers expanded from a
|
||||
comma-delimited string of individual
|
||||
numbers and hyphenated ranges.
|
||||
'''
|
||||
def go(a, x):
|
||||
tpl = breakOn('-')(x[1:])
|
||||
r = tpl[1]
|
||||
return a + (
|
||||
[int(x)] if not r
|
||||
else enumFromTo(int(x[0] + tpl[0]))(
|
||||
int(r[1:])
|
||||
)
|
||||
)
|
||||
return reduce(go, s.split(','), [])
|
||||
|
||||
|
||||
# -------------------------- TEST --------------------------
|
||||
def main():
|
||||
'''Expansion test'''
|
||||
|
||||
print(
|
||||
fTable(__doc__ + ':')(
|
||||
lambda x: "\n'" + str(x) + "'"
|
||||
)(lambda x: '\n\n\t' + showList(x))(
|
||||
rangeExpansion
|
||||
)([
|
||||
'-6,-3--1,3-5,7-11,14,15,17-20'
|
||||
])
|
||||
)
|
||||
|
||||
|
||||
# ------------------- GENERIC FUNCTIONS --------------------
|
||||
|
||||
# breakOn :: String -> String -> (String, String)
|
||||
def breakOn(needle):
|
||||
'''A tuple of:
|
||||
1. the prefix of haystack before needle,
|
||||
2. the remainder of haystack, starting
|
||||
with needle.
|
||||
'''
|
||||
def go(haystack):
|
||||
xs = haystack.split(needle)
|
||||
return (xs[0], haystack[len(xs[0]):]) if (
|
||||
1 < len(xs)
|
||||
) else (haystack, '')
|
||||
return lambda haystack: go(haystack) if (
|
||||
needle
|
||||
) else None
|
||||
|
||||
|
||||
# enumFromTo :: Int -> Int -> [Int]
|
||||
def enumFromTo(m):
|
||||
'''Enumeration of integer values [m..n]
|
||||
'''
|
||||
return lambda n: list(range(m, 1 + n))
|
||||
|
||||
|
||||
# fTable :: String -> (a -> String) ->
|
||||
# (b -> String) -> (a -> b) -> [a] -> String
|
||||
def fTable(s):
|
||||
'''Heading -> x display function ->
|
||||
fx display function -> f -> xs -> tabular string.
|
||||
'''
|
||||
def gox(xShow):
|
||||
def gofx(fxShow):
|
||||
def gof(f):
|
||||
def goxs(xs):
|
||||
ys = [xShow(x) for x in xs]
|
||||
w = max(map(len, ys))
|
||||
|
||||
def arrowed(x, y):
|
||||
return y.rjust(w, ' ') + ' -> ' + (
|
||||
fxShow(f(x))
|
||||
)
|
||||
return s + '\n' + '\n'.join(
|
||||
map(arrowed, xs, ys)
|
||||
)
|
||||
return goxs
|
||||
return gof
|
||||
return gofx
|
||||
return gox
|
||||
|
||||
|
||||
# showList :: [a] -> String
|
||||
def showList(xs):
|
||||
'''Stringification of a list.
|
||||
'''
|
||||
return '[' + ','.join(str(x) for x in xs) + ']'
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue