Range consolidation: Difference between revisions

(Added solution for Action!)
 
(9 intermediate revisions by 6 users not shown)
Line 69:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F consolidate(ranges)
F normalize(s)
R sorted(s.filter(bounds -> !bounds.empty).map(bounds -> sorted(bounds)))
Line 89:
[[4.0, 3.0], [2.0, 1.0], [-1.0, -2.0], [3.9, 10.0]],
[[1.0, 3.0], [-6.0, -1.0], [-4.0, -5.0], [8.0, 2.0], [-6.0, -6.0]]]
print(String(s)[1 .< (len)-1]‘ => ’String(consolidate(s))[1 .< (len)-1])</langsyntaxhighlight>
 
{{out}}
Line 103:
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
<langsyntaxhighlight Actionlang="action!">INCLUDE "H6:REALMATH.ACT"
 
DEFINE PTR="CARD"
Line 275:
PutE() PutE()
OD
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Range_consolidation.png Screenshot from Atari 8-bit computer]
Line 291:
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Ada.Containers.Vectors;
 
Line 377:
Show (Set_4);
Show (Set_5);
end Range_Consolidation;</langsyntaxhighlight>
 
{{out}}
Line 386:
( 4.0 3.0) ( 2.0 1.0) ( -1.0 -2.0) ( 3.9 10.0) ( -2.0 -1.0) ( 1.0 2.0) ( 3.0 10.0)
( 1.0 3.0) ( -6.0 -1.0) ( -4.0 -5.0) ( 8.0 2.0) ( -6.0 -6.0) ( -6.0 -1.0) ( 1.0 8.0)
</pre>
 
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">
BEGIN # range consolidation #
 
MODE RANGE = STRUCT( REAL lb, ub );
 
# returns a with the bounds swapped if necessary, so lb OF a <= ub OF a #
OP NORMALISE = ( RANGE a )RANGE:
( IF lb OF a < ub OF a THEN lb OF a ELSE ub OF a FI
, IF ub OF a > lb OF a THEN ub OF a ELSE lb OF a FI
) # NORMALISE # ;
# returns a with each element normalised #
OP NORMALISE = ( []RANGE a )[]RANGE:
BEGIN
[ LWB a : UPB a ]RANGE result;
FOR a pos FROM LWB a TO UPB a DO result[ a pos ] := NORMALISE a[ a pos ] OD;
result
END # NORMALISE # ;
OP < = ( RANGE a, b )BOOL: lb OF a < lb OF b;
OP > = ( RANGE a, b )BOOL: lb OF a > lb OF b;
 
# sorts a into order of each element's lb #
OP SORT = ( []RANGE a )[]RANGE:
BEGIN
# in-place quick sort an array of RANGEs from element lb #
# to element ub #
PROC quicksort = ( REF[]RANGE a, INT lb, ub )REF[]RANGE:
IF ub <= lb
THEN
# empty array or only 1 element #
a
ELSE
# more than one element, so must sort #
INT left := lb;
INT right := ub;
# choosing the middle element of the array as the pivot #
RANGE pivot := a[ left + ( ( right + 1 ) - left ) OVER 2 ];
WHILE
WHILE IF left <= ub THEN a[ left ] < pivot ELSE FALSE FI DO left +:= 1 OD;
WHILE IF right >= lb THEN a[ right ] > pivot ELSE FALSE FI DO right -:= 1 OD;
left <= right
DO
RANGE t := a[ left ];
a[ left ] := a[ right ];
a[ right ] := t;
left +:= 1;
right -:= 1
OD;
quicksort( a, lb, right );
quicksort( a, left, ub );
a
FI # quicksort # ;
quicksort( HEAP[ LWB a : UPB a ]RANGE := a, LWB a, UPB a )
END # SORT # ;
 
# returns the consolidation of the ranges in a in #
OP CONSOLIDATE = ( []RANGE a in )[]RANGE:
IF UPB a in <= LWB a in
THEN a in # 0 or 1 range #
ELSE # multiple ranges #
[]RANGE a = SORT NORMALISE a in;
[ 1 : 2 * ( ( UPB a - LWB a ) + 1 ) ]RANGE result;
INT r max := 1;
result[ r max ] := a[ LWB a ];
FOR a pos FROM LWB a + 1 TO UPB a DO
RANGE m = result[ r max ], n = a[ a pos ];
IF ub OF m < lb OF n THEN
result[ r max +:= 1 ] := n # distinct ranges #
ELSE
result[ r max ] # overlapping ranges #
:= ( IF lb OF m < lb OF n THEN lb OF m ELSE lb OF n FI
, IF ub OF m > ub OF n THEN ub OF m ELSE ub OF n FI
)
FI
OD;
result[ : r max ]
FI # CONSOLIDATE # ;
 
OP FMT = ( REAL v )STRING: # prints v with at most 3 decimal places #
BEGIN
STRING result := fixed( ABS v, 0, 3 );
IF result[ LWB result ] = "." THEN "0" +=: result FI;
WHILE result[ UPB result ] = "0" DO result := result[ : UPB result - 1 ] OD;
IF result[ UPB result ] = "." THEN result := result[ : UPB result - 1 ] FI;
IF v < 0 THEN "-" ELSE "" FI + result
END # FMT # ;
 
OP TOSTRING = ( RANGE a )STRING: "[ " + FMT lb OF a + ", " + FMT ub OF a + " ]";
OP TOSTRING = ( []RANGE a )STRING:
BEGIN
STRING result := "[";
STRING prefix := " ";
FOR r pos FROM LWB a TO UPB a DO
result +:= prefix + TOSTRING a[ r pos ];
prefix := ", "
OD;
result + " ]"
END # TOSTRING # ;
PRIO PAD = 8; # right pads s with blanks to w characters #
OP PAD = ( STRING s, INT w )STRING:
IF INT len = ( UPB s - LWB s ) + 1;
len >= w
THEN s
ELSE s + ( ( w - len ) * " " )
FI # PAD # ;
 
# task test cases #
 
PROC test = ( []RANGE a )VOID:
BEGIN print( ( ( TOSTRING a PAD 60 ), " -> ", TOSTRING CONSOLIDATE a, newline ) ) END;
test( []RANGE( RANGE( 1.1, 2.2 ) ) );
test( ( ( 6.1, 7.2 ), ( 7.2, 8.3 ) ) );
test( ( ( 4, 3 ), ( 2, 1 ) ) );
test( ( ( 4, 3 ), ( 2, 1 ), ( -1, -2 ), ( 3.9, 10 ) ) );
test( ( ( 1, 3 ), ( -6, -1 ), ( -4, -5 ), ( 8, 2 ), ( -6, -6 ) ) )
 
END
</syntaxhighlight>
{{out}}
<pre>
[ [ 1.1, 2.2 ] ] -> [ [ 1.1, 2.2 ] ]
[ [ 6.1, 7.2 ], [ 7.2, 8.3 ] ] -> [ [ 6.1, 8.3 ] ]
[ [ 4, 3 ], [ 2, 1 ] ] -> [ [ 1, 2 ], [ 3, 4 ] ]
[ [ 4, 3 ], [ 2, 1 ], [ -1, -2 ], [ 3.9, 10 ] ] -> [ [ -2, -1 ], [ 1, 2 ], [ 3, 10 ] ]
[ [ 1, 3 ], [ -6, -1 ], [ -4, -5 ], [ 8, 2 ], [ -6, -6 ] ] -> [ [ -6, -1 ], [ 1, 8 ] ]
</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">RangeConsolidation(arr){
arr1 := [], arr2 := [], result := []
Line 406 ⟶ 533:
result[i-1, 2] := stop > result[i-1, 2] ? stop : result[i-1, 2]
return result
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">test1 := [[1.1, 2.2]]
test2 := [[6.1, 7.2], [7.2, 8.3]]
test3 := [[4, 3], [2, 1]]
Line 422 ⟶ 549:
}
MsgBox % result
return</langsyntaxhighlight>
{{out}}
<pre>[1.1, 2.2]
Line 431 ⟶ 558:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 520 ⟶ 647:
test_consolidate_ranges(test5, LENGTHOF(test5));
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 533 ⟶ 660:
=={{header|C sharp}}==
{{works with|C sharp|7}}
<langsyntaxhighlight lang="csharp">using static System.Math;
using System.Linq;
using System;
Line 571 ⟶ 698:
private static (double s, double e) Normalize((double s, double e) range) =>
(Min(range.s, range.e), Max(range.s, range.e));
}</langsyntaxhighlight>
{{out}}
<pre>
Line 581 ⟶ 708:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <algorithm>
#include <iostream>
#include <utility>
Line 650 ⟶ 777:
}
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 663 ⟶ 790:
 
=={{header|Clojure}}==
<langsyntaxhighlight Clojurelang="clojure">(defn normalize [r]
(let [[n1 n2] r]
[(min n1 n2) (max n1 n2)]))
Line 688 ⟶ 815:
(remove #(contains? (set used) %) rs))]
(recur (conj res (consolidate-touching-ranges touching))
(remove-used (rest rs) touching))))))</langsyntaxhighlight>
 
{{out}}
Line 710 ⟶ 837:
{{trans|C#}}
 
<langsyntaxhighlight lang="dyalect">type Pt(s, e) with Lookup
 
func Pt.minMin() => min(this::.s, this::.e)
func Pt.maxMax() => max(this::.s, this::.e)
func Pt.toStringToString() => "(\(this::.s), \(this::.e))"
 
let rng = [
[ Pt(1.1, 2.2) ],
Line 723 ⟶ 850:
[ Pt(1.0, 3.0), Pt(-6, -1), Pt(-4, -5), Pt(8, 2), Pt(-6, -6) ]
]
 
func overlap(left, right) =>
left.Max() > right.Max() ? right.maxMax() >= left.minMin()
when: left.maxMax() >= right.maxMin()
else left.max() >= right.min()
func consolidate(left, right) => Pt(min(left.minMin(), right.minMin()), max(left.maxMax(), right.maxMax()))
func normalize(range) => Pt(range.minMin(), range.maxMax())
for list in rng {
var z = list.lenLength() - 1
while z >= 1 {
for y in (z - 1)^-1..0 when overlap(list[z], list[y]) {
list[y] = consolidate(list[z], list[y])
break list.removeAtRemoveAt(z)
}
z -= 1
}
for i in list.indicesIndices() {
list[i] = normalize(list[i])
}
list.sortSort((x,y) => x::.s - y::.s)
print(list)
}</langsyntaxhighlight>
 
{{out}}
Line 762 ⟶ 888:
=={{header|Factor}}==
{{works with|Factor|0.99 2021-06-02}}
<langsyntaxhighlight lang="factor">USING: arrays combinators formatting kernel math.combinatorics
math.order math.statistics sequences sets sorting ;
 
Line 785 ⟶ 911:
{ { 4 3 } { 2 1 } { -1 -2 } { 3.9 10 } }
{ { 1 3 } { -6 -1 } { -4 -5 } { 8 2 } { -6 -6 } }
} [ dup consolidate "%49u => %u\n" printf ] each</langsyntaxhighlight>
{{out}}
<pre>
Line 797 ⟶ 923:
=={{header|FreeBASIC}}==
{{trans|Yabasic}}
<langsyntaxhighlight lang="freebasic">
Dim Shared As Integer i
Dim Shared As Single items, temp = 10^30
Line 869 ⟶ 995:
Next j
Sleep
</syntaxhighlight>
</lang>
 
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 947 ⟶ 1,073:
fmt.Println(s[1 : len(s)-1])
}
}</langsyntaxhighlight>
 
{{out}}
Line 959 ⟶ 1,085:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.List (intercalate, maximumBy, sort)
import Data.Ord (comparing)
 
Line 1,043 ⟶ 1,169:
showNum n
| 0 == (n - fromIntegral (round n)) = show (round n)
| otherwise = show n</langsyntaxhighlight>
{{Out}}
<pre>Range consolidations:
Line 1,055 ⟶ 1,181:
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j">ensure2D=: ,:^:(1 = #@$) NB. if list make 1 row table
normalise=: ([: /:~ /:~"1)@ensure2D NB. normalises list of ranges
merge=: ,:`(<.&{. , >.&{:)@.(>:/&{: |.) NB. merge ranges x and y
consolidate=: (}.@] ,~ (merge {.)) ensure2D</langsyntaxhighlight>
'''Required Examples:'''
<langsyntaxhighlight lang="j"> tests=: <@".;._2 noun define
1.1 2.2
6.1 7.2 ,: 7.2 8.3
Line 1,073 ⟶ 1,199:
| | |3 4| 1 2| 1 8|
| | | | 3 10| |
+-------+-------+---+-----+-----+</langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.Arrays;
Line 1,186 ⟶ 1,312:
 
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,204 ⟶ 1,330:
{{Trans|Haskell}}
{{Trans|Python}}
<langsyntaxhighlight lang="javascript">(() => {
'use strict';
 
Line 1,380 ⟶ 1,506:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>Range consolidations:
Line 1,393 ⟶ 1,519:
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<langsyntaxhighlight lang="jq">def normalize: map(sort) | sort;
def consolidate:
Line 1,421 ⟶ 1,547:
;
testranges</langsyntaxhighlight>
{{out}}
<pre>
Line 1,438 ⟶ 1,564:
of the Python code is done, rather than using a native Julia Range.
{{trans|Python}}
<langsyntaxhighlight lang="julia">normalize(s) = sort([sort(bounds) for bounds in s])
 
function consolidate(ranges)
Line 1,464 ⟶ 1,590:
 
testranges()
</langsyntaxhighlight>{{output}}
<pre>
Array{Float64,1}[[1.1, 2.2]] => Array{Float64,1}[[1.1, 2.2]]
Line 1,474 ⟶ 1,600:
 
=={{header|Kotlin}}==
<langsyntaxhighlight Kotlinlang="kotlin">fun <T> consolidate(ranges: Iterable<ClosedRange<T>>): List<ClosedRange<T>> where T : Comparable<T>
{
return ranges
Line 1,539 ⟶ 1,665:
 
inputRanges.associateBy(Any::toString, ::consolidateDoubleRanges).forEach({ println("${it.key} => ${it.value}") })
}</langsyntaxhighlight>
 
{{Out}}
Line 1,552 ⟶ 1,678:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Using the Wolfram Language's built-in Interval operations:
<langsyntaxhighlight Mathematicalang="mathematica">data={{{1.1,2.2}},
{{6.1,7.2},{7.2,8.3}},
{{4,3},{2,1}},
{{4,3},{2,1},{-1,-2},{3.9,10}},
{{1,3},{-6,-1},{-4,-5},{8,2},{-6,-6}}};
Column[IntervalUnion@@@Map[Interval,data,{2}]]</langsyntaxhighlight>
{{out}}
<pre>Interval[{1.1,2.2}]
Line 1,566 ⟶ 1,692:
 
=={{header|Nim}}==
<langsyntaxhighlight Nimlang="nim">import algorithm, strutils
 
# Definition of a range of values of type T.
Line 1,620 ⟶ 1,746:
test([4, 3], [2, 1])
test([4.0, 3.0], [2.0, 1.0], [-1.0, -2.0], [3.9, 10.0])
test([1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6])</langsyntaxhighlight>
 
{{out}}
Line 1,633 ⟶ 1,759:
Note: the output is shown in the standard [https://perldoc.perl.org/perlop.html#Range-Operators Perl notation for Ranges].
 
<langsyntaxhighlight lang="perl">use strict;
use warnings;
 
Line 1,663 ⟶ 1,789:
$out .= join('..', @$_). ' ' for consolidate($intervals);
printf "%44s => %s\n", $in, $out;
}</langsyntaxhighlight>
{{out}}
<pre> [1.1, 2.2] => 1.1..2.2
Line 1,672 ⟶ 1,798:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function consolidate(sequence sets)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
for i=length(sets) to 1 by -1 do
<span style="color: #008080;">function</span> <span style="color: #000000;">consolidate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">sets</span><span style="color: #0000FF;">)</span>
sets[i] = sort(sets[i])
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sets</span><span style="color: #0000FF;">)</span>
atom {is,ie} = sets[i]
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
for j=length(sets) to i+1 by -1 do
<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: #000000;">l</span> <span style="color: #008080;">do</span>
atom {js,je} = sets[j]
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">rs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">re</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
bool overlap = iff(is<=js?js<=ie:is<=je)
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rs</span><span style="color: #0000FF;">></span><span style="color: #000000;">re</span><span style="color: #0000FF;">?{</span><span style="color: #000000;">re</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rs</span><span style="color: #0000FF;">}:{</span><span style="color: #000000;">rs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">re</span><span style="color: #0000FF;">})</span>
if overlap then
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
sets[i] = {min(is,js),max(ie,je)}
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">l</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
sets[j..j] = {}
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">il</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ih</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end if
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">l</span> <span style="color: #008080;">to</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
end for
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">jl</span><span style="color: #0000FF;">,</span><span style="color: #000000;">jh</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
end for
<span style="color: #004080;">bool</span> <span style="color: #000000;">overlap</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">il</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">jl</span><span style="color: #0000FF;">?</span><span style="color: #000000;">jl</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">ih</span><span style="color: #0000FF;">:</span><span style="color: #000000;">il</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">jh</span><span style="color: #0000FF;">)</span>
return sort(sets)
<span style="color: #008080;">if</span> <span style="color: #000000;">overlap</span> <span style="color: #008080;">then</span>
end function
<span style="color: #0000FF;">{</span><span style="color: #000000;">il</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ih</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">il</span><span style="color: #0000FF;">,</span><span style="color: #000000;">jl</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ih</span><span style="color: #0000FF;">,</span><span style="color: #000000;">jh</span><span style="color: #0000FF;">)}</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</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>
procedure test(sequence set)
<span style="color: #000000;">l</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
printf(1,"%40v => %v\n",{set,consolidate(set)})
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">il</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ih</span><span style="color: #0000FF;">}</span>
test({{1.1,2.2}})
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
test({{6.1,7.2},{7.2,8.3}})
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">l</span><span style="color: #0000FF;">])</span>
test({{4,3},{2,1}})
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
test({{4,3},{2,1},{-1,-2},{3.9,10}})
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
test({{1,3},{-6,-1},{-4,-5},{8,2},{-6,-6}})</lang>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%40v =&gt; %v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">set</span><span style="color: #0000FF;">,</span><span style="color: #000000;">consolidate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1.1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2.2</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">6.1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7.2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">7.2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8.3</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">3.9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">6</span><span style="color: #0000FF;">}})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,708 ⟶ 1,845:
=={{header|Prolog}}==
{{works with|SWI Prolog}}
<langsyntaxhighlight lang="prolog">consolidate_ranges(Ranges, Consolidated):-
normalize(Ranges, Normalized),
sort(Normalized, Sorted),
Line 1,750 ⟶ 1,887:
(consolidate_ranges(Ranges, Consolidated),
write_ranges(Ranges), write(' -> '),
write_ranges(Consolidated), nl)).</langsyntaxhighlight>
 
{{out}}
Line 1,763 ⟶ 1,900:
=={{header|Python}}==
===Procedural===
<langsyntaxhighlight lang="python">def normalize(s):
return sorted(sorted(bounds) for bounds in s if bounds)
 
Line 1,785 ⟶ 1,922:
]:
print(f"{str(s)[1:-1]} => {str(consolidate(s))[1:-1]}")
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,800 ⟶ 1,937:
{{Trans|Haskell}}
{{Works with|Python|3.7}}
<langsyntaxhighlight lang="python">'''Range consolidation'''
 
from functools import reduce
Line 1,887 ⟶ 2,024:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Consolidation of numeric ranges:
Line 1,898 ⟶ 2,035:
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">#lang racket
 
;; Racket's max and min allow inexact numbers to contaminate exact numbers
Line 1,925 ⟶ 2,062:
([1 3] [-6 -1] [-4 -5] [8 2] [-6 -6])))
 
(for ([xs (in-list inputs)]) (printf "~a => ~a\n" xs (solve xs)))</langsyntaxhighlight>
 
{{out}}
Line 1,943 ⟶ 2,080:
Note: the output is in standard [https://docs.raku.org/type/Range Raku notation for Ranges].
 
<syntaxhighlight lang="raku" perl6line># Union
sub infix:<∪> (Range $a, Range $b) { Range.new($a.min,max($a.max,$b.max)) }
 
Line 1,969 ⟶ 2,106:
printf "%46s => ", @intervals.raku;
say reverse consolidate |@intervals.grep(*.elems)».sort.sort({ [.[0], .[*-1]] }).map: { Range.new(.[0], .[*-1]) }
}</langsyntaxhighlight>
{{out}}
<pre> [[1.1, 2.2],] => (1.1..2.2)
Line 1,982 ⟶ 2,119:
 
The actual logic for the range consolidation is marked with the comments: &nbsp; &nbsp; <big> <tt> /*■■■■►*/ </tt> </big>
<langsyntaxhighlight lang="rexx">/*REXX program performs range consolidation (they can be [equal] ascending/descending). */
#.= /*define the default for range sets. */
parse arg #.1 /*obtain optional arguments from the CL*/
Line 2,036 ⟶ 2,173:
do k=j+1 to n; if word(@.k,1)>=word(_,1) then iterate; @.j=@.k; @.k=_; _=@.j
end /*k*/
end /*j*/; return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 2,064 ⟶ 2,201:
The algorithm relies on normalizing the ranges and folding a sorted sequence of them.
 
<langsyntaxhighlight Rustlang="rust">use std::fmt::{Display, Formatter};
 
// We could use std::ops::RangeInclusive, but we would have to extend it to
Line 2,217 ⟶ 2,354:
 
println!("Run: cargo test -- --nocapture");
}</langsyntaxhighlight>
 
{{out}}
Line 2,234 ⟶ 2,371:
 
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
</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 consolidation" in SQL ORACLE 19c
p_list_of_sets -- input string
delimeter by default "|"
*/
with
function range_consolidation(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_2 varchar2(2000);
v_pos_set_1 pls_integer;
v_pos_set_2 pls_integer;
v_set_1_min number;
v_set_1_max number;
v_set_2_min number;
v_set_2_max number;
--
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)) elem
from
(select p_in_str as str
from dual
)
connect by level <= regexp_count(str, '[^,]+')
)
select 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 to_number(regexp_substr(regexp_substr(str, '[^|]+', 1, rownum, 'c', 0), '[^,]+', 1, 1)) low_range
, regexp_substr(str, '[^|]+', 1, rownum, 'c', 0) range_def
from
(select p_in_str as str
from dual
)
connect by level <= regexp_count(str, '[^|]+')
)
select listagg(range_def, '|') within group(order by low_range)
into v_out
from out_tab;
--
return v_out;
end;
--
begin
--
execute immediate ('alter session set NLS_NUMERIC_CHARACTERS = ''.,''');
--
--cleaning
v_list_of_sets := ltrim(v_list_of_sets, '[');
v_list_of_sets := rtrim(v_list_of_sets, ']');
v_list_of_sets := replace(v_list_of_sets, ' ', '');
--set delimeter "|"
v_list_of_sets := regexp_replace(v_list_of_sets, '\]\,\[', '|', 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);
v_pos_set_1 := regexp_instr(v_list_of_sets, '[^|]+', 1, 1);
--
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 1..regexp_count(v_list_of_sets, '[^|]+')-1
loop
--
v_set_2 := regexp_substr(v_list_of_sets, '[^|]+', 1, i+1);
v_list_of_sets := regexp_replace(v_list_of_sets, v_set_2, sort_set(v_set_2), 1, 1);
v_set_2 := sort_set(v_set_2);
v_pos_set_2 := regexp_instr(v_list_of_sets, '[^|]+', 1, i+1);
v_set_2_min := least(to_number(regexp_substr(v_set_2, '[^,]+', 1, 1)),to_number(regexp_substr(v_set_2, '[^,]+', 1, 2)));
v_set_2_max := greatest(to_number(regexp_substr(v_set_2, '[^,]+', 1, 1)),to_number(regexp_substr(v_set_2, '[^,]+', 1, 2)));
--
if greatest(v_set_1_min,v_set_2_min)-least(v_set_1_max,v_set_2_max) <= 0 then --overlapping
v_list_of_sets := regexp_replace(v_list_of_sets, v_set_1, ''||least(v_set_1_min,v_set_2_min)||','||greatest(v_set_1_max,v_set_2_max),v_pos_set_1,1);
v_list_of_sets := regexp_replace(v_list_of_sets, v_set_2, '', v_pos_set_2, 1);
continue loop_through_sets;
end if;
--
end loop loop_for;
--
v_output := ltrim(v_output||'|'||least(v_set_1_min,v_set_1_max)||', '||greatest(v_set_1_min,v_set_1_max),'|');
--
v_output := sort_output(v_output);
v_list_of_sets := regexp_replace(v_list_of_sets,v_set_1,'',1,1);
--
end loop loop_through_sets;
--
return '['||replace(v_output,'|','], [')||']';
end;
 
--Test
select lpad('[]',50) || ' ==> ' || range_consolidation('[]') as output from dual
union all
select lpad('[],[]',50) || ' ==> ' || range_consolidation('[],[]') as output from dual
union all
select lpad('[],[1,1]',50) || ' ==> ' || range_consolidation('[],[1,1]') as output from dual
union all
select lpad('[1.3]',50) || ' ==> ' || range_consolidation('[1.3]') as output from dual
union all
select lpad('[2,2],[1]',50) || ' ==> ' || range_consolidation('[2,2],[1]') as output from dual
union all
select lpad('[4,-1,0,1,5,7,7,7],[9,6,9,6,9]',50) || ' ==> ' || range_consolidation('[4,-1,0,1,5,7,7,7],[9,6,9,6,9]') as output from dual
union all
--Test RosettaCode
select '-- Test RosettaCode' as output from dual
union all
select lpad('[1.1, 2.2]',50) || ' ==> ' || range_consolidation('[1.1, 2.2]') as output from dual
union all
select lpad('[6.1, 7.2], [7.2, 8.3]',50) || ' ==> ' || range_consolidation('[6.1, 7.2], [7.2, 8.3]') as output from dual
union all
select lpad('[4, 3], [2, 1]',50) || ' ==> ' || range_consolidation('[4, 3], [2, 1]') as output from dual
union all
select lpad('[4, 3], [2, 1], [-1, -2], [3.9, 10]',50) || ' ==> ' || range_consolidation('[4, 3], [2, 1], [-1, -2], [3.9, 10]') as output from dual
union all
select lpad('[1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6]',50) || ' ==> ' || range_consolidation('[1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6]') as output from dual
union all
select lpad('1,3|-6,-1|-4,-5|8,2|-6,-6',50) || ' ==> ' || range_consolidation('1,3|-6,-1|-4,-5|8,2|-6,-6') as output from dual
/
;
/
</syntaxhighlight>
 
{{out}}
<pre>
[] ==> []
[],[] ==> []
[],[1,1] ==> [1, 1]
[1.3] ==> [1.3, 1.3]
[2,2],[1] ==> [1, 1], [2, 2]
[4,-1,0,1,5,7,7,7],[9,6,9,6,9] ==> [-1, 9]
-- Test RosettaCode
[1.1, 2.2] ==> [1.1, 2.2]
[6.1, 7.2], [7.2, 8.3] ==> [6.1, 8.3]
[4, 3], [2, 1] ==> [1, 2], [3, 4]
[4, 3], [2, 1], [-1, -2], [3.9, 10] ==> [-2, -1], [1, 2], [3, 10]
[1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6] ==> [-6, -1], [1, 8]
1,3|-6,-1|-4,-5|8,2|-6,-6 ==> [-6, -1], [1, 8]
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-math}}
As Wren already has a built-in Range class (which is not quite the same as what's required here), we create a Span class instead.
<syntaxhighlight lang="wren">class Span {
<lang ecmascript>import "/math" for Math
 
class Span {
construct new(r) {
if (r.type != Range || !r.isInclusive) Fiber.abort("Argument must be an inclusive range.")
Line 2,259 ⟶ 2,559:
if (_high < r.low) return [this, r]
if (r.high < _low) return [r, this]
return [Span.new(Math_low.min(_low, r.low)..Math_high.max(_high, r.high))]
}
 
Line 2,296 ⟶ 2,596:
System.print(spanList.toString[1..-2])
}
}</langsyntaxhighlight>
 
{{out}}
Line 2,308 ⟶ 2,608:
 
=={{header|Yabasic}}==
<langsyntaxhighlight Yabasiclang="yabasic">sub sort(tabla())
local items, i, t1, t2, s
Line 2,378 ⟶ 2,678:
for i = 1 to items
if tabla(i, 1) <> void print tabla(i, 1), "..", tabla(i, 2);
next</langsyntaxhighlight>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn consolidate(rs){
(s:=List()).append(
normalize(rs).reduce('wrap(ab,cd){
Line 2,388 ⟶ 2,688:
}) )
}
fcn normalize(s){ s.apply("sort").sort(fcn(a,b){ a[0]<b[0] }) }</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">foreach rs in (L(
L(L(1.1, 2.2)), L(L(6.1, 7.2), L(7.2, 8.3)), L(L(4, 3), L(2, 1)),
L(L(4.0, 3.0), L(2.0, 1.0), L(-1.0, -2.0), L(3.9, 10.0)),
L(L(1, 3), L(-6, -1), L(-4, -5), L(8, 2), L(-6, -6)),
)){ println(ppp(rs),"--> ",ppp(consolidate(rs))) }
fcn ppp(ll){ ll.pump(String,fcn(list){ list.concat(", ", "[", "] ") }) }</langsyntaxhighlight>
{{out}}
<pre>
3,026

edits