Range expansion: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Added 11l)
m (→‎{{header|Wren}}: Changed to Wren S/H)
(42 intermediate revisions by 23 users not shown)
Line 17:
=={{header|11l}}==
{{trans|Python}}
<langsyntaxhighlight lang="11l">F rangeexpand(txt)
Array[Int] lst
L(r) txt.split(‘,’)
I ‘-’ C r[1..]
AV rr = r[1..].split(‘-’, 1 + 12)
lst [+]= (Int(r[0]‘’rr[0]) .<. Int(rr[1]) + 1)
E
lst.append(Int(r))
R lst
 
print(rangeexpand(‘-6,-3--1,3-5,7-11,14,15,17-20’))</langsyntaxhighlight>
 
=={{header|8th}}==
<langsyntaxhighlight Forthlang="forth">\ Given a low and high limit, create an array containing the numbers in the
\ range, inclusive:
: n:gen-range \ low hi -- a
Line 90:
n:range-expand
\ print the expanded list:
. cr bye</langsyntaxhighlight>
{{out}}
<pre>
[-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20]
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">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</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Range_expansion.png Screenshot from Atari 8-bit computer]
<pre>
[-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20]
</pre>
 
=={{header|Ada}}==
The function Expand takes a string and returns a corresponding array of integers.
Upon syntax errors Constraint_Error is propagated:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
procedure Test_Range_Expansion is
type Sequence is array (Positive range <>) of Integer;
Line 163 ⟶ 243:
begin
Put (Expand ("-6,-3--1,3-5,7-11,14,15,17-20"));
end Test_Range_Expansion;</langsyntaxhighlight>
{{out}}
<pre>
-6,-3,-2,-1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20
</pre>
 
=={{header|Aime}}==
{{incorrect|Aime|Needs "a comma separated list" without the trailing comma}}
<syntaxhighlight lang="aime">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");</syntaxhighlight>
or:
<syntaxhighlight lang="aime">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");</syntaxhighlight>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20,</pre>
 
=={{header|ALGOL 68}}==
Line 173 ⟶ 293:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny] - string parsing and formatting code tested with 2.6.win32}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
<langsyntaxhighlight lang="algol68">MODE YIELDINT = PROC(INT)VOID;
 
MODE RANGE = STRUCT(INT lwb, upb);
Line 342 ⟶ 462:
print( ( TOSTRING range expand( TORANGE "-6,-3--1,3-5,7-11,14,15,17-20" ), newline ) )
)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 348 ⟶ 468:
</pre>
 
=={{header|APL}}==
{{works with|Dyalog APL}}
<syntaxhighlight lang="apl">range←{
aplnum←{⍎('¯',⎕D)[('-',⎕D)⍳⍵]}
∊{ 0::('Invalid range: ''',⍵,'''')⎕SIGNAL 11
n←aplnum¨(~<\(⊢≠∨\)⍵∊⎕D)⊆⍵
1=≢n:n
s e←n
(s+(⍳e-s-1))-1
}¨(⍵≠',')⊆⍵
}</syntaxhighlight>
 
{{out}}
 
<pre> range '-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
range '-6,--3--1,3-5,7-11,14,15,17-20'
Invalid range: '--3--1'
range'-6,--3--1,3-5,7-11,14,15,17-20'
range'-6,-3--1,3-5,11-7,14,15,17-20'
Invalid range: '11-7'
range'-6,-3--1,3-5,11-7,14,15,17-20'
∧</pre>
 
=={{header|AppleScript}}==
===Functional===
{{Trans|JavaScript}} (Functional ES5 version)
<langsyntaxhighlight AppleScriptlang="applescript">-- 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]
Line 367 ⟶ 515:
-- signedIntegerAppended:: [Int] -> String -> Int -> [Int] -> [Int]
on signedIntegerAppended(lstAccumulatoracc, strNum, iPosn, lstxs)
if strNum ≠ "" then
if iPosn > 1 then
ifset strSign to |λ|(0 < length of (item (iPosn - 1) of lstxs)) > 0 then¬
setof strSign tobool("", "-")
else
set strSign to "-"
end if
else
set strSign to "+"
end if
lstAccumulator & ((strSign & strNum) as integer)
acc & ((strSign & strNum) as integer)
else
lstAccumulatoracc
end if
end signedIntegerAppended
Line 394 ⟶ 540:
 
 
-- TEST --------------------------------------------- TEST --------------------------
on run
Line 403 ⟶ 549:
 
 
-- GENERIC FUNCTIONS -------------------------------------- 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]
Line 483 ⟶ 651:
item 1 of tuple
end if
end tupleRange</langsyntaxhighlight>
{{Out}}
<langsyntaxhighlight AppleScriptlang="applescript">{-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20}</langsyntaxhighlight>
----
 
===Idiomatic===
 
<syntaxhighlight lang="applescript">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)</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">{-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20}</syntaxhighlight>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">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}</syntaxhighlight>
 
{{out}}
 
<pre>-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">msgbox % expand("-6,-3--1,3-5,7-11,14,15,17-20")
 
expand( range ) {
Line 496 ⟶ 718:
ret .= "," (A_Index-1) + f1
return SubStr(ret, 2)
}</langsyntaxhighlight>
 
=={{header|AWK}}==
 
<langsyntaxhighlight lang="awk">#!/usr/bin/awk -f
BEGIN { FS=","; }
 
Line 521 ⟶ 743:
}
return;
} </langsyntaxhighlight>
 
<pre>
Line 530 ⟶ 752:
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> PRINT FNrangeexpand("-6,-3--1,3-5,7-11,14,15,17-20")
END
Line 552 ⟶ 774:
ENDIF
UNTIL i% = 0
= r$</langsyntaxhighlight>
{{out}}
<pre>
Line 559 ⟶ 781:
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat"> ( expandRanges
= a b L
. @( !arg
Line 574 ⟶ 796:
)
& out$(str$(expandRanges$"-6,-3--1,3-5,7-11,14,15,17-20"))
</syntaxhighlight>
</lang>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20</pre>
Line 580 ⟶ 802:
=={{header|C}}==
Recursive descent parser.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
Line 657 ⟶ 879:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20
Line 666 ⟶ 888:
=={{header|C sharp|C#}}==
{{works with|C sharp|3.0}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 695 ⟶ 917:
Console.WriteLine(string.Join(", ", values));
}
}</langsyntaxhighlight>
 
{{works with|C sharp|3.5+}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 728 ⟶ 950:
}
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <sstream>
#include <iterator>
Line 804 ⟶ 1,026:
else
std::cout << "an error occured.";
}</langsyntaxhighlight>
{{out}}
-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20
Line 810 ⟶ 1,032:
=={{header|Clojure}}==
There is a split method in clojure.contrib, but I don't know if it is able to skip first character to so that <code>(split "-8--8") => (-8 -8)</code>.
<langsyntaxhighlight lang="clojure">(defn split [s sep]
(defn skipFirst [[x & xs :as s]]
(cond (empty? s) [nil nil]
Line 833 ⟶ 1,055:
 
> (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)</langsyntaxhighlight>
 
=={{header|COBOL}}==
{{works with|GNU Cobol|2.0}}
<langsyntaxhighlight lang="cobol"> >>SOURCE FREE
IDENTIFICATION DIVISION.
PROGRAM-ID. expand-range.
Line 929 ⟶ 1,151:
END-IF
.
END PROGRAM display-edited-num.</langsyntaxhighlight>
 
Setup:
Line 943 ⟶ 1,165:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun expand-ranges (string)
(loop
with prevnum = nil
Line 965 ⟶ 1,187:
 
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)</langsyntaxhighlight>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">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</syntaxhighlight>
 
{{out}}
 
<pre>-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
-6-3--1,3-5,7-11,14,15,17-20
>> error at: 3--1,3-5,7-11,14,15,17-20
-6,-3--1,5-3,7-11,14,15,17-20
>> error at: 3,7-11,14,15,17-20</pre>
 
=={{header|Crystal}}==
{{trans|Ruby}}
<syntaxhighlight lang="crystal">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")</syntaxhighlight>
{{out}}
<pre>[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]</pre>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.regex, std.conv, std.range, std.algorithm;
 
enum rangeEx = (string s) /*pure*/ => s.matchAll(`(-?\d+)-?(-?\d+)?,?`)
Line 975 ⟶ 1,319:
void main() {
"-6,-3--1,3-5,7-11,14,15,17-20".rangeEx.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
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.</syntaxhighlight>
 
 
=={{header|DWScript}}==
<langsyntaxhighlight lang="pascal">
function ExpandRanges(ranges : String) : array of Integer;
begin
Line 996 ⟶ 1,415:
var expanded := ExpandRanges('-6,-3--1,3-5,7-11,14,15,17-20');
PrintLn(JSON.Stringify(expanded));
</syntaxhighlight>
</lang>
{{out}}
<pre>[-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20]</pre>
 
=={{header|Dyalect}}==
 
{{trans|Go}}
 
<syntaxhighlight lang="dyalect">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()</syntaxhighlight>
 
{{out}}
 
<pre>range: -6,-3--1,3-5,7-11,14,15,17-20
expanded: [-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]</pre>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; parsing [spaces][-]digit(s)-[-]digit(s)[spaces]
(define R (make-regexp "^ *(\-?\\d+)\-(\-?\\d+) *$" ))
Line 1,027 ⟶ 1,492:
(ranges task)
→ (-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20)
</syntaxhighlight>
</lang>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule RC do
def expansion(range) do
Enum.flat_map(String.split(range, ","), fn part ->
Line 1,042 ⟶ 1,507:
end
 
IO.inspect RC.expansion("-6,-3--1,3-5,7-11,14,15,17-20")</langsyntaxhighlight>
 
{{out}}
Line 1,050 ⟶ 1,515:
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( range ).
 
Line 1,065 ⟶ 1,530:
expansion_individual( {ok, [N], []} ) -> N;
expansion_individual( {ok, [Start], "-" ++ Stop_string} ) -> lists:seq( Start, erlang:list_to_integer(Stop_string) ).
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,074 ⟶ 1,539:
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">open System.Text.RegularExpressions
 
// simplify regex matching with an active pattern
Line 1,096 ⟶ 1,561:
|> List.collect parseRange
 
printfn "%A" (expand "-6,-3--1,3-5,7-11,14,15,17-20")</langsyntaxhighlight>
{{out}}
<pre>[-6; -3; -2; -1; 3; 4; 5; 7; 8; 9; 10; 11; 14; 15; 17; 18; 19; 20]</pre>
Line 1,102 ⟶ 1,567:
=={{header|Factor}}==
<code>R/ (?<=\d)-/ re-split</code> says: ''split only on hyphens immediately preceded by a digit.''
<langsyntaxhighlight lang="factor">USING: kernel math.parser math.ranges prettyprint regexp
sequences sequences.extras splitting ;
 
Line 1,111 ⟶ 1,576:
] map-concat ;
 
"-6,-3--1,3-5,7-11,14,15,17-20" expand .</langsyntaxhighlight>
{{out}}
<pre>
Line 1,118 ⟶ 1,583:
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: >snumber ( str len -- 'str 'len n )
0. 2swap
over c@ [char] - = if
Line 1,142 ⟶ 1,607:
repeat 2drop ;
 
s" -6,-3--1,3-5,7-11,14,15,17-20" expand</langsyntaxhighlight>
 
=={{header|Fortran}}==
Line 1,153 ⟶ 1,618:
A frustrating problem with many modern computer languages is the absence of a "shortcut" evaluation praxis for logical expressions; in Fortran's case the modern standard is that there is no standard. So a test <code>I<=LEN(TEXT) & TEXT(I:I)''etc.''</code> can't be relied upon to dodge out-of-bounds errors, and a flabby two-statement sequence is required instead. Similarly, few Fortran compilers allow for a function being evaluated via a WRITE statement to itself succeed in using a WRITE statement internally, though some do if one usage is free-format and the other formatted. If necessary, subroutine SPLOT could be re-written to convert an integer to a digit string without a WRITE statement, even for negative integers. And some compilers have difficulty with the use of the function name as a variable within the function so that it is safest to develop the result in an ordinary variable and then remember to assign its value to the function name just before exit.
 
A single number is made internally into a two-number range sequence, which values are used as the bounds for a DO-loop to generate the numbers for output. Despite the '''The range syntax is to be used only for, and for every range that expands to more than two values''', I see no reason for this restriction (say because otherwise some fancy method would be stymied, except I can think of no such fancier method) and I have no desire to interpose some sort of error message, a tedious business that requires a wider interface between a routine and its caller. Similarly, if a range of 40-30 were to appear, why not take it at face value? <langsyntaxhighlight Fortranlang="fortran"> MODULE HOMEONTHERANGE
CONTAINS !The key function.
CHARACTER*200 FUNCTION ERANGE(TEXT) !Expands integer ranges in a list.
Line 1,252 ⟶ 1,717:
SOME = ERANGE(SOME)
WRITE (6,*) SOME !If ERANGE(SOME) then the function usually can't write output also.
END</langsyntaxhighlight>
 
Output: <pre> -6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20</pre>
Line 1,259 ⟶ 1,724:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Sub split (s As Const String, sepList As Const String, result() As String)
Line 1,333 ⟶ 1,798:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
{{out}}
Line 1,342 ⟶ 1,807:
=={{header|Go}}==
A version rather strict with input
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,405 ⟶ 1,870:
}
fmt.Println("expanded:", r)
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
Line 1,415 ⟶ 1,880:
# express as a string
# unwrap the list delimiters
<langsyntaxhighlight lang="groovy">def expandRanges = { compressed ->
Eval.me('['+compressed.replaceAll(~/(\d)-/, '$1..')+']').flatten().toString()[1..-2]
}</langsyntaxhighlight>
Test:
<langsyntaxhighlight lang="groovy">def s = '-6,-3--1,3-5,7-11,14,15,17-20'
println (expandRanges(s))</langsyntaxhighlight>
{{out}}
<pre>-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20</pre>
Line 1,426 ⟶ 1,891:
=={{header|Haskell}}==
Given either of the below implementations of <code>expandRange</code>:
<langsyntaxhighlight lang="haskell">> 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]</langsyntaxhighlight>
===With conventional list processing===
<langsyntaxhighlight lang="haskell">expandRange :: String -> [Int]
expandRange = concatMap f . split ','
where f str@(c : cs) | '-' `elem` cs = [read (c : a) .. read b]
Line 1,438 ⟶ 1,903:
split delim [] = []
split delim l = a : split delim (dropWhile (== delim) b)
where (a, b) = break (== delim) l</langsyntaxhighlight>
===With a parser===
<langsyntaxhighlight lang="haskell">{-# LANGUAGE FlexibleContexts #-}
 
import Control.Applicative (Applicative((<*>), (*>)), (<$>))
import Text.Parsec
 
expandRange :: String -> Maybe [Int]
expandRange = either (const Nothing) Just . parse rangeParser ""
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
Line 1,457 ⟶ 1,925:
n2 <- option n1 (char '-' *> num)
return [n1 .. n2]
num =
num = read `dot` (++) <$> option "" (string "-") <*> many1 digit
read `dot` (<>) <$> option "" (string "-")
<*> many1 digit
dot = (.) . (.)
 
main :: IO ()
main = print $ expandRange "-6,-3--1,3-5,7-11,14,15,17-20"</langsyntaxhighlight>
{{Out}}
<pre>Just [-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20]</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main()
s := "-6,-3--1,3-5,7-11,14,15,17-20"
write("Input string := ",s)
Line 1,490 ⟶ 1,960:
every (s := "[ ") ||:= !L || " "
return s || "]"
end</langsyntaxhighlight>
{{out}}
<pre>Input string := -6,-3--1,3-5,7-11,14,15,17-20
Line 1,496 ⟶ 1,966:
 
=={{header|J}}==
<langsyntaxhighlight lang="j">require'strings'
thru=: <. + i.@(+*)@-~
num=: _&".
normaliz=: rplc&(',-';',_';'--';'-_')@,~&','
subranges=:<@(thru/)@(num;._2)@,&'-';._1
rngexp=: ;@subranges@normaliz</langsyntaxhighlight>
{{out|Example}}
<langsyntaxhighlight lang="j"> 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</langsyntaxhighlight>
 
Notes:
Line 1,521 ⟶ 1,991:
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.util.*;
 
class RangeExpander implements Iterator<Integer>, Iterable<Integer> {
Line 1,585 ⟶ 2,055:
}
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
Line 1,591 ⟶ 2,061:
===Imperative (Spidermonkey)===
 
<langsyntaxhighlight lang="javascript">#!/usr/bin/env js
 
function main() {
Line 1,625 ⟶ 2,095:
 
main();
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,634 ⟶ 2,104:
====ES5====
 
<langsyntaxhighlight JavaScriptlang="javascript">(function (strTest) {
'use strict';
 
Line 1,672 ⟶ 2,142:
return expansion(strTest);
 
})('-6,-3--1,3-5,7-11,14,15,17-20');</langsyntaxhighlight>
 
{{Out}}
 
<langsyntaxhighlight JavaScriptlang="javascript">[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]</langsyntaxhighlight>
 
 
====ES6====
<syntaxhighlight lang="javascript">(() => {
"use strict";
 
// ----------------- RANGE EXPANSION -----------------
<lang JavaScript>(strTest => {
// expansion :: String -> [Int]
let expansion = strExpr =>
 
// rangeExpansion :: String -> [Int]
// concat map yields flattened output list
const rangeExpansion = rangeString =>
[].concat.apply([], strExpr.split(',')
// A list of .map(xintegers =>parsed x.split('-')from a
// comma-delimited string which may include
.reduce((a, s, i, l) =>
// (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 ? (
// negative (after item 0) if preceded by an empty string
// uncurry(i.e. a hyphen-split artefact, otherwise ignoredenumFromTo)(ns)
) : s.length ? i ? a.concat(ns;
});
parseInt(l[i - 1].length ? s :
'-' + s, 10)
) : [+s] : a, [])
 
// two-number lists are interpreted as ranges
)
.map(r => r.length > 1 ? range.apply(null, r) : r)),
 
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () =>
rangeExpansion("-6,-3--1,3-5,7-11,14,15,17-20");
 
 
// --------------------- GENERIC ---------------------
// range :: Int -> Int -> Maybe Int -> [Int]
range = (m, n, step) => {
let d = (step || 1) * (n >= m ? 1 : -1);
 
// enumFromTo :: Int -> Int -> [Int]
return Array.from({
const enumFromTo = m =>
length: Math.floor((n - m) / d) + 1
}, (_, i)n => m + Array.from(i * d));{
}; 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 expansionf(x)(strTesty);
};
 
})('-6,-3--1,3-5,7-11,14,15,17-20');</lang>
 
// MAIN ---
return JSON.stringify(main());
})();</syntaxhighlight>
{{Out}}
<lang JavaScriptpre>[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]</langpre>
 
=={{header|jq}}==
{{works with|jq|with regex support}}
<langsyntaxhighlight lang="jq">def expand_range:
def number: "-?[0-9]+";
def expand: [range(.[0]; .[1] + 1)];
Line 1,734 ⟶ 2,229:
else sub( "(?<x>\(number))-(?<y>\(number))"; "\(.x):\(.y)")
| split(":") | map(tonumber) | expand
end));</langsyntaxhighlight>
'''Example''':
<langsyntaxhighlight lang="jq">"-6,-3--1,3-5,7-11,14,15,17-20" | expand_range</langsyntaxhighlight>
{{out}}$ jq -c -n -f Range_expansion.jq
[-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20]
 
=={{header|Jsish}}==
{{trans|Javascript}}
<syntaxhighlight lang="javascript">#!/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!=
*/</syntaxhighlight>
 
{{out}}
<pre>prompt$ jsish --U rangeExpansion.jsi
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 ]</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight Julialang="julia">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))</langsyntaxhighlight>
{{out}}
<pre>julia> show(expand("-6,-3--1,3-5,7-11,14,15,17-20"))
Line 1,751 ⟶ 2,293:
 
=={{header|K}}==
<langsyntaxhighlight lang="k">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}</langsyntaxhighlight>
{{out|Example}}
<langsyntaxhighlight lang="k"> 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</langsyntaxhighlight>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun expandRange(s: String): MutableList<Int> {
Line 1,795 ⟶ 2,337:
val s = "-6,-3--1,3-5,7-11,14,15,17-20"
println(expandRange(s))
}</langsyntaxhighlight>
 
{{out}}
Line 1,803 ⟶ 2,345:
 
=={{header|Lasso}}==
<langsyntaxhighlight lang="lasso">define range_expand(expression::string) => {
local(parts) = regexp(`^(-?\d+)-(-?\d+)$`)
Line 1,815 ⟶ 2,357:
}
 
range_expand(`-6,-3--1,3-5,7-11,14,15,17-20`)</langsyntaxhighlight>
 
{{out}}
<pre>-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20</pre>
 
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">print ExpandRange$( "-6,-3--1,3-5,7-11,14,15,17-20")
end
 
Line 1,844 ⟶ 2,385:
ItemCount = ItemCount + 1
wend
end function</langsyntaxhighlight>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20</pre>
 
=={{header|Lingo}}==
<langsyntaxhighlight lang="lingo">-- Note: currently does not support extra white space in input string
on expandRange (str)
res = ""
Line 1,869 ⟶ 2,410:
delete the last char of res
return res
end</langsyntaxhighlight>
<langsyntaxhighlight lang="lingo">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"</langsyntaxhighlight>
 
=={{header|LiveCode}}==
<langsyntaxhighlight LiveCodelang="livecode">function range beginning ending stepping
local tRange, tBegin, tEnd, tstep
if stepping is empty or stepping is 0 then
Line 1,911 ⟶ 2,452:
end repeat
return z
end expandRange</langsyntaxhighlight>
 
Test
<langsyntaxhighlight LiveCodelang="livecode">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 </langsyntaxhighlight>
 
=={{header|Lua}}==
 
<langsyntaxhighlight lang="lua">function range(i, j)
local t = {}
for n = i, j, i<j and 1 or -1 do
Line 1,946 ⟶ 2,487:
 
local ranges = "-6,-3--1,3-5,7-11,14,15,17-20"
print(table.concat(expand_ranges(ranges), ', '))</langsyntaxhighlight>
 
Due to the way Lua's <code>tonumber</code> function works and the way the string pattern to parse ranges is written, whitespace is allowed around commas and the dash separating the range start and end (but not between the plus/minus sign and the number).
Line 1,956 ⟶ 2,497:
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
ExpandRanges := proc( s :: string )
uses StringTools;
Line 1,994 ⟶ 2,535:
map( DoOne, map( Trim, Split( s, "," ) ) )
end proc:
</syntaxhighlight>
</lang>
Running this on the example input we get the following.
<syntaxhighlight lang="maple">
<lang Maple>
> 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]
</syntaxhighlight>
</lang>
Here is an additional example which my first attempt got wrong.
<syntaxhighlight lang="maple">
<lang Maple>
> 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]
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">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<>"]"] ]</langsyntaxhighlight>
{{out|Example}}
<pre>rangeexpand["-6,-3--1,3-5,7-11,14,15,17-20"]
Line 2,017 ⟶ 2,558:
 
=={{header|MATLAB}} / {{header|Octave}}==
<langsyntaxhighlight MATLABlang="matlab">function L=range_expansion(S)
% Range expansion
if nargin < 1;
Line 2,029 ⟶ 2,570:
S(ixr)=':';
S=['[',S,']'];
L=eval(S);</langsyntaxhighlight>
Usage:
<pre>
Line 2,037 ⟶ 2,578:
 
</pre>
 
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">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")</syntaxhighlight>
{{out}}
<pre>[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]</pre>
 
=={{header|MUMPS}}==
<langsyntaxhighlight MUMPSlang="mumps">RANGEXP(X) ;Integer range expansion
NEW Y,I,J,X1,H SET Y=""
FOR I=1:1:$LENGTH(X,",") DO
Line 2,048 ⟶ 2,617:
.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</langsyntaxhighlight>
{{out|Example}}
<pre>USER>SET U="-6,-3--1,3-5,7-11,14,15,17-20"
Line 2,057 ⟶ 2,626:
=={{header|NetRexx}}==
Translation of: [[Range_expansion#Version_2_somewhat_simplified_.21.3F.21|Rexx Version 2]]
<langsyntaxhighlight NetRexxlang="netrexx">/*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(' ',',')
Line 2,091 ⟶ 2,660:
End
Say 'new='new /*show the expanded list */
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,099 ⟶ 2,668:
 
=={{header|Nim}}==
<syntaxhighlight lang ="nim">import parseutils, re, strutils
 
proc expandRange(input: string): string =
var output: seq[string] = @[]
for range in input.split(','):
var sep = range.find('-', 1)
Line 2,122 ⟶ 2,691:
return output.join(",")
 
echo("-6,-3--1,3-5,7-11,14,15,17-20".expandRange)</langsyntaxhighlight>
 
{{out}}
Line 2,129 ⟶ 2,698:
=={{header|Oberon-2}}==
Oxford Oberon-2
<langsyntaxhighlight lang="oberon2">
MODULE LIVector;
IMPORT SYSTEM;
Line 2,366 ⟶ 2,935:
END ExpandRange.
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,373 ⟶ 2,942:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">#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
Line 2,395 ⟶ 2,964:
let exp = range_expand rng in
List.iter (Printf.printf " %d") exp;
print_newline ()</langsyntaxhighlight>
 
=={{header|Oforth}}==
<langsyntaxhighlight lang="oforth">: addRange( s res -- )
| i n |
s asInteger dup ifNotNull: [ res add return ] drop
Line 2,407 ⟶ 2,976:
 
: rangeExpand ( s -- [ n ] )
ArrayBuffer new s wordsWith( ',' ) apply( #[ over addRange ] ) ;</langsyntaxhighlight>
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
list = '-6,-3--1,3-5,7-11,14,15,17-20'
expanded = expandRanges(list)
Line 2,441 ⟶ 3,010:
end
return expanded
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,449 ⟶ 3,018:
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
fun {Expand RangeDesc}
{Flatten
Line 2,478 ⟶ 3,047:
in
{System.showInfo
{Value.toVirtualString {Expand "-6,-3--1,3-5,7-11,14,15,17-20"} 100 100}}</langsyntaxhighlight>
{{out|Sample output}}
<langsyntaxhighlight lang="oz">[~6 ~3 ~2 ~1 3 4 5 7 8 9 10 11 14 15 17 18 19 20]</langsyntaxhighlight>
 
=={{header|Perl}}==
One-liner:
<langsyntaxhighlight Perllang="perl">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";</langsyntaxhighlight>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20</pre>
 
Alternative:
<langsyntaxhighlight Perllang="perl">sub rangex {
(my $range = shift) =~ s/(?<=\d)-/../g;
eval $range;
}</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
<!--<syntaxhighlight lang="phix">(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>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{-6,-3,-2,-1,0,1,3,4,5,7,8,9,10,11,14,15,17,18,19,20}
{-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20}
</pre>
 
=={{header|Phixmonti}}==
{{works with|Rakudo|2016.07}}
Require Phixmonti 1.1
<lang Perl6>sub range-expand (Str $range-description) {
<syntaxhighlight lang="phixmonti">0 tolist var r
my token number { '-'? \d+ }
my token range { (<&number>) '-' (<&number>) }
$range-description
.split(',')
.map({ .match(&range) ?? $0..$1 !! +$_ })
.flat
}
say range-expand('-6,-3--1,3-5,7-11,14,15,17-20').join(', ');</lang>
 
def append
{{out}}
r swap 0 put var r
<pre>-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20</pre>
enddef
 
"-6,-3--1,3-5,7-11,14,15,17-20" "," " " subst split
<br>
Alternatively, using a grammar:
 
len for
<lang perl6>grammar RangeList {
get dup tonum dup
token TOP { <term>* % ',' { make $<term>.map(*.made) } }
nan == if
token term { [<range>|<num>] { make ($<num> // $<range>).made } }
drop
token range { <num> '-' <num> { make +$<num>[0] .. +$<num>[1] } }
dup len 1 - 2 swap slice
token num { '-'? \d+ { make +$/ } }
"-" 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</syntaxhighlight>
 
Other solution
say RangeList.parse('-6,-3--1,3-5,7-11,14,15,17-20').made.flat.join(', ');</lang>
<syntaxhighlight lang="phixmonti">0 tolist var r
 
def append
{{out}}
r swap 0 put var r
<pre>-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20</pre>
enddef
 
"-6,-3--1,3-5,7-11,14,15,17-20" "," " " subst split
=={{header|Phix}}==
<lang Phix>function range_expansion(string range)
sequence s = split(range,','),
res = {}
for i=1 to length(s) do
string si = s[i]
integer k = find('-',si,2)
if k=0 then
res = append(res,to_number(si))
else
integer startrange = to_number(si[1..k-1])
integer endofrange = to_number(si[k+1..$])
for l=startrange to endofrange do
res = append(res,l)
end for
end if
end for
return res
end function
 
len for
?range_expansion("-6,-3-1,3-5,7-11,14,15,17-20")
get dup tonum dup
?range_expansion("-6,-3--1,3-5,7-11,14,15,17-20")</lang>
nan == if
{{out}}
drop
<pre>
dup 32 1 set
{-6,-3,-2,-1,0,1,3,4,5,7,8,9,10,11,14,15,17,18,19,20}
"-" find nip
{-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20}
swap over 1 - 1 swap slice tonum
</pre>
rot rot len rot swap over - swap 1 + swap slice tonum
nip 2 tolist for append endfor
else
append drop
endif
endfor
r
pstack</syntaxhighlight>
 
A bit more understandable
<syntaxhighlight lang="phixmonti">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</syntaxhighlight>
 
=={{header|PHP}}==
{{trans|Python}}
<langsyntaxhighlight PHPlang="php">function rangex($str) {
$lst = array();
foreach (explode(',', $str) as $e) {
Line 2,573 ⟶ 3,204:
}
return $lst;
}</langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de rangeexpand (Str)
(make
(for S (split (chop Str) ",")
Line 2,584 ⟶ 3,215:
(format (head @ S))
(format (tail (- -1 @) S)) ) )
(link (format S)) ) ) ) )</langsyntaxhighlight>
{{out}}
<pre>: (rangeexpand "-6,-3--1,3-5,7-11,14,15,17-20")
Line 2,590 ⟶ 3,221:
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">range_expansion:
procedure options (main);
 
Line 2,640 ⟶ 3,271:
delimiter = ',';
end;
end range_expansion;</langsyntaxhighlight>
{{out}}
<pre>
Line 2,647 ⟶ 3,278:
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function range-expansion($array) {
function expansion($arr) {
Line 2,670 ⟶ 3,301:
}
range-expansion "-6,-3--1,3-5,7-11,14,15,17-20"
</syntaxhighlight>
</lang>
<b>Output:</b>
<pre>
Line 2,678 ⟶ 3,309:
===Alternate Half-Assed Regex Version===
Ten times faster (only minimally tested).
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Expand-Range
{
Line 2,721 ⟶ 3,352:
$output
}
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
(Expand-Range "-6,-3--1,3-5,7-11,14,15,17-20") -join ", "
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,735 ⟶ 3,366:
The code uses three predicates '''extract_Range/2''', '''study_Range/2''' and '''pack_Range/2'''.<BR>
Every predicate works in both directions arg1 towards arg2 and arg2 towards arg1, so that '''Range expansion''' and '''Range extraction''' work with the same predicates but in reverse order.
<langsyntaxhighlight Prologlang="prolog">range_expand :-
L = '-6,-3--1,3-5,7-11,14,15,17-20',
writeln(L),
Line 2,815 ⟶ 3,446:
run(Var1,LRest,[Deb, Fin], RRest).
 
run(Val,[Other|RRest], [Val, Val],[Other|RRest]).</langsyntaxhighlight>
{{out}}
<pre> ?- range_expand.
Line 2,823 ⟶ 3,454:
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">Procedure rangeexpand(txt.s, List outputList())
Protected rangesCount = CountString(txt, ",") + 1
Protected subTxt.s, r, rangeMarker, rangeStart, rangeFinish, rangeIncrement, i
Line 2,868 ⟶ 3,499:
Input()
CloseConsole()
EndIf</langsyntaxhighlight>
{{out}}
<pre>[ -6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20 ]</pre>
 
=={{header|Python}}==
===Procedural===
<lang python>def rangeexpand(txt):
<syntaxhighlight lang="python">def rangeexpand(txt):
lst = []
for r in txt.split(','):
Line 2,883 ⟶ 3,515:
return lst
 
print(rangeexpand('-6,-3--1,3-5,7-11,14,15,17-20'))</langsyntaxhighlight>
 
another variant, using [[regular expressions]] to parse the ranges,
<langsyntaxhighlight lang="python">import re
 
def rangeexpand(txt):
Line 2,896 ⟶ 3,528:
else:
lst.append(int(start))
return lst</langsyntaxhighlight>
 
===Functional===
and a functional version, assembled from a set of curried generics.
As a fold/catamorphism:
<lang python>from functools import (reduce)
{{Works with|Python|3.7}}
<syntaxhighlight lang="python">'''Range expansion'''
 
from functools import (reduce)
 
 
# rangeExpand :: String -> [Int]
# ------------------- EXPANSION FUNCTION -------------------
def rangeExpand(s):
 
return (
# rangeExpansion :: String -> [Int]
foldl(lambda a: lambda x: (
def rangeExpansion(s):
(lambda tpl=breakOn('-')(x[1:]): (
'''List of integers expanded from a
a + (lambda r=tpl[1]: (
comma-delimited string of individual
[int(x)] if not r
numbers and hyphenated ranges.
else enumFromTo
'''
(int(x[0] + tpl[0]))
def go(a, x):
(int(r[1:]))
tpl = )breakOn('-')(x[1:])
r = ))()tpl[1]
))return a + (
( []int(x)] if not r
else enumFromTo(s.splitint(','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 ------------------- GENERIC FUNCTIONS --------------------
 
# breakOn :: String -> String -> (String, String)
def breakOn(patneedle):
return'''A (lambdatuple srcof: (
1. the prefix of haystack before needle,
lambda xs=src.split(pat): (
2. the remainder of (xs[0]haystack, src[len(xs[0]):])starting
with if 1 < len(xs) else (src, '')needle.
)'''
def go(haystack):
)()) if 0 < len(pat) else None
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))
 
 
# foldlfTable :: (aString -> b(a -> aString) -> a -> [b] -> a
# (b -> String) -> (a -> b) -> [a] -> String
def foldl(f):
def fTable(s):
return lambda a: lambda xs: (
'''Heading -> x display function ->
reduce(uncurry(f), xs, a)
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
 
# uncurry :: (a -> b -> c) -> ((a, b) -> c)
def uncurry(f):
def g(x, y):
return f(x)(y)
return g
 
# showList :: [a] -> String
def showList(xs):
'''Stringification of a list.
'''
return '[' + ','.join(str(x) for x in xs) + ']'
 
# MAIN ----------------------------------------------------
def main():
print(
rangeExpand('-6,-3--1,3-5,7-11,14,15,17-20')
)
 
# MAIN ---
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>Range expansion:
 
'-6,-3--1,3-5,7-11,14,15,17-20' ->
main()</lang>
 
{{out}}
<pre> [-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]</pre>
 
=={{header|R}}==
<syntaxhighlight lang="r">
<lang R>
rangeExpand <- function(text) {
lst <- gsub("(\\d)-", "\\1:", unlist(strsplit(text, ",")))
Line 2,971 ⟶ 3,651:
rangeExpand("-6,-3--1,3-5,7-11,14,15,17-20")
[1] -6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 2,988 ⟶ 3,668:
 
(range-expand "-6,-3--1,3-5,7-11,14,15,17-20")
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,999 ⟶ 3,679:
rather than 3 followed by - followed by -4,
a readtable is installed that makes - a delimiter.
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 3,026 ⟶ 3,706:
(range-expand (open-input-string "-6,-3--1,3-5,7-11,14,15,17-20"))
</syntaxhighlight>
</lang>
Note that one can use the full number syntax in this alternative version:
<pre>
Line 3,032 ⟶ 3,712:
'(1 2 30.0 31.0 32.0)
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
 
{{works with|Rakudo|2016.07}}
<syntaxhighlight lang="raku" line>sub range-expand (Str $range-description) {
my token number { '-'? \d+ }
my token range { (<&number>) '-' (<&number>) }
$range-description
.split(',')
.map({ .match(&range) ?? $0..$1 !! +$_ })
.flat
}
say range-expand('-6,-3--1,3-5,7-11,14,15,17-20').join(', ');</syntaxhighlight>
 
{{out}}
<pre>-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20</pre>
 
<br>
Alternatively, using a grammar:
 
<syntaxhighlight lang="raku" line>grammar RangeList {
token TOP { <term>* % ',' { make $<term>.map(*.made) } }
token term { [<range>|<num>] { make ($<num> // $<range>).made } }
token range { <num> '-' <num> { make +$<num>[0] .. +$<num>[1] } }
token num { '-'? \d+ { make +$/ } }
}
 
say RangeList.parse('-6,-3--1,3-5,7-11,14,15,17-20').made.flat.join(', ');</syntaxhighlight>
 
{{out}}
<pre>-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20</pre>
 
=={{header|Raven}}==
Based loosely on Ruby
<langsyntaxhighlight lang="raven">define get_num use $lst
# "-22" split by "-" is [ "", "22" ] so check if
# first list item is "" -> a negative number
Line 3,067 ⟶ 3,781:
"\n" print
 
'-6,-3--1,3-5,7-11,14,15,17-20' range_expand</langsyntaxhighlight>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20</pre>
Line 3,074 ⟶ 3,788:
===version 1===
Extra imbedded blanks were added to the &nbsp; old &nbsp; list (which are ignored) to make the &nbsp; ''over/under'' &nbsp; comparison easier &nbsp; (in the output).
<langsyntaxhighlight lang="rexx">/*REXX program expands an ordered list of integers into an expanded list. */
old= '-6,-3--1, 3-5, 7-11, 14,15,17-20'; a=translate(old,,',')
new= /*translate [↑] commas (,) ───► blanks*/
Line 3,086 ⟶ 3,800:
new=translate( strip(new), ',', " ") /*remove the first blank, add commas. */
say 'old list: ' old /*show the old list of numbers/ranges.*/
say 'new list: ' new /* " " new " " numbers. */</langsyntaxhighlight>
'''output'''
<pre>
Line 3,094 ⟶ 3,808:
 
===Version 2 somewhat simplified !?!===
<langsyntaxhighlight lang="rexx">/*REXX program to expand a range of integers into a list. *************
* 09.08.2012 Walter Pachl
**********************************************************************/
Line 3,122 ⟶ 3,836:
End
End
Say 'new='new /*show the expanded list */</langsyntaxhighlight>
{{out}}
<pre>
Line 3,130 ⟶ 3,844:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Range expansion
 
Line 3,172 ⟶ 3,886:
see svect
see "]" + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 3,179 ⟶ 3,893:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def range_expand(rng)
rng.split(',').flat_map do |part|
if part =~ /^(-?\d+)-(-?\d+)$/
Line 3,189 ⟶ 3,903:
end
 
p range_expand('-6,-3--1,3-5,7-11,14,15,17-20')</langsyntaxhighlight>
{{out}}
<pre>[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]</pre>
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">PRINT rangeExpand$("-6,-3--1,3-5,7-11,14,15,17-20")
end
 
Line 3,218 ⟶ 3,932:
if i <> 0 then goto [loop]
rangeExpand$ = range$
end function</langsyntaxhighlight>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20</pre>
Line 3,225 ⟶ 3,939:
Rust doesn't have regex in standard library yet.
 
<langsyntaxhighlight lang="rust">use std::str::FromStr;
 
// Precondition: range doesn't contain multibyte UTF-8 characters
Line 3,251 ⟶ 3,965:
println!("{:?}", range_expand("-6,-3--1,3-5,7-11,14,15,17-20"));
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,259 ⟶ 3,973:
 
=={{header|S-lang}}==
<langsyntaxhighlight Slang="s-lang">variable r_expres = "-6,-3--1,3-5,7-11,14,15,17-20", s, r_expan = {}, dpos, i;
 
foreach s (strchop(r_expres, ',', 0))
Line 3,277 ⟶ 3,991:
list_append(r_expan, s);
}
print(strjoin(list_to_array(r_expan), ", "));</langsyntaxhighlight>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">def rangex(str: String): Seq[Int] =
str split "," flatMap { (s) =>
val r = """(-?\d+)(?:-(-?\d+))?""".r
val r(a,b) = s
if (b == null) Seq(a.toInt) else a.toInt to b.toInt
}</langsyntaxhighlight>
 
{{out}}
Line 3,294 ⟶ 4,008:
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">(define split
(lambda (str char skip count)
(let ((len (string-length str)))
Line 3,328 ⟶ 4,042:
(display ","))))))
(split str #\, 0 0))
(newline)))</langsyntaxhighlight>
{{out}}
<pre>
Line 3,338 ⟶ 4,052:
The library [http://seed7.sourceforge.net/libraries/scanstri.htm scanstri.s7i] defines the function [http://seed7.sourceforge.net/libraries/scanstri.htm#getInteger%28inout_string%29 getInteger] to extract substrings with integer literals (optional sign followed by a sequence of digits) from a string.
The integer literals are converted to the type [http://seed7.sourceforge.net/libraries/integer.htm integer] with the [http://seed7.sourceforge.net/libraries/integer.htm#%28attr_integer%29parse%28in_string%29 parse] operator.
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "scanstri.s7i";
 
Line 3,372 ⟶ 4,086:
end for;
writeln;
end func;</langsyntaxhighlight>
{{out}}
<pre>
Line 3,379 ⟶ 4,093:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func rangex(str) {
str.split(',').map { |r|
var m = r.match(/^
Line 3,390 ⟶ 4,104:
}
 
say rangex('-6,-3--1,3-5,7-11,14,15,17-20').join(',')</langsyntaxhighlight>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20</pre>
 
=={{header|SNOBOL4}}==
<langsyntaxhighlight SNOBOL4lang="snobol4">* # Return range n1 .. n2
define('range(n1,n2)') :(range_end)
range range = range n1 ','; n1 = lt(n1,n2) n1 + 1 :s(range)
Line 3,409 ⟶ 4,123:
* # Test and display
output = rangex('-6,-3--1,3-5,7-11,14,15,17-20')
end</langsyntaxhighlight>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20</pre>
=={{header|SQL}}==
{{works with|ORACLE 19c}}
This is not a particularly efficient solution, but it gets the job done.
 
<syntaxhighlight lang="sql">
/*
This code is an implementation of "Range expansion" in SQL ORACLE 19c
p_list_of_sets -- input string
delimeter by default ","
*/
with
function range_expansion(p_list_of_sets in varchar2)
return varchar2 is
--
v_list_of_sets varchar2(32767) := p_list_of_sets;
v_output varchar2(32767) ;
v_set_1 varchar2(2000) ;
v_set_1_min pls_integer;
v_set_1_max pls_integer;
--
function sort_set(p_in_str varchar2)
return varchar2 is
v_out varchar2(32767) := p_in_str;
begin
--
with out_tab as
(select to_number(regexp_substr(str, '[^,]+', 1, rownum, 'c', 0) default null on conversion error) elem
from
(select p_in_str as str
from dual
)
connect by level <= regexp_count(str, '[^,]+')
)
select trim(both ',' from min(elem)||','||max(elem)) end
into v_out
from out_tab;
--
return v_out;
end;
--
function sort_output(p_in_str varchar2)
return varchar2 is
v_out varchar2(32767) := p_in_str;
begin
--
with out_tab as
(select distinct to_number(regexp_substr(str, '[^,]+', 1, rownum, 'c', 0) default null on conversion error) elem
from
(select p_in_str as str
from dual
)
connect by level <= regexp_count(str, '[^,]+')
)
select listagg(elem, ',') within group(order by elem) end
into v_out
from out_tab
where elem is not null;
--
return v_out;
end;
--
begin
--cleaning
v_list_of_sets := replace(v_list_of_sets, ' ', '') ;
v_list_of_sets := replace(v_list_of_sets, '+', '') ;
v_list_of_sets := replace(v_list_of_sets, ',', '|') ;
v_list_of_sets := regexp_replace(v_list_of_sets, '(\d{1,})-(\d{1,})', '\1,\2', 1, 0) ;
v_list_of_sets := regexp_replace(v_list_of_sets, '(\d{1,})--(\d{1,})', '\1,-\2', 1, 0) ;
--
<<loop_through_sets>>
while regexp_count(v_list_of_sets, '[^|]+') > 0
loop
v_set_1 := regexp_substr(v_list_of_sets, '[^|]+', 1, 1) ;
v_list_of_sets := regexp_replace(v_list_of_sets, v_set_1, sort_set(v_set_1), 1, 1) ;
v_set_1 := sort_set(v_set_1) ;
--
continue loop_through_sets when v_set_1 is null;
--
v_set_1_min := least(to_number(regexp_substr(v_set_1, '[^,]+', 1, 1))
,to_number(regexp_substr(v_set_1, '[^,]+', 1, 2))
) ;
v_set_1_max := greatest(to_number(regexp_substr(v_set_1, '[^,]+', 1, 1))
,to_number(regexp_substr(v_set_1, '[^,]+', 1, 2))
) ;
--
<<loop_for>>
for i in v_set_1_min..v_set_1_max
loop
--
v_output := v_output||','||i;
--
end loop loop_for;
--
v_list_of_sets := regexp_replace(v_list_of_sets,v_set_1,'',1,1);
--
end loop loop_through_sets;
--
v_output := sort_output(v_output);
--
return trim(v_output);
end;
 
--Test
select '-- Test ' as output from dual
union all
select lpad(' ', 65) || ' ==> ' || range_expansion(' ') as output from dual
union all
select lpad('-0,+0,-2 ,-1--2,3 ,-3, 2,-2', 65) || ' ==> ' || range_expansion('-0,+0,-2 ,-1--2,3 ,-3, 2,-2') as output from dual
union all
select lpad('0,-1,+2,-2', 65) || ' ==> ' || range_expansion('0,-1,2,-2') as output from dual
union all
select lpad('-D,-w23--1,+14q,15,17-20,3-5,7-11, +0, 2q, +4, 3,0 ,-0,-2 , -3', 65) || ' ==> ' || range_expansion('-D,-w23--1,+14q,15,17-20,3-5,7-11, +0, 2q, +4, 3,0 ,-0,-2 , -3') as output from dual
union all
select lpad('-6,-3--1,14,15,17-20,3-5,7-11', 65) || ' ==> ' || range_expansion('-6,-3--1,14,15,17-20,3-5,11-7') as output from dual
union all
--Test RosettaCode
select '-- Test RosettaCode' as output from dual
union all
select lpad('-6,-3--1,3-5,7-11,14,15,17-20', 65) || ' ==> ' || range_expansion('-6,-3--1,3-5,7-11,14,15,17-20') as output from dual
;
 
</syntaxhighlight>
 
{{out}}
<pre>
-- Test
==>
-0,+0,-2 ,-1--2,3 ,-3, 2,-2 ==> -3,-2,-1,0,2,3
0,-1,+2,-2 ==> -2,-1,0,2
-D,-w23--1,+14q,15,17-20,3-5,7-11, +0, 2q, +4, 3,0 ,-0,-2 , -3 ==> -3,-2,-1,0,3,4,5,7,8,9,10,11,15,17,18,19,20
-6,-3--1,14,15,17-20,3-5,7-11 ==> -6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20
-- Test RosettaCode
-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
</pre>
 
=={{header|Tailspin}}==
<syntaxhighlight lang="tailspin">
composer expand
[<element>*]
rule element: <range|INT> (<','>?)
rule range: (def start: <INT>; <'-'>) <INT> -> $start..$
end expand
 
'-6,-3--1,3-5,7-11,14,15,17-20' -> expand -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc rangeExpand desc {
set result {}
foreach term [split $desc ","] {
Line 3,427 ⟶ 4,290:
}
 
puts [rangeExpand "-6,-3--1,3-5,7-11,14,15,17-20"]</langsyntaxhighlight>
{{out}}
<pre>-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20</pre>
 
=={{header|TUSCRIPT}}==
<langsyntaxhighlight lang="tuscript">$$ MODE TUSCRIPT
rangednrs="-6,-3--1,3-5,7-11,14,15,17-20"
expandnrs=SPLIT (rangednrs,":,:")
Line 3,453 ⟶ 4,316:
expandnrs= JOIN (expandnrs,",")
 
PRINT expandnrs</langsyntaxhighlight>
{{out}}
<pre>
Line 3,478 ⟶ 4,341:
Code:
 
<langsyntaxhighlight lang="txr">@(define num (n))@(local tok)@{tok /[+\-]?\d+/}@(bind n @(int-str tok))@(end)
@(define entry (e))@\
@(local n1 n2)@\
Line 3,520 ⟶ 4,383:
your junk: @{trailing-junk}
@(end)
@(end)</langsyntaxhighlight>
 
{{out|Run}}
Line 3,544 ⟶ 4,407:
=={{header|UNIX Shell}}==
{{works with|bash}}
<langsyntaxhighlight lang="bash">#!/usr/bin/bash
 
range_expand () (
Line 3,562 ⟶ 4,425:
)
 
range_expand "-6,-3--1,3-5,7-11,14,15,17-20"</langsyntaxhighlight>
{{out}}
<pre>-6 -3 -2 -1 3 4 5 7 8 9 10 11 14 15 17 18 19 20</pre>
 
=={{header|Ursala}}==
<langsyntaxhighlight Ursalalang="ursala">#import std
#import int
 
Line 3,574 ⟶ 4,437:
#cast %zL
 
t = rex '-6,-3--1,3-5,7-11,14,15,17-20'</langsyntaxhighlight>
{{out}}
<pre><-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20></pre>
 
=={{header|VBA}}==
<langsyntaxhighlight VBAlang="vba">Public Function RangeExpand(AString as string)
' return a list with the numbers expressed in AString
Dim Splits() As String
Line 3,624 ⟶ 4,487:
Next
Debug.Print
End Sub</langsyntaxhighlight>
{{out}}
<pre>
Line 3,632 ⟶ 4,495:
</pre>
 
=={{header|XPL0Wren}}==
{{trans|Kotlin}}
<lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations
<syntaxhighlight lang="wren">var expandRange = Fn.new { |s|
string 0; \use zero-terminated strings, instead of MSb
var list = []
char Str;
var items = s.split(",")
int Char, Inx;
for (item in items) {
var count = item.count { |c| c == "-" }
if (count == 0 || (count == 1 && item[0] == "-")) {
list.add(Num.fromString(item))
} else {
var items2 = item.split("-")
var first
var last
if (count == 1) {
first = Num.fromString(items2[0])
last = Num.fromString(items2[1])
} else if (count == 2) {
first = Num.fromString(items2[1]) * -1
last = Num.fromString(items2[2])
} else {
first = Num.fromString(items2[1]) * -1
last = Num.fromString(items2[3]) * -1
}
for (i in first..last) list.add(i)
}
}
return list
}
 
var s = "-6,-3--1,3-5,7-11,14,15,17-20"
System.print(expandRange.call(s))</syntaxhighlight>
 
{{out}}
proc GetCh; \Get character from Str
<pre>
[Char:= Str(Inx);
[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]
Inx:= Inx+1;
</pre>
]; \GetCh
 
=={{header|XPL0}}==
 
See Range Extraction for explanations.
func GetNum; \Get number from Str and return its value
<syntaxhighlight lang "XPL0">proc Expand(Range);
int Neg, Num;
char Range;
[Neg:= false;
int Lo, Hi, N;
if Char = ^- then [Neg:= true; GetCh];
[Text(8, Range);
Num:= 0;
loop [Lo:= IntIn(8);
while Char>=^0 & Char<=^9 do
BackUp; \get what terminated number
[Num:= Num*10 + Char-^0;
GetCh;case ChIn(8) of
^-: [Hi:= IntIn(8);
for N:= Lo to Hi do
[IntOut(0, N);
if N < Hi then Text(0, ", ");
];
BackUp;
if ChIn(8) = $1A \EOF\ then quit;
];
^,: IntOut(0, Lo)
other \EOF\ [IntOut(0, Lo); quit];
Text(0, ", ");
];
];
return if Neg then -Num else Num;
]; \GetNum
 
 
int I, N0, N1;
[Str:= "-6,-3--1,3-5,7-11,14,15,17-20";
Inx:= 0;
GetCh; \one character look ahead
loop [N0:= GetNum;
IntOut(0,N0);
case Char of
^,: [GetCh; ChOut(0,^,)];
^-: [GetCh;
N1:= GetNum;
for I:= N0+1 to N1 do \expand range
[ChOut(0,^,); IntOut(0,I)];
if Char=^, then [GetCh; ChOut(0,^,)] else quit]
other quit; \must be 0 string terminator
];
CrLf(0);
]</lang>
 
Expand("-6,-3--1,3-5,7-11,14,15,17-20")
</syntaxhighlight>
{{out}}
<pre>
-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20</pre>
</pre>
 
=={{header|Yabasic}}==
<langsyntaxhighlight Yabasiclang="yabasic">print RangeExpand$("-6,-3--1,3-5,7-11,14,15,17-20")
 
sub RangeExpand$(s$)
Line 3,704 ⟶ 4,584:
return left$(r$, len(r$) - 1)
end sub
</syntaxhighlight>
</lang>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn rangex(s){
fcn(s,re){
if (re.search(s)){
Line 3,717 ⟶ 4,597:
s.split(",").pump(List, _.fp1(RegExp(0'|(.*\d+)-(.*\d+)|)))
.flatten().concat(",");
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">ns="-6,-3-1,3-5,7-11,14,15,17-20";
rangex(ns).println();
 
ns="-6,-3--1,3-5,7-11,14,15,17-20";
rangex(ns).println();</langsyntaxhighlight>
 
{{out}}
9,476

edits