package ch.claude_martin; import java.util.ArrayList; import java.util.Arrays; import java.util.Set; import java.util.TreeSet; class SomeClass { static boolean test(int a, int b) { return a + 2 == b; } public static void main(final String... args) { // Take the data from the arguments or use the example list: final var data = args.length > 0 ? Arrays.stream(args).mapToInt(Integer::parseInt).sorted().toArray() : new int[] { 1, 2, 5, 7, 8, 9, 11, 12, 14 }; System.out.println(Arrays.toString(data));// [5, 7, 9, 11, 12, 14] final var size = data.length; // three pointers are needed for this. Initially we look at the first two // elements of the data. // When third is used below to find longer progressions and add each sublist to // the result set. var p0 = 0; var p1 = 1; // The result set is a collection of sets. Each of those sets is a progression. var resultSet = new ArrayList>(); // This loops through all possible pairs, but p1 is always < p1: while (p0 < size && p1 < size) { // The set contains at least 2 elements if it is part of the result set: var set = new TreeSet(); var a = data[p0]; var b = data[p1]; if (test(a, b)) { set.add(a); set.add(b); resultSet.add(new TreeSet<>(set)); // Now we look for longer progressions that start with the one we just found: for (var p2 = p1 + 1; p2 < size; p2++) { var c = data[p2]; if (test(b, c)) { set.add(b = c); resultSet.add(new TreeSet<>(set)); } } } p1++; // increment pointer for "b": // But it we go out of bounds we instead increment p0: if (p1 == size) { // And p1 points to the one next to the new p0: p1 = ++p0 + 1; } } // Show the result set: System.out.println(resultSet); } }