internal static IEnumerable <T> NNP <T>(IEnumerable <T> source, int from, int to, int step) { if (from >= to) { yield break; } var buffer = new DynamicRotativeBuffer <T>(); from = -from; to = -to; int count; using (var enumerator = source.GetEnumerator()) { buffer.BufferUpToCount(enumerator, from); count = buffer.length; if (from == count) { count += buffer.RotateUntilEndWithCount(enumerator); } } to = Math.Min(from, count) - to; int head = buffer.head; int i = 0; while (i < to) { i += step; yield return(buffer.items[head]); head = (head + step) % buffer.length; } }
internal static IEnumerable <T> NNN <T>(IEnumerable <T> source, int from, int to, int step) { if (from <= to) { yield break; } from = -from; step = -step; to = -to; var buffer = new DynamicRotativeBuffer <T>(); using (var enumerator = source.GetEnumerator()) { buffer.BufferUpToCount(enumerator, to); if (buffer.length == to) { buffer.RotateUntilEndWithCount(enumerator); } } var length = buffer.length; if (length < from) { yield break; } var head = buffer.head - from; var count = (Math.Min(length - from, to - from - 1) + step) / step; while (count-- > 0) { yield return(buffer.items[(head + length) % length]); head -= step; } }
internal static IEnumerable <T> NPP <T>(IEnumerable <T> source, int from, int?to, int step) { from = -from; var buffer = new DynamicRotativeBuffer <T>(); int count; var offset = 0; if (to.HasValue) { var toValue = to.Value; if (from >= toValue) { using (var enumerator = source.GetEnumerator()) { buffer.BufferUpToCount(enumerator, toValue); if (buffer.length != toValue) { offset = 0; count = buffer.length; } else { var toSkip = from - toValue; if (toSkip != enumerator.Skip(toSkip)) { offset = 0; count = buffer.length; } else { offset = enumerator.Skip(toValue); count = toValue - offset; } } } } else { using (var enumerator = source.GetEnumerator()) { buffer.BufferUpToCount(enumerator, from); count = buffer.length; if (count != from) { offset = 0; } else { var toSkip = toValue - from; if (toSkip != buffer.RotateUpToCount(enumerator, toSkip)) { offset = 0; count = buffer.length; } else { offset = enumerator.Skip(from); count = from - offset; } } } } } else { using (var enumerator = source.GetEnumerator()) { buffer.BufferUpToCount(enumerator, from); if (buffer.length == from) { buffer.RotateUntilEndWithCount(enumerator); } } count = buffer.length; } if (count <= 0) { yield break; } count = (count + step - 1) / step; buffer.head += offset; while (count-- > 0) { yield return(buffer.items[buffer.head % buffer.length]); buffer.head += step; } }