public static class Itertools {
public static List<Integer> range(int start, int end, int step) {
List<Integer> result = new ArrayList<>();
for (int i = start; i < end; i += step) {
result.add(i);
}
return result;
}
public static <T> List<List<T>> permutations(List<T> list) {
if (list.size() == 0) return new ArrayList<>();
if (list.size() == 1) return Collections.singletonList(list);
List<List<T>> result = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
T current = list.get(i);
List<T> remaining = new ArrayList<>(list);
remaining.remove(i);
for (List<T> perm : permutations(remaining)) {
List<T> temp = new ArrayList<>();
temp.add(current);
temp.addAll(perm);
result.add(temp);
}
}
return result;
}
public static <T> List<List<T>> combinations(List<T> list, int r) {
List<List<T>> result = new ArrayList<>();
combinationsHelper(list, r, 0, new ArrayList<>(), result);
return result;
}
private static <T> void combinationsHelper(List<T> list, int r, int start, List<T> current, List<List<T>> result) {
if (current.size() == r) {
result.add(new ArrayList<>(current));
return;
}
for (int i = start; i < list.size(); i++) {
current.add(list.get(i));
combinationsHelper(list, r, i + 1, current, result);
current.remove(current.size() - 1);
}
}
public static <T> List<List<T>> product(List<List<T>> lists) {
List<List<T>> result = new ArrayList<>();
result.add(new ArrayList<>());
for (List<T> list : lists) {
List<List<T>> temp = new ArrayList<>();
for (List<T> r : result) {
for (T t : list) {
List<T> newList = new ArrayList<>(r);
newList.add(t);
temp.add(newList);
}
}
result = temp;
}
return result;
}
public static <T> List<List<T>> combinations_with_replacement(List<T> list, int r) {
List<List<T>> result = new ArrayList<>();
combinationsWithReplacementHelper(list, r, 0, new ArrayList<>(), result);
return result;
}
private static <T> void combinationsWithReplacementHelper(List<T> list, int r, int start, List<T> current, List<List<T>> result) {
if (current.size() == r) {
result.add(new ArrayList<>(current));
return;
}
for (int i = start; i < list.size(); i++) {
current.add(list.get(i));
combinationsWithReplacementHelper(list, r, i, current, result);
current.remove(current.size() - 1);
}
}
}
public static void itertoolsExamples() {
System.out.println("Range: " + Itertools.range(0, 10, 2));
List<Integer> numbers = Arrays.asList(1, 2, 3);
System.out.println("Permutations: " + Itertools.permutations(numbers));
System.out.println("Combinations (n=3, r=2): " + Itertools.combinations(numbers, 2));
List<List<String>> lists = Arrays.asList(
Arrays.asList("A", "B"),
Arrays.asList("X", "Y"),
Arrays.asList("1", "2")
);
System.out.println("Cartesian product: " + Itertools.product(lists));
System.out.println("Combinations with replacement (n=3, r=2): " + Itertools.combinations_with_replacement(numbers, 2));
}
}