Start by making the biggest possible set at the beginning of the sorted list. Then keep removing values from the front until the next one fits, and add as many as possible after the next one too. This makes a new set. Keep track of the largest at any given moment.
Something like this in C#:
static IEnumerable<T[]> CloseSublists<T>(this IEnumerable<T> values, Func<T, T, bool> isClose) where T : IComparable<T> {
var window = new Queue<T>();
var enumerator = values.GetEnumerator();
if (!enumerator.MoveNext()) {
return;
}
bool more;
do {
window.Enqueue(enumerator.Current);
} while ((more = enumerator.MoveNext()) && isClose(window.Peek(), enumerator.Current));
yield return window.ToArray();
while (more) {
do {
window.Dequeue();
} while (window.Count != 0 && !isClose(window.Peek(), enumerator.Current));
do {
window.Enqueue(enumerator.Current);
} while ((more = enumerator.MoveNext()) && isClose(window.Peek(), enumerator.Current));
yield return window.ToArray();
}
}
and
public static T MaxBy<T, TKey>(this IEnumerable<T> items, Func<T, TKey> key) where TKey : IComparable<TKey> {
var enumerator = items.GetEnumerator();
enumerator.MoveNext();
var max = enumerator.Current;
TKey maxKey = key(max);
while (enumerator.MoveNext()) {
T current = enumerator.Current;
TKey currentKey = key(current);
int relation = currentKey.CompareTo(maxKey);
if (relation > 0) {
max = current;
maxKey = currentKey;
}
}
return max;
}
used as:
int[] x = {1, 2, 5, 6, 8, 9, 15};
x.CloseSublists((a, b) => b < a + 5).MaxBy(l => l.Length)