Set consolidation: Difference between revisions

Add Draco
(Added AutoHotkey)
(Add Draco)
 
(23 intermediate revisions by 13 users not shown)
Line 28:
We start with specifying a generic package Set_Cons that provides the neccessary tools, such as contructing and manipulating sets, truning them, etc.:
 
<langsyntaxhighlight Adalang="ada">generic
type Element is (<>);
with function Image(E: Element) return String;
Line 54:
type Set is array(Element) of Boolean;
 
end Set_Cons;</langsyntaxhighlight>
 
Here is the implementation of Set_Cons:
 
<langsyntaxhighlight Adalang="ada">package body Set_Cons is
 
function "+"(E: Element) return Set is
Line 134:
end Image;
 
end Set_Cons;</langsyntaxhighlight>
 
Given that package, the task is easy:
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Set_Cons;
 
procedure Set_Consolidation is
Line 177:
Ada.Text_IO.Put_Line
(Image(Consolidate((H+I+K) & (A+B) & (C+D) & (D+B) & (F+G+H))));
end Set_Consolidation;</langsyntaxhighlight>
 
{{out}}
Line 186:
 
=={{header|Aime}}==
<langsyntaxhighlight lang="aime">display(list l)
{
for (integer i, record r in l) {
Line 240:
 
0;
}</langsyntaxhighlight>
{{out}}
<pre>{A, B}, {C, D}
Line 246:
{A, B, C, D}
{A, B, C, D}, {F, G, H, I, K}</pre>
 
=={{header|APL}}==
<syntaxhighlight lang="apl">consolidate ← (⊢((⊂∘∪∘∊(/⍨)),(/⍨)∘~)(((⊃∘⍒+/)⊃↓)∘.(∨/∊)⍨))⍣≡</syntaxhighlight>
{{out}}
<syntaxhighlight lang="apl"> consolidate 'AB' 'CD'
AB CD
consolidate 'AB' 'BD'
ABD
consolidate 'AB' 'CD' 'DB'
ABCD
consolidate 'HIK' 'AB' 'CD' 'DB' 'FGH'
HIKFG ABCD </syntaxhighlight>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">SetConsolidation(sets){
arr2 := [] , arr3 := [] , arr4 := [] , arr5 := [], result:=[]
; sort each set individually
Line 293 ⟶ 305:
result[i, A_Index] := k
return result
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">test1 := [["A","B"], ["C","D"]]
test2 := [["A","B"], ["B","D"]]
test3 := [["A","B"], ["C","D"], ["D","B"]]
Line 312 ⟶ 324:
}
MsgBox % RTrim(result, "`n[")
return</langsyntaxhighlight>
{{out}}
<pre>[["A","B"] , ["C","D"]]
Line 318 ⟶ 330:
[["A","B","C","D"]]
[["A","B","C","D"] , ["F","G","H","I","K"]]</pre>
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">dim test$(4)
test$[0] = "AB"
test$[1] = "AB,CD"
test$[2] = "AB,CD,DB"
test$[3] = "HIK,AB,CD,DB,FGH"
for t = 0 to 3 #test$[?]
print Consolidate(test$[t])
next t
end
 
function Consolidate(s$)
dim sets$(100)
 
# Split the string into substrings
pio = 1
n = 0
for i = 1 to length(s$)
if mid(s$, i, 1) = "," then
fin = i - 1
sets$[n] = mid(s$, pio, fin - pio + 1)
pio = i + 1
n += 1
end if
next i
sets$[n] = mid(s$, pio, length(s$) - pio + 1)
 
# Main logic
for i = 0 to n
p = i
ts$ = ""
for j = i to 0 step -1
if ts$ = "" then p = j
ts$ = ""
for k = 1 to length(sets$[p])
if j > 0 then
if instr(sets$[j-1], mid(sets$[p], k, 1)) = 0 then
ts$ += mid(sets$[p], k, 1)
end if
end if
next k
if length(ts$) < length(sets$[p]) then
if j > 0 then
sets$[j-1] = sets$[j-1] + ts$
sets$[p] = "-"
ts$ = ""
end if
else
p = i
end if
next j
next i
 
# Join the substrings into a string
temp$ = sets$[0]
for i = 1 to n
temp$ += "," + sets$[i]
next i
 
return s$ + " = " + temp$
end function</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
Same code as [[#GW-BASIC|GW-BASIC]]
 
==={{header|FreeBASIC}}===
{{trans|Ring}}
<syntaxhighlight lang="vbnet">Function Consolidate(s As String) As String
Dim As Integer i, j, k, p, n, pio, fin
Dim As String ts, sets(0 To 100), temp
' Split the string into substrings
pio = 1
n = 0
For i = 1 To Len(s)
If Mid(s, i, 1) = "," Then
fin = i - 1
sets(n) = Mid(s, pio, fin - pio + 1)
pio = i + 1
n += 1
End If
Next i
sets(n) = Mid(s, pio, Len(s) - pio + 1)
' Main logic
For i = 0 To n
p = i
ts = ""
For j = i To 0 Step -1
If ts = "" Then p = j
ts = ""
For k = 1 To Len(sets(p))
If j > 0 Then
If Instr(sets(j-1), Mid(sets(p), k, 1)) = 0 Then ts += Mid(sets(p), k, 1)
End If
Next k
If Len(ts) < Len(sets(p)) Then
If j > 0 Then
sets(j-1) += ts
sets(p) = "-"
ts = ""
End If
Else
p = i
End If
Next j
Next i
' Join the substrings into a string
temp = sets(0)
For i = 1 To n
temp += "," + sets(i)
Next i
Return s + " = " + temp
End Function
 
Dim As String test(3) = {"AB", "AB,CD", "AB,CD,DB", "HIK,AB,CD,DB,FGH"}
For t As Integer = Lbound(test) To Ubound(test)
Print Consolidate(test(t))
Next t
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as Ring entry.</pre>
 
==={{header|Gambas}}===
{{trans|Ring}}
<syntaxhighlight lang="vbnet">Public test As String[] = ["AB", "AB,CD", "AB,CD,DB", "HIK,AB,CD,DB,FGH"]
 
Public Sub Main()
For t As Integer = 0 To test.Max
Print Consolidate(test[t])
Next
 
End
 
Public Function Consolidate(s As String) As String
 
Dim sets As New String[100]
Dim n As Integer, i As Integer, j As Integer, k As Integer, p As Integer
Dim ts As String, tmp As String
n = 0
For i = 1 To Len(s)
If Mid(s, i, 1) = "," Then
n += 1
Else
sets[n] = sets[n] & Mid(s, i, 1)
Endif
Next
For i = 0 To n
p = i
ts = ""
For j = i To 0 Step -1
If ts = "" Then p = j
ts = ""
For k = 1 To Len(sets[p])
If j > 0 Then
If InStr(sets[j - 1], Mid(sets[p], k, 1)) = 0 Then
ts &= Mid(sets[p], k, 1)
Endif
Endif
Next
If Len(ts) < Len(sets[p]) Then
If j > 0 Then
sets[j - 1] &= ts
sets[p] = "-"
ts = ""
Endif
Else
p = i
Endif
Next
Next
tmp = sets[0]
For i = 1 To n
tmp &= "," & sets[i]
Next
Return s & " = " & tmp
 
End</syntaxhighlight>
{{out}}
<pre>Same as Ring entry.</pre>
 
==={{header|GW-BASIC}}===
{{works with|PC-BASIC|any}}
{{works with|BASICA}}
{{works with|Chipmunk Basic}}
{{works with|QBasic}}
{{works with|MSX BASIC}}
<syntaxhighlight lang="qbasic">100 CLS
110 S$ = "AB" : GOSUB 160
120 S$ = "AB,CD" : GOSUB 160
130 S$ = "AB,CD,DB" : GOSUB 160
140 S$ = "HIK,AB,CD,DB,FGH" : GOSUB 160
150 END
160 DIM R$(20)
170 N = 0
180 FOR I = 1 TO LEN(S$)
190 IF MID$(S$,I,1) = "," THEN N = N+1 : GOTO 210
200 R$(N) = R$(N)+MID$(S$,I,1)
210 NEXT I
220 FOR I = 0 TO N
230 P = I
240 TS$ = ""
250 FOR J = I TO 0 STEP -1
260 IF TS$ = "" THEN P = J
270 TS$ = ""
280 FOR K = 1 TO LEN(R$(P))
290 IF J > 0 THEN IF INSTR(R$(J-1),MID$(R$(P),K,1)) = 0 THEN TS$ = TS$+MID$(R$(P),K,1)
300 NEXT K
310 IF LEN(TS$) < LEN(R$(P)) THEN IF J > 0 THEN R$(J-1) = R$(J-1)+TS$ : R$(P) = "-" : TS$ = ""
320 NEXT J
330 NEXT I
340 T$ = R$(0)
350 FOR I = 1 TO N
360 T$ = T$+","+R$(I)
370 NEXT I
380 PRINT S$;" = ";T$
390 ERASE R$
400 RETURN</syntaxhighlight>
{{out}}
<pre>AB = AB
AB,CD = AB,CD
AB,CD,DB = ABCD,-,-
HIK,AB,CD,DB,FGH = HIKFG,ABCD,-,-,-</pre>
 
==={{header|MSX Basic}}===
{{works with|MSX BASIC|any}}
Same code as [[#GW-BASIC|GW-BASIC]]
 
==={{header|PureBasic}}===
<syntaxhighlight lang="purebasic">Procedure.s Consolidate(s.s)
Dim sets.s(100)
Define.i n, i, j, k, p
Define.s ts.s, temp.s
n = 0
For i = 1 To Len(s)
If Mid(s, i, 1) = ",":
n + 1
Else
sets(n) = sets(n) + Mid(s, i, 1)
EndIf
Next i
For i = 0 To n
p = i
ts = ""
For j = i To 0 Step -1
If ts = "":
p = j
EndIf
ts = ""
For k = 1 To Len(sets(p))
If j > 0:
If FindString(sets(j-1), Mid(sets(p), k, 1)) = 0:
ts = ts + Mid(sets(p), k, 1)
EndIf
EndIf
Next k
If Len(ts) < Len(sets(p)):
If j > 0:
sets(j-1) = sets(j-1) + ts
sets(p) = "-"
ts = ""
EndIf
Else
p = i
EndIf
Next j
Next i
temp = sets(0)
For i = 1 To n
temp = temp + "," + sets(i)
Next i
ProcedureReturn s + " = " + temp
EndProcedure
 
OpenConsole()
Dim test.s(3) ;= {"AB","AB,CD","AB,CD,DB","HIK,AB,CD,DB,FGH"}
test(0) = "AB"
test(1) = "AB,CD"
test(2) = "AB,CD,DB"
test(3) = "HIK,AB,CD,DB,FGH"
For t.i = 0 To 3
PrintN(Consolidate(test(t)))
Next t
PrintN(#CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()</syntaxhighlight>
{{out}}
<pre>Same as Ring entry.</pre>
 
==={{header|QBasic}}===
{{trans|Ring}}
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">SUB consolidate (s$)
DIM sets$(100)
n = 0
FOR i = 1 TO LEN(s$)
IF MID$(s$, i, 1) = "," THEN
n = n + 1
ELSE
sets$(n) = sets$(n) + MID$(s$, i, 1)
END IF
NEXT i
 
FOR i = 0 TO n
p = i
ts$ = ""
FOR j = i TO 0 STEP -1
IF ts$ = "" THEN
p = j
END IF
ts$ = ""
FOR k = 1 TO LEN(sets$(p))
IF j > 0 THEN
IF INSTR(sets$(j - 1), MID$(sets$(p), k, 1)) = 0 THEN
ts$ = ts$ + MID$(sets$(p), k, 1)
END IF
END IF
NEXT k
IF LEN(ts$) < LEN(sets$(p)) THEN
IF j > 0 THEN
sets$(j - 1) = sets$(j - 1) + ts$
sets$(p) = "-"
ts$ = ""
END IF
ELSE
p = i
END IF
NEXT j
NEXT i
 
temp$ = sets$(0)
FOR i = 1 TO n
temp$ = temp$ + "," + sets$(i)
NEXT i
 
PRINT s$; " = "; temp$
END SUB
 
DIM test$(3)
test$(0) = "AB"
test$(1) = "AB,CD"
test$(2) = "AB,CD,DB"
test$(3) = "HIK,AB,CD,DB,FGH"
FOR t = 0 TO 3
CALL consolidate(test$(t))
NEXT t</syntaxhighlight>
{{out}}
<pre>Same as Ring entry.</pre>
 
==={{header|Run BASIC}}===
{{trans|QBasic}}
<syntaxhighlight lang="vbnet">function consolidate$(s$)
dim sets$(100)
n = 0
for i = 1 to len(s$)
if mid$(s$, i, 1) = "," then
n = n + 1
else
sets$(n) = sets$(n) + mid$(s$, i, 1)
end if
next i
 
for i = 0 to n
p = i
ts$ = ""
for j = i to 0 step -1
if ts$ = "" then p = j
ts$ = ""
for k = 1 to len(sets$(p))
if j > 0 then
if instr(sets$(j-1), mid$(sets$(p), k, 1)) = 0 then
ts$ = ts$ + mid$(sets$(p), k, 1)
end if
end if
next k
if len(ts$) < len(sets$(p)) then
if j > 0 then
sets$(j-1) = sets$(j-1) + ts$
sets$(p) = "-"
ts$ = ""
end if
else
p = i
end if
next j
next i
 
temp$ = sets$(0)
for i = 1 to n
temp$ = temp$ + "," + sets$(i)
next i
 
consolidate$ = s$ + " = " + temp$
end function
 
dim test$(3)
test$(0) = "AB"
test$(1) = "AB,CD"
test$(2) = "AB,CD,DB"
test$(3) = "HIK,AB,CD,DB,FGH"
for t = 0 to 3
print consolidate$(test$(t))
next t</syntaxhighlight>
 
==={{header|XBasic}}===
{{trans|BASIC256}}
{{works with|Windows XBasic}}
<syntaxhighlight lang="qbasic">PROGRAM "Set consolidation"
VERSION "0.0001"
 
DECLARE FUNCTION Entry ()
DECLARE FUNCTION Consolidate$ (s$)
 
FUNCTION Entry ()
DIM test$[4]
test$[0] = "AB"
test$[1] = "AB,CD"
test$[2] = "AB,CD,DB"
test$[3] = "HIK,AB,CD,DB,FGH"
FOR t = 0 TO 3
PRINT Consolidate$(test$[t])
NEXT t
END FUNCTION
 
FUNCTION Consolidate$ (s$)
DIM sets$[100]
 
' Split the STRING into substrings
pio = 1
n = 0
FOR i = 1 TO LEN(s$)
IF MID$(s$, i, 1) = "," THEN
fin = i - 1
sets$[n] = MID$(s$, pio, fin - pio + 1)
pio = i + 1
INC n
END IF
NEXT i
sets$[n] = MID$(s$, pio, LEN(s$) - pio + 1)
 
' Main logic
FOR i = 0 TO n
p = i
ts$ = ""
FOR j = i TO 0 STEP -1
IF ts$ = "" THEN p = j
ts$ = ""
FOR k = 1 TO LEN(sets$[p])
IF j > 0 THEN
IF INSTR(sets$[j-1], MID$(sets$[p], k, 1)) = 0 THEN
ts$ = ts$ + MID$(sets$[p], k, 1)
END IF
END IF
NEXT k
IF LEN(ts$) < LEN(sets$[p]) THEN
IF j > 0 THEN
sets$[j-1] = sets$[j-1] + ts$
sets$[p] = "-"
ts$ = ""
END IF
ELSE
p = i
END IF
NEXT j
NEXT i
 
' Join the substrings into a STRING
temp$ = sets$[0]
FOR i = 1 TO n
temp$ = temp$ + "," + sets$[i]
NEXT i
 
RETURN s$ + " = " + temp$
END FUNCTION
END PROGRAM</syntaxhighlight>
{{out}}
<pre>Same as BASIC256 entry.</pre>
 
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">dim test$(3)
test$(0) = "AB"
test$(1) = "AB,CD"
test$(2) = "AB,CD,DB"
test$(3) = "HIK,AB,CD,DB,FGH"
for t = 0 to arraysize(test$(), 1)
print Consolidate$(test$(t))
next t
end
 
sub Consolidate$(s$)
dim sets$(100)
 
// Split the string into substrings
pio = 1
n = 0
for i = 1 to len(s$)
if mid$(s$, i, 1) = "," then
fin = i - 1
sets$(n) = mid$(s$, pio, fin - pio + 1)
pio = i + 1
n = n + 1
fi
next i
sets$(n) = mid$(s$, pio, len(s$) - pio + 1)
 
// Main logic
for i = 0 to n
p = i
ts$ = ""
for j = i to 0 step -1
if ts$ = "" p = j
ts$ = ""
for k = 1 to len(sets$(p))
if j > 0 then
if instr(sets$(j-1), mid$(sets$(p), k, 1)) = 0 then
ts$ = ts$ + mid$(sets$(p), k, 1)
fi
fi
next k
if len(ts$) < len(sets$(p)) then
if j > 0 then
sets$(j-1) = sets$(j-1) + ts$
sets$(p) = "-"
ts$ = ""
fi
else
p = i
fi
next j
next i
 
// Join the substrings into a string
temp$ = sets$(0)
for i = 1 to n
temp$ = temp$ + "," + sets$(i)
next i
 
return s$ + " = " + temp$
end sub</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat">( ( consolidate
= a m z mm za zm zz
. ( removeNumFactors
Line 347 ⟶ 919:
& test$(A+B C+D D+B)
& test$(H+I+K A+B C+D D+B F+G+H)
);</langsyntaxhighlight>
{{out}}
<pre>A+B C+D ==> A+B C+D
Line 362 ⟶ 934:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
 
#define s(x) (1U << ((x) - 'A'))
Line 398 ⟶ 970:
puts("\nAfter:"); show_sets(x, consolidate(x, len));
return 0;
}</langsyntaxhighlight>
 
The above is O(N<sup>2</sup>) in terms of number of input sets. If input is large (many sets or huge number of elements), here's an O(N) method, where N is the sum of the sizes of all input sets:
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 502 ⟶ 1,074:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Linq;
using System.Collections.Generic;
Line 538 ⟶ 1,110:
IEqualityComparer<T> comparer = null)
{
ifvar (comparerelements == null)new comparerDictionary<T, = EqualityComparerNode<T>.Default>(comparer );
var elements = new Dictionary<T, Node<T>>();
foreach (var set in sets) {
Node<T> top = null;
Line 611 ⟶ 1,182:
foreach (var set in currentSets) yield return set.Select(value => value);
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 642 ⟶ 1,213:
{H, I, K, F, G}, {A, B, D, C}</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
 
using namespace std;
 
// Consolidation using a brute force approach
void SimpleConsolidate(vector<unordered_set<char>>& sets)
{
// Loop through the sets in reverse and consolidate them
for(auto last = sets.rbegin(); last != sets.rend(); ++last)
for(auto other = last + 1; other != sets.rend(); ++other)
{
bool hasIntersection = any_of(last->begin(), last->end(),
[&](auto val)
{ return other->contains(val); });
if(hasIntersection)
{
other->merge(*last);
sets.pop_back();
break;
}
}
}
 
// As a second approach, use the connected-component-finding-algorithm
// from the C# entry to consolidate
struct Node
{
char Value;
Node* Parent = nullptr;
};
 
Node* FindTop(Node& node)
{
auto top = &node;
while (top != top->Parent) top = top->Parent;
for(auto element = &node; element->Parent != top; )
{
// Point the elements to top to make it faster for the next time
auto parent = element->Parent;
element->Parent = top;
element = parent;
}
return top;
}
 
vector<unordered_set<char>> FastConsolidate(const vector<unordered_set<char>>& sets)
{
unordered_map<char, Node> elements;
for(auto& set : sets)
{
Node* top = nullptr;
for(auto val : set)
{
auto itr = elements.find(val);
if(itr == elements.end())
{
// A new value has been found
auto& ref = elements[val] = Node{val, nullptr};
if(!top) top = &ref;
ref.Parent = top;
}
else
{
auto newTop = FindTop(itr->second);
if(top)
{
top->Parent = newTop;
itr->second.Parent = newTop;
}
else
{
top = newTop;
}
}
}
}
 
unordered_map<char, unordered_set<char>> groupedByTop;
for(auto& e : elements)
{
auto& element = e.second;
groupedByTop[FindTop(element)->Value].insert(element.Value);
}
 
vector<unordered_set<char>> ret;
for(auto& itr : groupedByTop)
{
ret.push_back(move(itr.second));
}
 
return ret;
}
 
void PrintSets(const vector<unordered_set<char>>& sets)
{
for(const auto& set : sets)
{
cout << "{ ";
for(auto value : set){cout << value << " ";}
cout << "} ";
}
cout << "\n";
}
 
int main()
{
const unordered_set<char> AB{'A', 'B'}, CD{'C', 'D'}, DB{'D', 'B'},
HIJ{'H', 'I', 'K'}, FGH{'F', 'G', 'H'};
vector <unordered_set<char>> AB_CD {AB, CD};
vector <unordered_set<char>> AB_DB {AB, DB};
vector <unordered_set<char>> AB_CD_DB {AB, CD, DB};
vector <unordered_set<char>> HIJ_AB_CD_DB_FGH {HIJ, AB, CD, DB, FGH};
 
PrintSets(FastConsolidate(AB_CD));
PrintSets(FastConsolidate(AB_DB));
PrintSets(FastConsolidate(AB_CD_DB));
PrintSets(FastConsolidate(HIJ_AB_CD_DB_FGH));
 
SimpleConsolidate(AB_CD);
SimpleConsolidate(AB_DB);
SimpleConsolidate(AB_CD_DB);
SimpleConsolidate(HIJ_AB_CD_DB_FGH);
 
PrintSets(AB_CD);
PrintSets(AB_DB);
PrintSets(AB_CD_DB);
PrintSets(HIJ_AB_CD_DB_FGH);
}
</syntaxhighlight>
{{out}}
<pre>
{ B A } { D C }
{ B A D }
{ B A D C }
{ B A D C } { I K H G F }
{ B A } { D C }
{ D A B }
{ D C A B }
{ F G H K I } { D C A B }
</pre>
 
=={{header|Clojure}}==
<langsyntaxhighlight Clojurelang="clojure">(defn consolidate-linked-sets [sets]
(apply clojure.set/union sets))
 
Line 661 ⟶ 1,378:
(recur (remove-used (rest seeds) linked)
(conj (remove-used sets linked)
(consolidate-linked-sets linked)))))))</langsyntaxhighlight>
 
{{out}}
Line 675 ⟶ 1,392:
=={{header|Common Lisp}}==
{{trans|Racket}}
<langsyntaxhighlight lang="lisp">(defun consolidate (ss)
(labels ((comb (cs s)
(cond ((null s) cs)
Line 682 ⟶ 1,399:
(cons (first cs) (comb (rest cs) s)))
((consolidate (cons (union s (first cs)) (rest cs)))))))
(reduce #'comb ss :initial-value nil)))</langsyntaxhighlight>
 
{{Out}}
Line 696 ⟶ 1,413:
=={{header|D}}==
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.array;
 
dchar[][] consolidate(dchar[][] sets) @safe {
Line 724 ⟶ 1,441:
[['H','I','K'], ['A','B'], ['C','D'],
['D','B'], ['F','G','H']].consolidate.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>["AB", "CD"]
Line 732 ⟶ 1,449:
 
'''Recursive version''', as described on talk page.
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.array;
 
dchar[][] consolidate(dchar[][] sets) @safe {
Line 763 ⟶ 1,480:
[['H','I','K'], ['A','B'], ['C','D'],
['D','B'], ['F','G','H']].consolidate.writeln;
}</langsyntaxhighlight>
<pre>["AB", "CD"]
["ABD"]
["ABCD"]
["FGHIK", "ABCD"]</pre>
 
=={{header|Draco}}==
<syntaxhighlight lang="draco">type Set = word;
 
proc make_set(*char setdsc) Set:
Set set;
byte pos;
set := 0;
while setdsc* /= '\e' do
pos := setdsc* - 'A';
if pos < 16 then set := set | (1 << pos) fi;
setdsc := setdsc + 1
od;
set
corp
 
proc write_set(Set set) void:
char item;
write('(');
for item from 'A' upto ('A'+15) do
if set & 1 /= 0 then write(item) fi;
set := set >> 1
od;
write(')')
corp
 
proc consolidate([*]Set sets) word:
word i, j, n;
bool change;
n := dim(sets, 1);
 
change := true;
while change do
change := false;
for i from 0 upto n-1 do
for j from i+1 upto n-1 do
if sets[i] & sets[j] /= 0 then
sets[i] := sets[i] | sets[j];
sets[j] := 0;
change := true
fi
od
od
od;
 
for i from 1 upto n-1 do
if sets[i] = 0 then
for j from i+1 upto n-1 do
sets[j-1] := sets[j]
od
fi
od;
 
i := 0;
while i<n and sets[i] /= 0 do i := i+1 od;
i
corp
 
proc test([*]Set sets) void:
word i, n;
n := dim(sets, 1);
for i from 0 upto n-1 do write_set(sets[i]) od;
write(" -> ");
n := consolidate(sets);
for i from 0 upto n-1 do write_set(sets[i]) od;
writeln()
corp
 
proc main() void:
[2]Set ex1;
[2]Set ex2;
[3]Set ex3;
[5]Set ex4;
 
ex1[0]:=make_set("AB"); ex1[1]:=make_set("CD");
ex2[0]:=make_set("AB"); ex2[1]:=make_set("BC");
ex3[0]:=make_set("AB"); ex3[1]:=make_set("CD"); ex3[2]:=make_set("DB");
ex4[0]:=make_set("HIK"); ex4[1]:=make_set("AB"); ex4[2]:=make_set("CD");
ex4[3]:=make_set("DB"); ex4[4]:=make_set("FGH");
 
test(ex1);
test(ex2);
test(ex3);
test(ex4);
corp</syntaxhighlight>
{{out}}
<pre>(AB)(CD) -> (AB)(CD)
(AB)(BC) -> (ABC)
(AB)(CD)(BD) -> (ABCD)
(HIK)(AB)(CD)(BD)(FGH) -> (FGHIK)(ABCD)</pre>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; utility : make a set of sets from a list
(define (make-set* s)
Line 795 ⟶ 1,602:
→ { { a b c d } { f g h i k } }
</syntaxhighlight>
</lang>
 
=={{header|Egison}}==
 
<langsyntaxhighlight lang="egison">
(define $consolidate
(lambda [$xss]
Line 810 ⟶ 1,617:
 
(test (consolidate {{'H' 'I' 'K'} {'A' 'B'} {'C' 'D'} {'D' 'B'} {'F' 'G' 'H'}}))
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="egison">
{"DBAC" "HIKFG"}
</syntaxhighlight>
</lang>
 
=={{header|Ela}}==
This solution emulate sets using linked lists:
<langsyntaxhighlight lang="ela">open list
 
merge [] ys = ys
Line 828 ⟶ 1,635:
where conso xs [] = xs
conso (x::xs)@r (y::ys) | intersect x y <> [] = conso ((merge x y)::xs) ys
| else = conso (r ++ [y]) ys</langsyntaxhighlight>
Usage:
<langsyntaxhighlight lang="ela">open monad io
 
:::IO
Line 838 ⟶ 1,645:
putLn x
y <- return $ consolidate [['A','B'], ['B','D']]
putLn y</langsyntaxhighlight>
 
Output:<pre>[['K','I','F','G','H'],['A','C','D','B']]
Line 844 ⟶ 1,651:
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule RC do
def set_consolidate(sets, result\\[])
def set_consolidate([], result), do: result
Line 866 ⟶ 1,673:
IO.write "#{inspect sets} =>\n\t"
IO.inspect RC.set_consolidate(sets)
end)</langsyntaxhighlight>
 
{{out}}
Line 881 ⟶ 1,688:
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">let (|SeqNode|SeqEmpty|) s =
if Seq.isEmpty s then SeqEmpty
else SeqNode ((Seq.head s), Seq.skip 1 s)
Line 906 ⟶ 1,713:
[["H";"I";"K"]; ["A";"B"]; ["C";"D"]; ["D";"B"]; ["F";"G";"H"]]
]
0</langsyntaxhighlight>
{{out}}
<pre>seq [set ["C"; "D"]; set ["A"; "B"]]
Line 914 ⟶ 1,721:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: arrays kernel sequences sets ;
 
: comb ( x x -- x )
Line 923 ⟶ 1,730:
] if ;
 
: consolidate ( x -- x ) { } [ comb ] reduce ;</langsyntaxhighlight>
{{out}}
<pre>
Line 939 ⟶ 1,746:
=={{header|Go}}==
{{trans|Python}}
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 994 ⟶ 1,801:
}
return true
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,002 ⟶ 1,809:
=={{header|Haskell}}==
 
<langsyntaxhighlight Haskelllang="haskell">import Data.List (intersperse, intercalate)
import qualified Data.Set as S
 
Line 1,027 ⟶ 1,834:
 
showSet :: S.Set Char -> String
showSet = flip intercalate ["{", "}"] . intersperse ',' . S.elems</langsyntaxhighlight>
 
{{Out}}
Line 1,037 ⟶ 1,844:
=={{header|J}}==
 
<langsyntaxhighlight Jlang="j">consolidate=:4 :0/
b=. y 1&e.@e.&> x
(1,-.b)#(~.;x,b#y);y
)</langsyntaxhighlight>
 
In other words, fold each set into a growing list of consolidated sets. When there's any overlap between the newly considered set (<code>x</code>) and any of the list of previously considered sets (<code>y</code>), merge the unique values from all of those into a single set (any remaining sets remain as-is). Here, <code>b</code> selects the overlapping sets from y (and <code>-.b</code> selects the rest of those sets).
 
Examples:
 
<langsyntaxhighlight Jlang="j"> consolidate 'ab';'cd'
┌──┬──┐
│ab│cd│
Line 1,059 ⟶ 1,868:
┌─────┬────┐
│hijfg│abcd│
└─────┴────┘</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|D}}
{{works with|Java|7}}
<langsyntaxhighlight lang="java">import java.util.*;
 
public class SetConsolidation {
Line 1,126 ⟶ 1,935:
return r;
}
}</langsyntaxhighlight>
<pre>[A, B] [D, C]
[D, A, B]
Line 1,133 ⟶ 1,942:
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript">(() => {
'use strict';
 
Line 1,253 ⟶ 2,062:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>{c,d}, and {a,b}
Line 1,264 ⟶ 2,073:
 
Currently, jq does not have a "Set" library, so to save space here, we will use simple but inefficient implementations of set-oriented functions as they are fast for sets of moderate size. Nevertheless, we will represent sets as sorted arrays.
<langsyntaxhighlight lang="jq">def to_set: unique;
 
def union(A; B): (A + B) | unique;
Line 1,270 ⟶ 2,079:
# boolean
def intersect(A;B):
reduce A[] as $x (false; if . then . else (B|index($x)) end) | not | not;</langsyntaxhighlight>
'''Consolidation''':
 
For clarity, the helper functions are presented as top-level functions, but they could be defined as inner functions of the main function, consolidate/0.
 
<langsyntaxhighlight lang="jq"># Input: [i, j, sets] with i < j
# Return [i,j] for a pair that can be combined, else null
def combinable:
Line 1,305 ⟶ 2,114:
end
end;
</syntaxhighlight>
</lang>
'''Examples''':
<langsyntaxhighlight lang="jq">def tests:
[["A", "B"], ["C","D"]],
[["A","B"], ["B","D"]],
Line 1,317 ⟶ 2,126:
tests | to_set | consolidate;
 
test</langsyntaxhighlight>
{{Out}}
<langsyntaxhighlight lang="sh">$ jq -c -n -f Set_consolidation.rc
[["A","B"],["C","D"]]
[["A","B","D"]]
[["A","B","C","D"]]
[["A","B","C","D"],["F","G","H","I","K"]]</langsyntaxhighlight>
 
=={{header|Julia}}==
Line 1,329 ⟶ 2,138:
 
Here I assume that the data are contained in a list of sets. Perhaps a recursive solution would be more elegant, but in this case playing games with a stack works well enough.
<syntaxhighlight lang="julia">
<lang Julia>
function consolidate{T}(a::Array{Set{T},1})
1 < length(a) || return a
Line 1,348 ⟶ 2,157:
return c
end
</syntaxhighlight>
</lang>
 
'''Main'''
<syntaxhighlight lang="julia">
<lang Julia>
p = Set(["A", "B"])
q = Set(["C", "D"])
Line 1,369 ⟶ 2,178:
println("consolidate([p, q, r, s, t]) =\n ",
consolidate([p, q, r, s, t]))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,389 ⟶ 2,198:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun<T : Comparable<T>> consolidateSets(sets: Array<Set<T>>): Set<Set<T>> {
Line 1,423 ⟶ 2,232:
)
for (sets in unconsolidatedSets) println(consolidateSets(sets))
}</langsyntaxhighlight>
 
{{out}}
Line 1,433 ⟶ 2,242:
</pre>
 
=={{header|MathematicaLua}}==
<syntaxhighlight lang="lua">-- SUPPORT:
<lang Mathematica>reduce[x_] :=
function T(t) return setmetatable(t, {__index=table}) end
function S(t) local s=T{} for k,v in ipairs(t) do s[v]=v end return s end
table.each = function(t,f,...) for _,v in pairs(t) do f(v,...) end end
table.copy = function(t) local s=T{} for k,v in pairs(t) do s[k]=v end return s end
table.keys = function(t) local s=T{} for k,_ in pairs(t) do s[#s+1]=k end return s end
table.intersects = function(t1,t2) for k,_ in pairs(t1) do if t2[k] then return true end end return false end
table.union = function(t1,t2) local s=t1:copy() for k,_ in pairs(t2) do s[k]=k end return s end
table.dump = function(t) print('{ '..table.concat(t, ', ')..' }') end
 
-- TASK:
table.consolidate = function(t)
for a = #t, 1, -1 do
local seta = t[a]
for b = #t, a+1, -1 do
local setb = t[b]
if setb and seta:intersects(setb) then
t[a], t[b] = seta:union(setb), nil
end
end
end
return t
end
 
-- TESTING:
examples = {
T{ S{"A","B"}, S{"C","D"} },
T{ S{"A","B"}, S{"B","D"} },
T{ S{"A","B"}, S{"C","D"}, S{"D","B"} },
T{ S{"H","I","K"}, S{"A","B"}, S{"C","D"}, S{"D","B"}, S{"F","G","H"} },
}
for i,example in ipairs(examples) do
print("Given input sets:")
example:each(function(set) set:keys():dump() end)
print("Consolidated output sets:")
example:consolidate():each(function(set) set:keys():dump() end)
print("")
end</syntaxhighlight>
{{out}}
<pre>Given input sets:
{ A, B }
{ C, D }
Consolidated output sets:
{ A, B }
{ C, D }
 
Given input sets:
{ A, B }
{ D, B }
Consolidated output sets:
{ A, D, B }
 
Given input sets:
{ A, B }
{ C, D }
{ B, D }
Consolidated output sets:
{ A, D, C, B }
 
Given input sets:
{ I, H, K }
{ A, B }
{ C, D }
{ B, D }
{ H, G, F }
Consolidated output sets:
{ I, H, K, G, F }
{ A, D, C, B }</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">reduce[x_] :=
Block[{pairs, unique},
pairs =
Line 1,442 ⟶ 2,321:
unique = Complement[Range@Length@x, Flatten@pairs];
Join[Union[Flatten[x[[#]]]] & /@ pairs, x[[unique]]]]
consolidate[x__] := FixedPoint[reduce, {x}]</syntaxhighlight>
 
consolidate[x__] := FixedPoint[reduce, {x}]</lang>
<pre>consolidate[{a, b}, {c, d}]
-> {{a, b}, {c, d}}
 
consolidate[{a, b}, {b, d}]
-> {{a, b, d}}
 
consolidate[{a, b}, {c, d}, {d, b}]
-> {{a, b, c, d}}
 
consolidate[{h, i, k}, {a, b}, {c, d}, {d, b}, {f, g, h}]
-> {{a,b,c,d},{f,g,h,i,k}}</pre>
Line 1,458 ⟶ 2,333:
=={{header|Nim}}==
{{trans|Python}}
<langsyntaxhighlight lang="nim">proc consolidate(sets: seqvarargs[set[char]]): seq[set[char]] =
if len(sets) < 2:
return @sets
var (r, b) = (@[sets[0]], consolidate(sets[1..^1]))
for x in b:
Line 1,469 ⟶ 2,344:
r
 
echo $consolidate(@[{'A', 'B'}, {'C', 'D'}])
echo $consolidate(@[{'A', 'B'}, {'B', 'D'}])
echo $consolidate(@[{'A', 'B'}, {'C', 'D'}, {'D', 'B'}])
echo $consolidate(@[{'H', 'I', 'K'}, {'A', 'B'}, {'C', 'D'}, {'D', 'B'}, {'F', 'G', 'H'}])</langsyntaxhighlight>
 
{{out}}
<pre>
Line 1,483 ⟶ 2,359:
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">let join a b =
List.fold_left (fun acc v ->
if List.mem v acc then acc else v::acc
Line 1,522 ⟶ 2,398:
print_sets (consolidate [["H";"I";"K"]; ["A";"B"]; ["C";"D"]; ["D";"B"];
["F";"G";"H"]]);
;;</langsyntaxhighlight>
 
{{out}}
Line 1,531 ⟶ 2,407:
 
=={{header|ooRexx}}==
<langsyntaxhighlight lang="oorexx">/* REXX ***************************************************************
* 04.08.2013 Walter Pachl using ooRexx features
* (maybe not in the best way -improvements welcome!)
Line 1,646 ⟶ 2,522:
End
End
Return strip(ol)</langsyntaxhighlight>
{{out}}
<pre>
Line 1,678 ⟶ 2,554:
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">cons(V)={
my(v,u,s);
for(i=1,#V,
Line 1,689 ⟶ 2,565:
V=select(v->#v,V);
if(s,cons(V),V)
};</langsyntaxhighlight>
 
=={{header|Perl}}==
We implement the key data structure, a set of sets, as an array containing references to arrays of scalars.
<langsyntaxhighlight lang="perl">use strict;
use English;
use Smart::Comments;
Line 1,739 ⟶ 2,615:
}
return @result;
}</langsyntaxhighlight>
{{out}}
<pre>### Example 1: [
Line 1,787 ⟶ 2,663:
=={{header|Phix}}==
Using strings to represent sets of characters
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function has_intersection(sequence set1, sequence set2)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
for i=1 to length(set1) do
<span style="color: #008080;">function</span> <span style="color: #000000;">has_intersection</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">set1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">set2</span><span style="color: #0000FF;">)</span>
if find(set1[i],set2) then
<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;">set1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
return true
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">set2</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
end if
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return false
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function union(sequence set1, sequence set2)
for i=1 to length(set2) do
<span style="color: #008080;">function</span> <span style="color: #000000;">get_union</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">set1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">set2</span><span style="color: #0000FF;">)</span>
if not find(set2[i],set1) then
<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;">set2</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
set1 = append(set1,set2[i])
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">set1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">set1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">set2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return set1
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">set1</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function consolidate(sequence sets)
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>
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: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sets</span><span style="color: #0000FF;">)</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>
if has_intersection(sets[i],sets[j]) then
<span style="color: #008080;">for</span> <span style="color: #000000;">j</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> <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>
sets[i] = union(sets[i],sets[j])
<span style="color: #008080;">if</span> <span style="color: #000000;">has_intersection</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><span style="color: #000000;">sets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
sets[j..j] = {}
<span style="color: #000000;">sets</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: #000000;">get_union</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><span style="color: #000000;">sets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
end if
<span style="color: #000000;">sets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</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: #0000FF;">{}</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return sets
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">sets</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
?consolidate({"AB","CD"})
?consolidate({"AB","BD"})
<span style="color: #0000FF;">?</span><span style="color: #000000;">consolidate</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"AB"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"CD"</span><span style="color: #0000FF;">})</span>
?consolidate({"AB","CD","DB"})
<span style="color: #0000FF;">?</span><span style="color: #000000;">consolidate</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"AB"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"BD"</span><span style="color: #0000FF;">})</span>
?consolidate({"HIK","AB","CD","DB","FGH"})</lang>
<span style="color: #0000FF;">?</span><span style="color: #000000;">consolidate</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"AB"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"CD"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"DB"</span><span style="color: #0000FF;">})</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">consolidate</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"HIK"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"AB"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"CD"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"DB"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"FGH"</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,831 ⟶ 2,710:
=={{header|PicoLisp}}==
{{trans|Python}}
<langsyntaxhighlight PicoLisplang="picolisp">(de consolidate (S)
(when S
(let R (cons (car S))
Line 1,838 ⟶ 2,717:
(set R (uniq (conc X (car R))))
(conc R (cons X)) ) )
R ) ) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight PicoLisplang="picolisp">: (consolidate '((A B) (C D)))
-> ((A B) (C D))
: (consolidate '((A B) (B D)))
Line 1,847 ⟶ 2,726:
-> ((D B C A))
: (consolidate '((H I K) (A B) (C D) (D B) (F G H)))
-> ((F G H I K) (D B C A))</langsyntaxhighlight>
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">Set: procedure options (main); /* 13 November 2013 */
declare set(20) character (200) varying;
declare e character (1);
Line 1,907 ⟶ 2,786:
end print;
 
end Set;</langsyntaxhighlight>
<pre>
The original sets: {A,B}
Line 1,925 ⟶ 2,804:
Results: {A,B,E,F,G,H} {C,D}
</pre>
 
=={{header|PL/M}}==
<syntaxhighlight lang="plm">100H:
BDOS: PROCEDURE (F,A); DECLARE F BYTE, A ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; GO TO 0; END EXIT;
PUTC: PROCEDURE (C); DECLARE C BYTE; CALL BDOS(2, C); END PUTC;
PUTS: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9, S); END PUTS;
 
BIT: PROCEDURE (I) ADDRESS;
DECLARE I BYTE;
IF I=0 THEN RETURN 1;
RETURN SHL(DOUBLE(1), I);
END BIT;
 
PRINT$SET: PROCEDURE (SET);
DECLARE SET ADDRESS, I BYTE;
CALL PUTC('(');
DO I=0 TO 15;
IF (BIT(I) AND SET) <> 0 THEN CALL PUTC('A' + I);
END;
CALL PUTC(')');
END PRINT$SET;
 
MAKE$SET: PROCEDURE (SETSTR) ADDRESS;
DECLARE SETSTR ADDRESS, ITEM BASED SETSTR BYTE;
DECLARE SET ADDRESS, POS ADDRESS;
SET = 0;
DO WHILE ITEM <> '$';
POS = ITEM - 'A';
IF POS < 16 THEN SET = SET OR BIT(POS);
SETSTR = SETSTR + 1;
END;
RETURN SET;
END MAKE$SET;
 
CONSOLIDATE: PROCEDURE (SETS, N) BYTE;
DECLARE (SETS, S BASED SETS) ADDRESS;
DECLARE (N, I, J, CHANGE) BYTE;
 
STEP:
CHANGE = 0;
DO I=0 TO N-1;
DO J=I+1 TO N-1;
IF (S(I) AND S(J)) <> 0 THEN DO;
S(I) = S(I) OR S(J);
S(J) = 0;
CHANGE = 1;
END;
END;
END;
IF CHANGE THEN GO TO STEP;
 
DO I=0 TO N-1;
IF S(I)=0 THEN
DO J=I+1 TO N-1;
S(J-1) = S(J);
END;
END;
 
DO I=0 TO N-1;
IF S(I)=0 THEN RETURN I;
END;
RETURN N;
END CONSOLIDATE;
 
TEST: PROCEDURE (SETS, N);
DECLARE (SETS, S BASED SETS) ADDRESS;
DECLARE (N, I) BYTE;
DO I=0 TO N-1;
CALL PRINT$SET(S(I));
END;
CALL PUTS(.' -> $');
N = CONSOLIDATE(SETS, N);
DO I=0 TO N-1;
CALL PRINT$SET(S(I));
END;
CALL PUTS(.(13,10,'$'));
END TEST;
 
DECLARE S (5) ADDRESS;
 
S(0) = MAKE$SET(.'AB$'); S(1) = MAKE$SET(.'CD$');
CALL TEST(.S, 2);
S(0) = MAKE$SET(.'AB$'); S(1) = MAKE$SET(.'BD$');
CALL TEST(.S, 2);
S(0) = MAKE$SET(.'AB$'); S(1) = MAKE$SET(.'CD$');
S(2) = MAKE$SET(.'DB$');
CALL TEST(.S, 3);
S(0) = MAKE$SET(.'HIK$'); S(1) = MAKE$SET(.'AB$');
S(2) = MAKE$SET(.'CD$'); S(3) = MAKE$SET(.'DB$');
S(4) = MAKE$SET(.'FGH$');
CALL TEST(.S, 5);
CALL EXIT;
EOF</syntaxhighlight>
{{out}}
<pre>(AB)(CD) -> (AB)(CD)
(AB)(BD) -> (ABD)
(AB)(CD)(BD) -> (ABCD)
(HIK)(AB)(CD)(BD)(FGH) -> (FGHIK)(ABCD)</pre>
 
=={{header|Python}}==
===Python: Iterative===
<langsyntaxhighlight lang="python">def consolidate(sets):
setlist = [s for s in sets if s]
for i, s1 in enumerate(setlist):
Line 1,938 ⟶ 2,916:
s1.clear()
s1 = s2
return [s for s in setlist if s]</langsyntaxhighlight>
 
===Python: Recursive===
<langsyntaxhighlight lang="python">def conso(s):
if len(s) < 2: return s
Line 1,948 ⟶ 2,926:
if r[0].intersection(x): r[0].update(x)
else: r.append(x)
return r</langsyntaxhighlight>
 
===Python: Testing===
The <code>_test</code> function contains solutions to all the examples as well as a check to show the order-independence of the sets given to the consolidate function.
<langsyntaxhighlight lang="python">def _test(consolidate=consolidate):
def freze(list_of_sets):
Line 1,985 ⟶ 2,963:
if __name__ == '__main__':
_test(consolidate)
_test(conso)</langsyntaxhighlight>
 
{{out}}
Line 1,998 ⟶ 2,976:
{{Trans|JavaScript}}
{{Works with|Python|3.7}}
<langsyntaxhighlight lang="python">'''Set consolidation'''
 
from functools import (reduce)
Line 2,070 ⟶ 3,048:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Consolidation of sets of characters:
Line 2,077 ⟶ 3,055:
['ba', 'cd', 'db'] -> [{'d', 'a', 'c', 'b'}]
['ikh', 'ba', 'cd', 'db', 'gfh'] -> [{'d', 'a', 'c', 'b'}, {'i', 'k', 'g', 'h', 'f'}]</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ 0 swap witheach [ bit | ] ] is ->set ( $ --> { )
 
[ say "{" 0 swap
[ dup 0 != while
dup 1 & if [ over emit ]
1 >> dip 1+ again ]
2drop say "} " ] is echoset ( { --> )
 
[ [] swap dup size 1 - times
[ behead over witheach
[ 2dup & iff
[ | swap i^ poke
[] conclude ]
else drop ]
swap dip join ]
join ] is consolidate ( [ --> [ )
 
[ dup witheach echoset
say "--> "
consolidate witheach echoset
cr ] is task ( [ --> )
 
$ "AB" ->set
$ "CD" ->set join
task
$ "AB" ->set
$ "BD" ->set join
task
$ "AB" ->set
$ "CD" ->set join
$ "DB" ->set join
task
$ "HIK" ->set
$ "AB" ->set join
$ "CD" ->set join
$ "DB" ->set join
$ "FGH" ->set join
task</syntaxhighlight>
 
{{out}}
 
<pre>{AB} {CD} --> {AB} {CD}
{AB} {BD} --> {ABD}
{AB} {CD} {BD} --> {ABCD}
{HIK} {AB} {CD} {BD} {FGH} --> {ABCD} {FGHIK}
</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(define (consolidate ss)
Line 2,094 ⟶ 3,121:
(consolidate (list (set 'a 'b) (set 'c 'd) (set 'd 'b)))
(consolidate (list (set 'h 'i 'k) (set 'a 'b) (set 'c 'd) (set 'd 'b) (set 'f 'g 'h)))
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="racket">
(list (set 'b 'a) (set 'd 'c))
(list (set 'a 'b 'c))
(list (set 'a 'b 'd 'c))
(list (set 'g 'h 'k 'i 'f) (set 'a 'b 'd 'c))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>multi consolidate() { () }
multi consolidate(Set \this is copy, *@those) {
gather {
Line 2,121 ⟶ 3,148:
[set(A,B), set(B,D)],
[set(A,B), set(C,D), set(D,B)],
[set(H,I,K), set(A,B), set(C,D), set(D,B), set(F,G,H)];</langsyntaxhighlight>
{{out}}
<pre>set(A, B) set(C, D)
Line 2,131 ⟶ 3,158:
set(H, I, K) set(A, B) set(C, D) set(D, B) set(F, G, H)
==> set(A, B, C, D) set(H, I, K, F, G)</pre>
 
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Test (A B) (C D)>
<Test (A B) (B D)>
<Test (A B) (C D) (D B)>
<Test (H I K) (A B) (C D) (D B) (F G H)>;
};
 
Test {
e.S = <Prout e.S ' -> ' <Consolidate e.S>>;
};
 
Consolidate {
e.SS, <Consolidate1 () e.SS>: {
e.SS = e.SS;
e.SS2 = <Consolidate e.SS2>;
};
};
 
Consolidate1 {
(e.CSS) = e.CSS;
(e.CSS) (e.S) e.SS,
<Consolidate2 (e.CSS) (e.S)>: e.CSS2 =
<Consolidate1 (e.CSS2) e.SS>;
};
 
Consolidate2 {
() (e.S) = (e.S);
((e.S1) e.SS) (e.S), <Overlap (e.S1) (e.S)>: {
True = (<Set e.S1 e.S>) e.SS;
False = (e.S1) <Consolidate2 (e.SS) (e.S)>;
};
};
 
Overlap {
(e.S1) () = False;
(e.S1) (s.I e.S2), e.S1: {
e.L s.I e.R = True;
e.S1 = <Overlap (e.S1) (e.S2)>;
};
};
 
Set {
= ;
s.I e.S, e.S: {
e.L s.I e.R = <Set e.S>;
e.S = s.I <Set e.S>;
};
};</syntaxhighlight>
{{out}}
<pre>(A B )(C D ) -> (A B )(C D )
(A B )(B D ) -> (A B D )
(A B )(C D )(D B ) -> (A B C D )
(H I K )(A B )(C D )(D B )(F G H ) -> (I K F G H )(A B C D )</pre>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program demonstrates a method of set consolidating using some sample sets. */
@.=; @.1 = '{A,B} {C,D}'
@.2 = "{A,B} {B,D}"
Line 2,184 ⟶ 3,266:
 
say ' the new set=' new; say
return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the (internal) default supplied sample sets:}}
<pre>
Line 2,204 ⟶ 3,286:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Set consolidation
 
Line 2,243 ⟶ 3,325:
consolidate = s + " = " + substr(list2str(sets),nl,",")
return consolidate
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,253 ⟶ 3,335:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">require 'set'
 
tests = [[[:A,:B], [:C,:D]],
Line 2,265 ⟶ 3,347:
end
p sets
end</langsyntaxhighlight>
{{out}}
<pre>
Line 2,276 ⟶ 3,358:
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">object SetConsolidation extends App {
def consolidate[Type](sets: Set[Set[Type]]): Set[Set[Type]] = {
var result = sets // each iteration combines two sets and reiterates, else returns
Line 2,302 ⟶ 3,384:
})
 
}</langsyntaxhighlight>
{{out}}
<pre>{A,B} {C,D} -> {A,B} {C,D}
Line 2,308 ⟶ 3,390:
{A,B} {C,D} {D,B} -> {C,D,A,B}
{D,B} {F,G,H} {A,B} {C,D} {H,I,K} -> {F,I,G,H,K} {A,B,C,D}</pre>
 
=={{header|SETL}}==
<syntaxhighlight lang="setl">program set_consolidation;
tests := [
{{'A','B'}, {'C','D'}},
{{'A','B'}, {'B','D'}},
{{'A','B'}, {'C','D'}, {'D','B'}},
{{'H','I','K'}, {'A','B'}, {'C','D'}, {'D','B'}, {'F','G','H'}}
];
 
loop for t in tests do
print(consolidate(t));
end loop;
 
proc consolidate(sets);
outp := {};
loop while sets /= {} do
set_ from sets;
loop until overlap = {} do
overlap := {s : s in sets | exists el in s | el in set_};
set_ +:= {} +/ overlap;
sets -:= overlap;
end loop;
outp with:= set_;
end loop;
return outp;
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>{{A B} {C D}}
{{A B D}}
{{A B C D}}
{{A B C D} {F G H I K}}</pre>
 
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">func consolidate() { [] }
func consolidate(this, *those) {
gather {
Line 2,335 ⟶ 3,450:
].each { |ss|
say (format(ss), "\n\t==> ", format(consolidate(ss...)));
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,346 ⟶ 3,461:
(H I K) (A B) (C D) (D B) (F G H)
==> (A C D B) (I K F G H)
</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 "Set consolidation" in SQL ORACLE 19c
p_list_of_sets -- input string
delimeter by default "|"
*/
with
function set_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;
--
function remove_duplicates(p_set varchar2)
return varchar2 is
v_set varchar2(1000) := p_set;
begin
for i in 1..length(v_set)
loop
v_set := regexp_replace(v_set, substr(v_set, i, 1), '', i+1, 0) ;
end loop;
return v_set;
end;
--
begin
--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, ' ', '') ;
v_list_of_sets := replace(v_list_of_sets, ',', '') ;
--set delimeter "|"
v_list_of_sets := replace(v_list_of_sets, '}{', '|') ;
--
<<loop_through_sets>>
while regexp_count(v_list_of_sets, '[^|]+') > 0
loop
v_set_1 := regexp_substr(v_list_of_sets, '[^|]+', 1, 1) ;
v_pos_set_1 := regexp_instr(v_list_of_sets, '[^|]+', 1, 1) ;
--
<<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_pos_set_2 := regexp_instr(v_list_of_sets, '[^|]+', 1, i+1) ;
--
if regexp_count(v_set_2, '['||v_set_1||']') > 0 then
v_list_of_sets := regexp_replace(v_list_of_sets, v_set_1, remove_duplicates(v_set_1||v_set_2), 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 := v_output||'{'||rtrim(regexp_replace(v_set_1, '([A-Z])', '\1,'), ',') ||'}';
v_list_of_sets := regexp_replace(v_list_of_sets, v_set_1, '', 1, 1) ;
--
end loop loop_through_sets;
--
return replace(nvl(v_output,'{}'),'}{','},{') ;
end;
 
--Test
select lpad('{}',50) || ' ==> ' || set_consolidation('{}') as output from dual
union all
select lpad('{},{}',50) || ' ==> ' || set_consolidation('{},{}') as output from dual
union all
select lpad('{},{B}',50) || ' ==> ' || set_consolidation('{},{B}') as output from dual
union all
select lpad('{D}',50) || ' ==> ' || set_consolidation('{D}') as output from dual
union all
select lpad('{F},{A},{A}',50) || ' ==> ' || set_consolidation('{F},{A},{A}') as output from dual
union all
select lpad('{A,B},{B}',50) || ' ==> ' || set_consolidation('{A,B},{B}') as output from dual
union all
select lpad('{A,D},{D,A}',50) || ' ==> ' || set_consolidation('{A,D},{D,A}') as output from dual
union all
--Test RosettaCode
select '-- Test RosettaCode' as output from dual
union all
select lpad('{A,B},{C,D}',50) || ' ==> ' || set_consolidation('{A,B},{C,D}') as output from dual
union all
select lpad('{A,B},{B,D}',50) || ' ==> ' || set_consolidation('{A,B},{B,D}') as output from dual
union all
select lpad('{A,B},{C,D},{D,B}',50) || ' ==> ' || set_consolidation('{A,B},{C,D},{D,B}') as output from dual
union all
select lpad('{H, I, K}, {A,B}, {C,D}, {D,B}, {F,G,H}',50) || ' ==> ' || set_consolidation('{H, I, K}, {A,B}, {C,D}, {D,B}, {F,G,H}') as output from dual
union all
select lpad('HIK|AB|CD|DB|FGH',50) || ' ==> ' || set_consolidation('HIK|AB|CD|DB|FGH') as output from dual
;
/
</syntaxhighlight>
 
{{out}}
<pre>
{} ==> {}
{},{} ==> {}
{},{B} ==> {B}
{D} ==> {D}
{F},{A},{A} ==> {F},{A}
{A,B},{B} ==> {A,B}
{A,D},{D,A} ==> {A,D}
-- Test RosettaCode
{A,B},{C,D} ==> {A,B},{C,D}
{A,B},{B,D} ==> {A,B,D}
{A,B},{C,D},{D,B} ==> {A,B,D,C}
{H, I, K}, {A,B}, {C,D}, {D,B}, {F,G,H} ==> {H,I,K,F,G},{A,B,D,C}
HIK|AB|CD|DB|FGH ==> {H,I,K,F,G},{A,B,D,C}
</pre>
 
Line 2,352 ⟶ 3,585:
{{tcllib|struct::set}}
This uses just the recursive version, as this is sufficient to handle substantial merges.
<langsyntaxhighlight lang="tcl">package require struct::set
 
proc consolidate {sets} {
Line 2,369 ⟶ 3,602:
}
return [lset r 0 $r0]
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">puts 1:[consolidate {{A B} {C D}}]
puts 2:[consolidate {{A B} {B D}}]
puts 3:[consolidate {{A B} {C D} {D B}}]
puts 4:[consolidate {{H I K} {A B} {C D} {D B} {F G H}}]</langsyntaxhighlight>
{{out}}
<pre>1:{A B} {C D}
Line 2,385 ⟶ 3,618:
Original solution:
 
<langsyntaxhighlight lang="txrlisp">(defun mkset (p x) (set [p x] (or [p x] x)))
 
(defun fnd (p x) (if (eq [p x] x) x (fnd p [p x])))
Line 2,409 ⟶ 3,642:
((a b) (c d) (d b))
((h i k) (a b) (c d) (d b) (f g h)))))
(format t "~s -> ~s\n" test (consoli test)))</langsyntaxhighlight>
 
{{out}}
Line 2,419 ⟶ 3,652:
{{trans|Racket}}
 
<langsyntaxhighlight lang="txrlisp">(defun mkset (items) [group-by identity items])
 
(defun empty-p (set) (zerop (hash-count set)))
Line 2,438 ⟶ 3,671:
((h i k) (a b) (c d) (d b) (f g h)))))
(format t "~s -> ~s\n" test
[mapcar hash-keys (consoli [mapcar mkset test])]))</langsyntaxhighlight>
 
{{out}}
Line 2,449 ⟶ 3,682:
{{trans|Phix}}
This solutions uses collections as sets. The first three coroutines are based on the Phix solution. Two coroutines are written to create the example sets as collections, and another coroutine to show the consolidated set.
<langsyntaxhighlight lang="vb">Private Function has_intersection(set1 As Collection, set2 As Collection) As Boolean
For Each element In set1
On Error Resume Next
Line 2,513 ⟶ 3,746:
show consolidate(ms(Array(mc("AB"), mc("CD"), mc("DB"))))
show consolidate(ms(Array(mc("HIK"), mc("AB"), mc("CD"), mc("DB"), mc("FGH"))))
End Sub</langsyntaxhighlight>{{out}}
<pre>{{A, B}, {C, D}}
{{A, B, D}}
Line 2,520 ⟶ 3,753:
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
<lang vb>
Function consolidate(s)
sets = Split(s,",")
Line 2,554 ⟶ 3,787:
WScript.StdOut.WriteLine consolidate(t)
Next
</syntaxhighlight>
</lang>
 
{{Out}}
Line 2,570 ⟶ 3,803:
 
As Sets are Map-based, iteration (and hence printing) order are undefined.
<langsyntaxhighlight ecmascriptlang="wren">import "./set" for Set
 
var consolidateSets = Fn.new { |sets|
Line 2,607 ⟶ 3,840:
System.print("Unconsolidated: %(sets)")
System.print("Cosolidated : %(consolidateSets.call(sets))\n")
}</langsyntaxhighlight>
 
{{out}}
Line 2,626 ⟶ 3,859:
=={{header|zkl}}==
{{trans|Tcl}}
<langsyntaxhighlight lang="zkl">fcn consolidate(sets){ // set are munged if they are read/write
if(sets.len()<2) return(sets);
r,r0 := List(List()),sets[0];
Line 2,636 ⟶ 3,869:
r[0]=r0;
r
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">fcn prettize(sets){
sets.apply("concat"," ").pump(String,"(%s),".fmt)[0,-1]
}
Line 2,652 ⟶ 3,885:
prettize(sets).print(" --> ");
consolidate(sets) : prettize(_).println();
}</langsyntaxhighlight>
{{out}}
<pre>
2,095

edits