Range expansion: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
(10 intermediate revisions by 8 users not shown)
Line 17:
=={{header|11l}}==
{{trans|Python}}
<langsyntaxhighlight lang="11l">F rangeexpand(txt)
[Int] lst
L(r) txt.split(‘,’)
Line 27:
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>
 
Line 99 ⟶ 178:
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 164 ⟶ 243:
begin
Put (Expand ("-6,-3--1,3-5,7-11,14,15,17-20"));
end Test_Range_Expansion;</langsyntaxhighlight>
{{out}}
<pre>
Line 172 ⟶ 251:
=={{header|Aime}}==
{{incorrect|Aime|Needs "a comma separated list" without the trailing comma}}
<langsyntaxhighlight lang="aime">list l;
 
file().b_affix("-6,-3--1,3-5,7-11,14,15,17-20").news(l, 0, 0, ",");
Line 191 ⟶ 270:
}
 
o_("\n");</langsyntaxhighlight>
or:
<langsyntaxhighlight lang="aime">integer p;
list l;
 
Line 206 ⟶ 285:
}
 
o_("\n");</langsyntaxhighlight>
{{out}}
<pre>-6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20,</pre>
Line 214 ⟶ 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 383 ⟶ 462:
print( ( TOSTRING range expand( TORANGE "-6,-3--1,3-5,7-11,14,15,17-20" ), newline ) )
)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 391 ⟶ 470:
=={{header|APL}}==
{{works with|Dyalog APL}}
<langsyntaxhighlight APLlang="apl">range←{
aplnum←{⍎('¯',⎕D)[('-',⎕D)⍳⍵]}
∊{ 0::('Invalid range: ''',⍵,'''')⎕SIGNAL 11
Line 399 ⟶ 478:
(s+(⍳e-s-1))-1
}¨(⍵≠',')⊆⍵
}</langsyntaxhighlight>
 
{{out}}
Line 417 ⟶ 496:
===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
 
Line 572 ⟶ 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===
 
<langsyntaxhighlight lang="applescript">on rangeExpansion(rangeExpression)
-- Split the expression at the commas, if any.
set astid to AppleScript's text item delimiters
Line 609 ⟶ 688:
-- Demo code:
set rangeExpression to "-6,-3--1,3-5,7-11,14,15,17-20"
return rangeExpansion(rangeExpression)</langsyntaxhighlight>
 
{{output}}
<langsyntaxhighlight lang="applescript">{-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20}</langsyntaxhighlight>
 
=={{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 623 ⟶ 718:
ret .= "," (A_Index-1) + f1
return SubStr(ret, 2)
}</langsyntaxhighlight>
 
=={{header|AWK}}==
 
<langsyntaxhighlight lang="awk">#!/usr/bin/awk -f
BEGIN { FS=","; }
 
Line 648 ⟶ 743:
}
return;
} </langsyntaxhighlight>
 
<pre>
Line 657 ⟶ 752:
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> PRINT FNrangeexpand("-6,-3--1,3-5,7-11,14,15,17-20")
END
Line 679 ⟶ 774:
ENDIF
UNTIL i% = 0
= r$</langsyntaxhighlight>
{{out}}
<pre>
Line 686 ⟶ 781:
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat"> ( expandRanges
= a b L
. @( !arg
Line 701 ⟶ 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 707 ⟶ 802:
=={{header|C}}==
Recursive descent parser.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
Line 784 ⟶ 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 793 ⟶ 888:
=={{header|C sharp|C#}}==
{{works with|C sharp|3.0}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 822 ⟶ 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 855 ⟶ 950:
}
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <sstream>
#include <iterator>
Line 931 ⟶ 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 937 ⟶ 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 960 ⟶ 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 1,056 ⟶ 1,151:
END-IF
.
END PROGRAM display-edited-num.</langsyntaxhighlight>
 
Setup:
Line 1,070 ⟶ 1,165:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun expand-ranges (string)
(loop
with prevnum = nil
Line 1,092 ⟶ 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}}==
<langsyntaxhighlight lang="cowgol">include "cowgol.coh";
 
# Callback interface
Line 1,188 ⟶ 1,283:
# 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</langsyntaxhighlight>
 
{{out}}
Line 1,201 ⟶ 1,296:
=={{header|Crystal}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="crystal">def range_expand(range)
range.split(',').flat_map do |part|
match = /^(-?\d+)-(-?\d+)$/.match(part)
Line 1,212 ⟶ 1,307:
end
 
puts 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|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 1,224 ⟶ 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>
Line 1,230 ⟶ 1,325:
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program Range_expansion;
 
Line 1,300 ⟶ 1,395:
end;
readln;
end.</langsyntaxhighlight>
 
 
=={{header|DWScript}}==
<langsyntaxhighlight lang="pascal">
function ExpandRanges(ranges : String) : array of Integer;
begin
Line 1,320 ⟶ 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>
Line 1,328 ⟶ 1,423:
{{trans|Go}}
 
<langsyntaxhighlight 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.splitSplit(',') {
var i = part[1..].indexOfIndexOf('-')
if i == -1 {
var n = Integer(part)
if r.lenLength() > 0 {
return print("duplicate value: \(n)") when last == n
return print("values not ordered: \(last) > \(n)") when last > n
}
r.addAdd(n)
last = n
} else {
Line 1,347 ⟶ 1,442:
var n2 = Integer(part[(i + 2)..])
return print("invalid range: \(part)") when n2 < n1 + 2
if r.lenLength() > 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.addAdd(i)
}
last = n2
Line 1,363 ⟶ 1,458:
}
main()</langsyntaxhighlight>
 
{{out}}
Line 1,371 ⟶ 1,466:
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; parsing [spaces][-]digit(s)-[-]digit(s)[spaces]
(define R (make-regexp "^ *(\-?\\d+)\-(\-?\\d+) *$" ))
Line 1,397 ⟶ 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,412 ⟶ 1,507:
end
 
IO.inspect RC.expansion("-6,-3--1,3-5,7-11,14,15,17-20")</langsyntaxhighlight>
 
{{out}}
Line 1,420 ⟶ 1,515:
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( range ).
 
Line 1,435 ⟶ 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,444 ⟶ 1,539:
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">open System.Text.RegularExpressions
 
// simplify regex matching with an active pattern
Line 1,466 ⟶ 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,472 ⟶ 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,481 ⟶ 1,576:
] map-concat ;
 
"-6,-3--1,3-5,7-11,14,15,17-20" expand .</langsyntaxhighlight>
{{out}}
<pre>
Line 1,488 ⟶ 1,583:
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: >snumber ( str len -- 'str 'len n )
0. 2swap
over c@ [char] - = if
Line 1,512 ⟶ 1,607:
repeat 2drop ;
 
s" -6,-3--1,3-5,7-11,14,15,17-20" expand</langsyntaxhighlight>
 
=={{header|Fortran}}==
Line 1,523 ⟶ 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,622 ⟶ 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,629 ⟶ 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,703 ⟶ 1,798:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
{{out}}
Line 1,712 ⟶ 1,807:
=={{header|Go}}==
A version rather strict with input
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,775 ⟶ 1,870:
}
fmt.Println("expanded:", r)
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
Line 1,785 ⟶ 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,796 ⟶ 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,808 ⟶ 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 Text.Parsec
Line 1,836 ⟶ 1,931:
 
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,865 ⟶ 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,871 ⟶ 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,896 ⟶ 1,991:
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.util.*;
 
class RangeExpander implements Iterator<Integer>, Iterable<Integer> {
Line 1,960 ⟶ 2,055:
}
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
Line 1,966 ⟶ 2,061:
===Imperative (Spidermonkey)===
 
<langsyntaxhighlight lang="javascript">#!/usr/bin/env js
 
function main() {
Line 2,000 ⟶ 2,095:
 
main();
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,009 ⟶ 2,104:
====ES5====
 
<langsyntaxhighlight JavaScriptlang="javascript">(function (strTest) {
'use strict';
 
Line 2,047 ⟶ 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 2,109 ⟶ 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]
Line 2,117 ⟶ 2,237:
=={{header|Jsish}}==
{{trans|Javascript}}
<langsyntaxhighlight lang="javascript">#!/usr/bin/env jsish
"use strict";
 
Line 2,156 ⟶ 2,276:
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!=
*/</langsyntaxhighlight>
 
{{out}}
Line 2,163 ⟶ 2,283:
 
=={{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 2,173 ⟶ 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 2,217 ⟶ 2,337:
val s = "-6,-3--1,3-5,7-11,14,15,17-20"
println(expandRange(s))
}</langsyntaxhighlight>
 
{{out}}
Line 2,225 ⟶ 2,345:
 
=={{header|Lasso}}==
<langsyntaxhighlight lang="lasso">define range_expand(expression::string) => {
local(parts) = regexp(`^(-?\d+)-(-?\d+)$`)
Line 2,237 ⟶ 2,357:
}
 
range_expand(`-6,-3--1,3-5,7-11,14,15,17-20`)</langsyntaxhighlight>
 
{{out}}
Line 2,243 ⟶ 2,363:
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">print ExpandRange$( "-6,-3--1,3-5,7-11,14,15,17-20")
end
 
Line 2,265 ⟶ 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 2,290 ⟶ 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 2,332 ⟶ 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 2,367 ⟶ 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 2,377 ⟶ 2,497:
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
ExpandRanges := proc( s :: string )
uses StringTools;
Line 2,415 ⟶ 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,438 ⟶ 2,558:
 
=={{header|MATLAB}} / {{header|Octave}}==
<langsyntaxhighlight MATLABlang="matlab">function L=range_expansion(S)
% Range expansion
if nargin < 1;
Line 2,450 ⟶ 2,570:
S(ixr)=':';
S=['[',S,']'];
L=eval(S);</langsyntaxhighlight>
Usage:
<pre>
Line 2,460 ⟶ 2,580:
 
=={{header|MiniScript}}==
<langsyntaxhighlight MiniScriptlang="miniscript">pullInt = function(chars)
numstr = chars.pull
while chars and chars[0] != "," and chars[0] != "-"
Line 2,483 ⟶ 2,603:
end function
 
print expandRange("-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|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,497 ⟶ 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,506 ⟶ 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,540 ⟶ 2,660:
End
Say 'new='new /*show the expanded list */
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,548 ⟶ 2,668:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import parseutils, strutils
 
proc expandRange(input: string): string =
Line 2,571 ⟶ 2,691:
return output.join(",")
 
echo("-6,-3--1,3-5,7-11,14,15,17-20".expandRange)</langsyntaxhighlight>
 
{{out}}
Line 2,578 ⟶ 2,698:
=={{header|Oberon-2}}==
Oxford Oberon-2
<langsyntaxhighlight lang="oberon2">
MODULE LIVector;
IMPORT SYSTEM;
Line 2,815 ⟶ 2,935:
END ExpandRange.
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,822 ⟶ 2,942:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">#load "str.cma"
 
let range a b =
Line 2,844 ⟶ 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,856 ⟶ 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,890 ⟶ 3,010:
end
return expanded
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,898 ⟶ 3,018:
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
fun {Expand RangeDesc}
{Flatten
Line 2,927 ⟶ 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|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function range_expansion(string range)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence s = split(range,','),
<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>
res = {}
<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>
for i=1 to length(s) do
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
string si = s[i]
<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>
integer k = find('-',si,2)
<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>
if k=0 then
<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>
res = append(res,to_number(si))
<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>
else
<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>
integer startrange = to_number(si[1..k-1])
<span style="color: #008080;">else</span>
integer endofrange = to_number(si[k+1..$])
<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>
for l=startrange to endofrange do
<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>
res = append(res,l)
<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>
end for
<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>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
?range_expansion("-6,-3-1,3-5,7-11,14,15,17-20")
?range_expansion("-6,-3--1,3-5,7-11,14,15,17-20")</lang>
<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>
Line 2,978 ⟶ 3,101:
=={{header|Phixmonti}}==
Require Phixmonti 1.1
<langsyntaxhighlight Phixmontilang="phixmonti">0 tolist var r
 
def append
Line 3,001 ⟶ 3,124:
endfor
r
pstack</langsyntaxhighlight>
 
Other solution
<langsyntaxhighlight Phixmontilang="phixmonti">0 tolist var r
 
def append
Line 3,026 ⟶ 3,149:
endfor
r
pstack</langsyntaxhighlight>
 
A bit more understandable
<langsyntaxhighlight Phixmontilang="phixmonti">0 tolist var r
 
def append
Line 3,066 ⟶ 3,189:
endfor
r
pstack</langsyntaxhighlight>
 
=={{header|PHP}}==
{{trans|Python}}
<langsyntaxhighlight PHPlang="php">function rangex($str) {
$lst = array();
foreach (explode(',', $str) as $e) {
Line 3,081 ⟶ 3,204:
}
return $lst;
}</langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de rangeexpand (Str)
(make
(for S (split (chop Str) ",")
Line 3,092 ⟶ 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 3,098 ⟶ 3,221:
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">range_expansion:
procedure options (main);
 
Line 3,148 ⟶ 3,271:
delimiter = ',';
end;
end range_expansion;</langsyntaxhighlight>
{{out}}
<pre>
Line 3,155 ⟶ 3,278:
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function range-expansion($array) {
function expansion($arr) {
Line 3,178 ⟶ 3,301:
}
range-expansion "-6,-3--1,3-5,7-11,14,15,17-20"
</syntaxhighlight>
</lang>
<b>Output:</b>
<pre>
Line 3,186 ⟶ 3,309:
===Alternate Half-Assed Regex Version===
Ten times faster (only minimally tested).
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Expand-Range
{
Line 3,229 ⟶ 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 3,243 ⟶ 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 3,323 ⟶ 3,446:
run(Var1,LRest,[Deb, Fin], RRest).
 
run(Val,[Other|RRest], [Val, Val],[Other|RRest]).</langsyntaxhighlight>
{{out}}
<pre> ?- range_expand.
Line 3,331 ⟶ 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 3,376 ⟶ 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>
Line 3,382 ⟶ 3,505:
=={{header|Python}}==
===Procedural===
<langsyntaxhighlight lang="python">def rangeexpand(txt):
lst = []
for r in txt.split(','):
Line 3,392 ⟶ 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 3,405 ⟶ 3,528:
else:
lst.append(int(start))
return lst</langsyntaxhighlight>
 
===Functional===
As a fold/catamorphism:
{{Works with|Python|3.7}}
<langsyntaxhighlight lang="python">'''Range expansion'''
 
from functools import (reduce)
Line 3,511 ⟶ 3,634:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Range expansion:
Line 3,520 ⟶ 3,643:
 
=={{header|R}}==
<syntaxhighlight lang="r">
<lang R>
rangeExpand <- function(text) {
lst <- gsub("(\\d)-", "\\1:", unlist(strsplit(text, ",")))
Line 3,528 ⟶ 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 3,545 ⟶ 3,668:
 
(range-expand "-6,-3--1,3-5,7-11,14,15,17-20")
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,556 ⟶ 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,583 ⟶ 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,594 ⟶ 3,717:
 
{{works with|Rakudo|2016.07}}
<syntaxhighlight lang="raku" perl6line>sub range-expand (Str $range-description) {
my token number { '-'? \d+ }
my token range { (<&number>) '-' (<&number>) }
Line 3,604 ⟶ 3,727:
}
say range-expand('-6,-3--1,3-5,7-11,14,15,17-20').join(', ');</langsyntaxhighlight>
 
{{out}}
Line 3,612 ⟶ 3,735:
Alternatively, using a grammar:
 
<syntaxhighlight lang="raku" perl6line>grammar RangeList {
token TOP { <term>* % ',' { make $<term>.map(*.made) } }
token term { [<range>|<num>] { make ($<num> // $<range>).made } }
Line 3,619 ⟶ 3,742:
}
 
say RangeList.parse('-6,-3--1,3-5,7-11,14,15,17-20').made.flat.join(', ');</langsyntaxhighlight>
 
{{out}}
Line 3,626 ⟶ 3,749:
=={{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,658 ⟶ 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,665 ⟶ 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,677 ⟶ 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,685 ⟶ 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,713 ⟶ 3,836:
End
End
Say 'new='new /*show the expanded list */</langsyntaxhighlight>
{{out}}
<pre>
Line 3,721 ⟶ 3,844:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Range expansion
 
Line 3,763 ⟶ 3,886:
see svect
see "]" + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 3,770 ⟶ 3,893:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def range_expand(rng)
rng.split(',').flat_map do |part|
if part =~ /^(-?\d+)-(-?\d+)$/
Line 3,780 ⟶ 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,809 ⟶ 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,816 ⟶ 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,842 ⟶ 3,965:
println!("{:?}", range_expand("-6,-3--1,3-5,7-11,14,15,17-20"));
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,850 ⟶ 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,868 ⟶ 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,885 ⟶ 4,008:
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">(define split
(lambda (str char skip count)
(let ((len (string-length str)))
Line 3,919 ⟶ 4,042:
(display ","))))))
(split str #\, 0 0))
(newline)))</langsyntaxhighlight>
{{out}}
<pre>
Line 3,929 ⟶ 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,963 ⟶ 4,086:
end for;
writeln;
end func;</langsyntaxhighlight>
{{out}}
<pre>
Line 3,970 ⟶ 4,093:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func rangex(str) {
str.split(',').map { |r|
var m = r.match(/^
Line 3,981 ⟶ 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 4,000 ⟶ 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}}==
<langsyntaxhighlight lang="tailspin">
composer expand
[<element>*]
Line 4,013 ⟶ 4,270:
 
'-6,-3--1,3-5,7-11,14,15,17-20' -> expand -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,020 ⟶ 4,277:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc rangeExpand desc {
set result {}
foreach term [split $desc ","] {
Line 4,033 ⟶ 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 4,059 ⟶ 4,316:
expandnrs= JOIN (expandnrs,",")
 
PRINT expandnrs</langsyntaxhighlight>
{{out}}
<pre>
Line 4,084 ⟶ 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 4,126 ⟶ 4,383:
your junk: @{trailing-junk}
@(end)
@(end)</langsyntaxhighlight>
 
{{out|Run}}
Line 4,150 ⟶ 4,407:
=={{header|UNIX Shell}}==
{{works with|bash}}
<langsyntaxhighlight lang="bash">#!/usr/bin/bash
 
range_expand () (
Line 4,168 ⟶ 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 4,180 ⟶ 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 4,230 ⟶ 4,487:
Next
Debug.Print
End Sub</langsyntaxhighlight>
{{out}}
<pre>
Line 4,240 ⟶ 4,497:
=={{header|Wren}}==
{{trans|Kotlin}}
<langsyntaxhighlight ecmascriptlang="wren">var expandRange = Fn.new { |s|
var list = []
var items = s.split(",")
Line 4,268 ⟶ 4,525:
 
var s = "-6,-3--1,3-5,7-11,14,15,17-20"
System.print(expandRange.call(s))</langsyntaxhighlight>
 
{{out}}
Line 4,276 ⟶ 4,533:
 
=={{header|XPL0}}==
See Range Extraction for explanations.
<lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations
<syntaxhighlight lang "XPL0">proc Expand(Range);
string 0; \use zero-terminated strings, instead of MSb
char StrRange;
int CharLo, InxHi, N;
[Text(8, Range);
 
loop [Lo:= IntIn(8);
 
proc GetCh; BackUp; \Getget characterwhat fromterminated Strnumber
case ChIn(8) of
[Char:= Str(Inx);
^-: [Hi:= IntIn(8);
Inx:= Inx+1;
for N:= Lo to Hi do
]; \GetCh
[IntOut(0, N);
 
if N < Hi then Text(0, ", ");
 
func GetNum; \Get number from Str and return its value];
BackUp;
int Neg, Num;
if ChIn(8) = $1A \EOF\ then quit;
[Neg:= false;
if Char = ^- then [Neg:= true; GetCh ];
^,: IntOut(0, Lo)
Num:= 0;
other \EOF\ [IntOut(0, Lo); quit];
while Char>=^0 & Char<=^9 do
[Num:=Text(0, Num*10", + Char-^0");
GetCh;
];
];
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 4,347 ⟶ 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 4,360 ⟶ 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,482

edits