tasks a-s

This commit is contained in:
Ingy döt Net 2013-04-10 23:57:08 -07:00
parent 47bf37c096
commit b83f433714
12433 changed files with 156208 additions and 123 deletions

View file

@ -0,0 +1,20 @@
Given two sets of items then if any item is common to any set then the result of applying ''consolidation'' to those sets is a set of sets whose contents is:
* The two input sets if no common item exists between the two input sets of items.
* The single set that is the union of the two input sets if they share a common item.
Given N sets of items where N>2 then the result is the same as repeatedly replacing all combinations of two sets by their consolidation until no further consolidation between set pairs is possible.
If N<2 then consolidation has no strict meaning and the input can be returned.
;'''Example 1:'''
:Given the two sets <tt>{A,B}</tt> and <tt>{C,D}</tt> then there is no common element between the sets and the result is the same as the input.
;'''Example 2:'''
:Given the two sets <tt>{A,B}</tt> and <tt>{B,D}</tt> then there is a common element <tt>B</tt> between the sets and the result is the single set <tt>{B,D,A}</tt>. (Note that order of items in a set is immaterial: <tt>{A,B,D}</tt> is the same as <tt>{B,D,A}</tt> and <tt>{D,A,B}</tt>, etc).
;'''Example 3:'''
:Given the three sets <tt>{A,B}</tt> and <tt>{C,D}</tt> and <tt>{D,B}</tt> then there is no common element between the sets <tt>{A,B}</tt> and <tt>{C,D}</tt> but the sets <tt>{A,B}</tt> and <tt>{D,B}</tt> do share a common element that consolidates to produce the result <tt>{B,D,A}</tt>. On examining this result with the remaining set, <tt>{C,D}</tt>, they share a common element and so consolidate to the final output of the single set <tt>{A,B,C,D}</tt>
;'''Example 4:'''
:The consolidation of the five sets:
::<tt>{H,I,K}</tt>, <tt>{A,B}</tt>, <tt>{C,D}</tt>, <tt>{D,B}</tt>, and <tt>{F,G,H}</tt>
:Is the two sets:
::<tt>{A, C, B, D}</tt>, and <tt>{G, F, I, H, K}</tt>
'''See also:'''

View file

@ -0,0 +1,27 @@
generic
type Element is (<>);
with function Image(E: Element) return String;
package Set_Cons is
type Set is private;
-- constructor and manipulation functions for type Set
function "+"(E: Element) return Set;
function "+"(Left, Right: Element) return Set;
function "+"(Left: Set; Right: Element) return Set;
function "-"(Left: Set; Right: Element) return Set;
-- compare, unite or output a Set
function Nonempty_Intersection(Left, Right: Set) return Boolean;
function Union(Left, Right: Set) return Set;
function Image(S: Set) return String;
type Set_Vec is array(Positive range <>) of Set;
-- output a Set_Vec
function Image(V: Set_Vec) return String;
private
type Set is array(Element) of Boolean;
end Set_Cons;

View file

@ -0,0 +1,77 @@
package body Set_Cons is
function "+"(E: Element) return Set is
S: Set := (others => False);
begin
S(E) := True;
return S;
end "+";
function "+"(Left, Right: Element) return Set is
begin
return (+Left) + Right;
end "+";
function "+"(Left: Set; Right: Element) return Set is
S: Set := Left;
begin
S(Right) := True;
return S;
end "+";
function "-"(Left: Set; Right: Element) return Set is
S: Set := Left;
begin
S(Right) := False;
return S;
end "-";
function Nonempty_Intersection(Left, Right: Set) return Boolean is
begin
for E in Element'Range loop
if Left(E) and then Right(E) then return True;
end if;
end loop;
return False;
end Nonempty_Intersection;
function Union(Left, Right: Set) return Set is
S: Set := Left;
begin
for E in Right'Range loop
if Right(E) then S(E) := True;
end if;
end loop;
return S;
end Union;
function Image(S: Set) return String is
function Image(S: Set; Found: Natural) return String is
begin
for E in S'Range loop
if S(E) then
if Found = 0 then
return Image(E) & Image((S-E), Found+1);
else
return "," & Image(E) & Image((S-E), Found+1);
end if;
end if;
end loop;
return "";
end Image;
begin
return "{" & Image(S, 0) & "}";
end Image;
function Image(V: Set_Vec) return String is
begin
if V'Length = 0 then
return "";
else
return Image(V(V'First)) & Image(V(V'First+1 .. V'Last));
end if;
end Image;
end Set_Cons;

View file

@ -0,0 +1,40 @@
with Ada.Text_IO, Set_Cons;
procedure Set_Consolidation is
type El_Type is (A, B, C, D, E, F, G, H, I, K);
function Image(El: El_Type) return String is
begin
return El_Type'Image(El);
end Image;
package Helper is new Set_Cons(Element => El_Type, Image => Image);
use Helper;
function Consolidate(List: Set_Vec) return Set_Vec is
begin
for I in List'First .. List'Last - 1 loop
for J in I+1 .. List'Last loop
-- if List(I) and List(J) share an element
-- then recursively consolidate
-- (List(I) union List(J)) followed by List(K), K not in {I, J}
if Nonempty_Intersection(List(I), List(J)) then
return Consolidate
(Union(List(I), List(J))
& List(List'First .. I-1)
& List(I+1 .. J-1)
& List(J+1 .. List'Last));
end if;
end loop;
end loop;
return List;
end Consolidate;
begin
Ada.Text_IO.Put_Line(Image(Consolidate((A+B) & (C+D))));
Ada.Text_IO.Put_Line(Image(Consolidate((A+B) & (B+D))));
Ada.Text_IO.Put_Line(Image(Consolidate((A+B) & (C+D) & (D+B))));
Ada.Text_IO.Put_Line
(Image(Consolidate((H+I+K) & (A+B) & (C+D) & (D+B) & (F+G+H))));
end Set_Consolidation;

View file

@ -0,0 +1,28 @@
( ( consolidate
= a m z mm za zm zz
. ( removeNumFactors
= a m z
. !arg:?a+#%*?m+?z
& !a+!m+removeNumFactors$!z
| !arg
)
& !arg
: ?a
%?`m
( %?z
& !m
: ?
+ ( %@?mm
& !z:?za (?+!mm+?:?zm) ?zz
)
+ ?
)
& consolidate$(!a removeNumFactors$(!m+!zm) !za !zz)
| !arg
)
& (test=.out$(!arg "==>" consolidate$!arg))
& 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)
);

View file

@ -0,0 +1,37 @@
#include <stdio.h>
#define s(x) (1U << ((x) - 'A'))
typedef unsigned int bitset;
int consolidate(bitset *x, int len)
{
int i, j;
for (i = len - 2; i >= 0; i--)
for (j = len - 1; j > i; j--)
if (x[i] & x[j])
x[i] |= x[j], x[j] = x[--len];
return len;
}
void show_sets(bitset *x, int len)
{
bitset b;
while(len--) {
for (b = 'A'; b <= 'Z'; b++)
if (x[len] & s(b)) printf("%c ", b);
putchar('\n');
}
}
int main(void)
{
bitset x[] = { s('A') | s('B'), s('C') | s('D'), s('B') | s('D'),
s('F') | s('G') | s('H'), s('H') | s('I') | s('K') };
int len = sizeof(x) / sizeof(x[0]);
puts("Before:"); show_sets(x, len);
puts("\nAfter:"); show_sets(x, consolidate(x, len));
return 0;
}

View file

@ -0,0 +1,102 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct edge { int to; struct edge *next; };
struct node { int group; struct edge *e; };
int **consolidate(int **x)
{
# define alloc(v, size) v = calloc(size, sizeof(v[0]));
int group, n_groups, n_nodes;
int n_edges = 0;
struct edge *edges, *ep;
struct node *nodes;
int pos, *stack, **ret;
void add_edge(int a, int b) {
ep->to = b;
ep->next = nodes[a].e;
nodes[a].e = ep;
ep++;
}
void traverse(int a) {
if (nodes[a].group) return;
nodes[a].group = group;
stack[pos++] = a;
for (struct edge *e = nodes[a].e; e; e = e->next)
traverse(e->to);
}
n_groups = n_nodes = 0;
for (int i = 0; x[i]; i++, n_groups++)
for (int j = 0; x[i][j]; j++) {
n_edges ++;
if (x[i][j] >= n_nodes)
n_nodes = x[i][j] + 1;
}
alloc(ret, n_nodes);
alloc(nodes, n_nodes);
alloc(stack, n_nodes);
ep = alloc(edges, n_edges);
for (int i = 0; x[i]; i++)
for (int *s = x[i], j = 0; s[j]; j++)
add_edge(s[j], s[j + 1] ? s[j + 1] : s[0]);
group = 0;
for (int i = 1; i < n_nodes; i++) {
if (nodes[i].group) continue;
group++, pos = 0;
traverse(i);
stack[pos++] = 0;
ret[group - 1] = malloc(sizeof(int) * pos);
memcpy(ret[group - 1], stack, sizeof(int) * pos);
}
free(edges);
free(stack);
free(nodes);
// caller is responsible for freeing ret
return realloc(ret, sizeof(ret[0]) * (1 + group));
# undef alloc
}
void show_sets(int **x)
{
for (int i = 0; x[i]; i++) {
printf("%d: ", i);
for (int j = 0; x[i][j]; j++)
printf(" %d", x[i][j]);
putchar('\n');
}
}
int main(void)
{
int *x[] = {
(int[]) {1, 2, 0}, // 0: end of set
(int[]) {3, 4, 0},
(int[]) {3, 1, 0},
(int[]) {0}, // empty set
(int[]) {5, 6, 0},
(int[]) {7, 6, 0},
(int[]) {3, 9, 10, 0},
0 // 0: end of sets
};
puts("input:");
show_sets(x);
puts("components:");
show_sets(consolidate(x));
return 0;
}

View file

@ -0,0 +1,29 @@
import std.stdio, std.algorithm, std.array;
dchar[][] consolidate(dchar[][] sets) {
foreach (set; sets)
set.sort;
foreach (i, ref si; sets[0 .. $ - 1]) {
if (si.empty)
continue;
foreach (ref sj; sets[i + 1 .. $])
if (!sj.empty && !si.setIntersection(sj).empty) {
sj = si.setUnion(sj).uniq.array;
si = null;
}
}
return sets.filter!"!a.empty".array;
}
void main() {
[['A', 'B'], ['C','D']].consolidate.writeln;
[['A','B'], ['B','D']].consolidate.writeln;
[['A','B'], ['C','D'], ['D','B']].consolidate.writeln;
[['H','I','K'], ['A','B'], ['C','D'],
['D','B'], ['F','G','H']].consolidate.writeln;
}

View file

@ -0,0 +1,32 @@
import std.stdio, std.algorithm, std.array;
dchar[][] consolidate(dchar[][] sets) {
foreach (set; sets)
set.sort;
dchar[][] consolidateR(dchar[][] s) {
if (s.length < 2)
return s;
auto r = [s[0]];
foreach (x; consolidateR(s[1 .. $])) {
if (!r[0].setIntersection(x).empty) {
r[0] = r[0].setUnion(x).uniq.array;
} else
r ~= x;
}
return r;
}
return consolidateR(sets);
}
void main() {
[['A', 'B'], ['C','D']].consolidate.writeln;
[['A','B'], ['B','D']].consolidate.writeln;
[['A','B'], ['C','D'], ['D','B']].consolidate.writeln;
[['H','I','K'], ['A','B'], ['C','D'],
['D','B'], ['F','G','H']].consolidate.writeln;
}

View file

@ -0,0 +1,11 @@
open list
merge [] ys = ys
merge (x::xs) ys | x `elem` ys = merge xs ys
| else = merge xs (x::ys)
consolidate (_::[])@xs = xs
consolidate (x::xs) = conso [x] (consolidate xs)
where conso xs [] = xs
conso (x::xs)@r (y::ys) | intersect x y <> [] = conso ((merge x y)::xs) ys
| else = conso (r ++ [y]) ys

View file

@ -0,0 +1,4 @@
open console
consolidate [['H','I','K'], ['A','B'], ['C','D'], ['D','B'], ['F','G','H']] |> writen $
consolidate [['A','B'], ['B','D']] |> writen

View file

@ -0,0 +1,56 @@
package main
import "fmt"
type set map[string]bool
var testCase = []set{
set{"H": true, "I": true, "K": true},
set{"A": true, "B": true},
set{"C": true, "D": true},
set{"D": true, "B": true},
set{"F": true, "G": true, "H": true},
}
func main() {
fmt.Println(consolidate(testCase))
}
func consolidate(sets []set) []set {
setlist := []set{}
for _, s := range sets {
if s != nil && len(s) > 0 {
setlist = append(setlist, s)
}
}
for i, s1 := range setlist {
if len(s1) > 0 {
for _, s2 := range setlist[i+1:] {
if s1.disjoint(s2) {
continue
}
for e := range s1 {
s2[e] = true
delete(s1, e)
}
s1 = s2
}
}
}
r := []set{}
for _, s := range setlist {
if len(s) > 0 {
r = append(r, s)
}
}
return r
}
func (s1 set) disjoint(s2 set) bool {
for e := range s2 {
if s1[e] {
return false
}
}
return true
}

View file

@ -0,0 +1,8 @@
import qualified Data.Set as S
consolidate :: Ord a => [S.Set a] -> [S.Set a]
consolidate = foldl comb []
where comb [] s' = [s']
comb (s:ss) s'
| S.null (s `S.intersection` s') = s : comb ss s'
| otherwise = comb ss (s `S.union` s')

View file

@ -0,0 +1,4 @@
consolidate=:4 :0/
b=. y 1&e.@e.&> x
(1,-.b)#(~.;x,b#y);y
)

View file

@ -0,0 +1,16 @@
consolidate 'ab';'cd'
┌──┬──┐
│ab│cd│
└──┴──┘
consolidate 'ab';'bd'
┌───┐
│abd│
└───┘
consolidate 'ab';'cd';'db'
┌────┐
│abcd│
└────┘
consolidate 'hij';'ab';'cd';'db';'fgh'
┌─────┬────┐
│hijfg│abcd│
└─────┴────┘

View file

@ -0,0 +1,63 @@
import java.util.*;
public class SetConsolidation {
public static void main(String[] args) {
List<Set<Character>> h1 = hashSetList("AB", "CD");
System.out.println(consolidate(h1));
List<Set<Character>> h2 = hashSetList("AB", "BD");
System.out.println(consolidateR(h2));
List<Set<Character>> h3 = hashSetList("AB", "CD", "DB");
System.out.println(consolidate(h3));
List<Set<Character>> h4 = hashSetList("HIK", "AB", "CD", "DB", "FGH");
System.out.println(consolidateR(h4));
}
// iterative
private static <E> List<Set<E>>
consolidate(Collection<? extends Set<E>> sets) {
List<Set<E>> r = new ArrayList<>();
for (Set<E> s : sets) {
List<Set<E>> new_r = new ArrayList<>();
new_r.add(s);
for (Set<E> x : r) {
if (!Collections.disjoint(s, x)) {
s.addAll(x);
} else {
new_r.add(x);
}
}
r = new_r;
}
return r;
}
// recursive
private static <E> List<Set<E>> consolidateR(List<Set<E>> sets) {
if (sets.size() < 2)
return sets;
List<Set<E>> r = new ArrayList<>();
r.add(sets.get(0));
for (Set<E> x : consolidateR(sets.subList(1, sets.size()))) {
if (!Collections.disjoint(r.get(0), x)) {
r.get(0).addAll(x);
} else {
r.add(x);
}
}
return r;
}
private static List<Set<Character>> hashSetList(String... set) {
List<Set<Character>> r = new ArrayList<>();
for (int i = 0; i < set.length; i++) {
r.add(new HashSet<Character>());
for (int j = 0; j < set[i].length(); j++)
r.get(i).add(set[i].charAt(j));
}
return r;
}
}

View file

@ -0,0 +1,10 @@
reduce[x_] :=
Block[{pairs, unique},
pairs =
DeleteCases[
Subsets[Range@
Length@x, {2}], _?(Intersection @@ x[[#]] == {} &)];
unique = Complement[Range@Length@x, Flatten@pairs];
Join[Union[Flatten[x[[#]]]] & /@ pairs, x[[unique]]]]
consolidate[x__] := FixedPoint[reduce, {x}]

View file

@ -0,0 +1,40 @@
let join a b =
List.fold_left (fun acc v ->
if List.mem v acc then acc else v::acc
) b a
let share a b = List.exists (fun x -> List.mem x b) a
let extract p lst =
let rec aux acc = function
| x::xs -> if p x then Some (x, List.rev_append acc xs) else aux (x::acc) xs
| [] -> None
in
aux [] lst
let consolidate sets =
let rec aux acc = function
| [] -> List.rev acc
| x::xs ->
match extract (share x) xs with
| Some (y, ys) -> aux acc ((join x y) :: ys)
| None -> aux (x::acc) xs
in
aux [] sets
let print_sets sets =
print_string "{ ";
List.iter (fun set ->
print_string "{";
print_string (String.concat " " set);
print_string "} "
) sets;
print_endline "}"
let () =
print_sets (consolidate [["A";"B"]; ["C";"D"]]);
print_sets (consolidate [["A";"B"]; ["B";"C"]]);
print_sets (consolidate [["A";"B"]; ["C";"D"]; ["D";"B"]]);
print_sets (consolidate [["H";"I";"K"]; ["A";"B"]; ["C";"D"]; ["D";"B"];
["F";"G";"H"]]);
;;

View file

@ -0,0 +1,12 @@
cons(V)={
my(v,u,s);
for(i=1,#V,
v=V[i];
for(j=i+1,#V,
u=V[j];
if(#setintersect(u,v),V[i]=v=vecsort(setunion(u,v));V[j]=[];s++)
)
);
V=select(v->#v,V);
if(s,cons(V),V)
};

View file

@ -0,0 +1,17 @@
multi consolidate() { () }
multi consolidate(Set \this is copy, *@those) {
gather {
for consolidate |@those -> \that {
if this that { this = that }
else { take that }
}
take this;
}
}
enum Elems ('A'..'Z');
say $_, "\n ==> ", consolidate |$_
for [set(A,B), set(C,D)],
[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)];

View file

@ -0,0 +1,8 @@
(de consolidate (S)
(when S
(let R (cons (car S))
(for X (consolidate (cdr S))
(if (mmeq X (car R))
(set R (uniq (conc X (car R))))
(conc R (cons X)) ) )
R ) ) )

View file

@ -0,0 +1,8 @@
: (consolidate '((A B) (C D)))
-> ((A B) (C D))
: (consolidate '((A B) (B D)))
-> ((B D A))
: (consolidate '((A B) (C D) (D B)))
-> ((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))

View file

@ -0,0 +1,42 @@
def consolidate(sets):
'''
>>> # Define some variables
>>> A,B,C,D,E,F,G,H,I,J,K = 'A,B,C,D,E,F,G,H,I,J,K'.split(',')
>>> # Consolidate some lists of sets
>>> 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', 'C', 'B', 'D'}]
>>> consolidate([{H,I,K}, {A,B}, {C,D}, {D,B}, {F,G,H}])
[{'A', 'C', 'B', 'D'}, {'G', 'F', 'I', 'H', 'K'}]
>>> consolidate([{A,H}, {H,I,K}, {A,B}, {C,D}, {D,B}, {F,G,H}])
[{'A', 'C', 'B', 'D', 'G', 'F', 'I', 'H', 'K'}]
>>> consolidate([{H,I,K}, {A,B}, {C,D}, {D,B}, {F,G,H}, {A,H}])
[{'A', 'C', 'B', 'D', 'G', 'F', 'I', 'H', 'K'}]
>>> # Confirm order-independence
>>> from copy import deepcopy
>>> import itertools
>>> sets = [{H,I,K}, {A,B}, {C,D}, {D,B}, {F,G,H}, {A,H}]
>>> answer = consolidate(deepcopy(sets))
>>> for perm in itertools.permutations(sets):
assert consolidate(deepcopy(perm)) == answer
>>> answer
[{'A', 'C', 'B', 'D', 'G', 'F', 'I', 'H', 'K'}]
>>> len(list(itertools.permutations(sets)))
720
>>>
'''
setlist = [s for s in sets if s]
for i, s1 in enumerate(setlist):
if s1:
for s2 in setlist[i+1:]:
intersection = s1.intersection(s2)
if intersection:
s2.update(s1)
s1.clear()
s1 = s2
return [s for s in setlist if s]

View file

@ -0,0 +1,8 @@
def conso(s):
if len(s) < 2: return s
r, b = [s[0]], conso(s[1:])
for x in b:
if r[0].intersection(x): r[0].update(x)
else: r.append(x)
return r

View file

@ -0,0 +1,53 @@
/*REXX program shows how to consolidate a sample bunch of sets. */
sets.= /*assign all SETS. to null. */
sets.1 = '{A,B} {C,D}'
sets.2 = "{A,B} {B,D}"
sets.3 = '{A,B} {C,D} {D,B}'
sets.4 = '{H,I,K} {A,B} {C,D} {D,B} {F,G,H}'
sets.5 = '{snow,ice,slush,frost,fog} {iceburgs,icecubes} {rain,fog,sleet}'
do j=1 while sets.j\=='' /*traipse through the sample sets*/
call SETcombo sets.j /*have the other guy do the work.*/
end /*j*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────SETcombo subroutine─────────────────*/
SETcombo: procedure; parse arg bunch; n=words(bunch); newBunch=
say ' the old sets=' space(bunch)
do k=1 for n /*change all commas to a blank. */
@.k=translate(word(bunch,k),,'},{') /*create a list of words (=a set)*/
end /*k*/ /*... and also remove the braces.*/
do until \changed; changed=0 /*consolidate some sets (maybe).*/
do set=1 for n-1
do item=1 for words(@.set); x=word(@.set,item)
do other=set+1 to n
if isIn(x,@.other) then do; changed=1
@.set=@.set @.other; @.other=
iterate set
end
end /*other*/
end /*item*/
end /*set*/
end /*until ¬changed*/
do set=1 for n; new= /*remove duplicates in a set. */
do items=1 for words(@.set)
x=word(@.set,items); if x==',' then iterate; if x=='' then leave
new=new x /*start building the new set. */
do forever; if \isIn(x,@.set) then leave
_=wordpos(x,@.set)
@.set=subword(@.set,1,_-1) ',' subword(@.set,_+1) /*purify set.*/
end /*forever*/
end /*items*/
@.set=translate(strip(new),','," ")
end /*set*/
do new=1 for n; if @.new=='' then iterate
newBunch=space(newbunch '{'@.new"}")
end /*new*/
say ' the new sets=' newBunch; say
return
/*──────────────────────────────────isIn subroutine─────────────────────*/
isIn: return wordpos(arg(1),arg(2))\==0 /*is (word) arg1 in set arg2? */

View file

@ -0,0 +1,18 @@
package require struct::set
proc consolidate {sets} {
if {[llength $sets] < 2} {
return $sets
}
set r [list {}]
set r0 [lindex $sets 0]
foreach x [consolidate [lrange $sets 1 end]] {
if {[struct::set size [struct::set intersect $x $r0]]} {
struct::set add r0 $x
} else {
lappend r $x
}
}
return [lset r 0 $r0]
}

View file

@ -0,0 +1,4 @@
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}}]