package com.shekhargulati.ninetynine_problems._01_lists;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static com.shekhargulati.ninetynine_problems._01_lists.P26.combinations;
import static java.util.stream.Collectors.toList;
/**
* (**) Group the elements of a set into disjoint subsets
*/
public class P27 {
/**
* In how many ways can a group of 9 people work in 3 disjoint subgroups of 2, 3 and 4 persons?
* Write a predicate that generates all the possibilities via backtracking
*/
public static <T> List<List<List<T>>> group3(List<T> list) {
/*
1. Find all the combinations of 2
2. For each combination of 2 find combination of 3 in the remaining list
3. add combination of 2, 3 and remaining to the result
*/
List<List<List<T>>> result = new ArrayList<>();
for (List<T> combinationOf2 : combinations(list, 2)) {
List<T> r = remaining(list, combinationOf2);
for (List<T> combinationOf3 : combinations(r, 3)) {
result.add(Stream.of(combinationOf2, combinationOf3, remaining(r, combinationOf3)).collect(toList()));
}
}
return result;
}
public static <T> List<List<List<T>>> group(List<T> list, List<Integer> gss) {
if (gss.isEmpty()) {
List<List<List<T>>> lists = new ArrayList<>();
lists.add(new ArrayList<>());
return lists;
}
int n = gss.get(0);
List<Integer> ns = gss.subList(1, gss.size());
List<List<List<T>>> result = new ArrayList<>();
for (List<T> c : combinations(list, n)) {
List<T> remaining = remaining(list, c);
for (List<List<T>> cg : group(remaining, ns)) {
List<List<T>> sg = new ArrayList<>();
sg.add(c);
sg.addAll(cg);
result.add(sg);
}
}
return result;
}
private static <T> List<T> remaining(List<T> list, List<T> c) {
return list.stream().filter(e -> !c.contains(e)).collect(toList());
}
}