예제 #1
0
        internal static IEnumerable <T> PNN <T>(IEnumerable <T> source, int from, int to, int step)
        {
            to   = -to;
            step = -step;
            int count;
            var buffer = new DynamicRotativeBuffer <T>();

            using (var enumerator = source.GetEnumerator())
            {
                var fromCount   = from + 1;
                var toCount     = to - 1;
                var minToBuffer = Math.Min(fromCount, toCount);
                buffer.BufferUpToCount(enumerator, minToBuffer);
                if (buffer.length == 0)
                {
                    yield break;
                }

                var reachedEnd = buffer.length < minToBuffer;
                if (!reachedEnd)
                {
                    if (fromCount > toCount)
                    {
                        var toSkip = fromCount - toCount;
                        reachedEnd = toSkip != buffer.RotateUpToCount(enumerator, toSkip);
                    }
                    else if (toCount > fromCount)
                    {
                        count = toCount - fromCount;
                        while (count > 0 && enumerator.MoveNext())
                        {
                            --count;
                        }
                        reachedEnd = count > 0;
                    }
                }
                count = buffer.length;
                if (!reachedEnd)
                {
                    count -= enumerator.Skip(count);
                }
            }

            if (count <= 0)
            {
                yield break;
            }

            var head = (buffer.head - 1 + buffer.length) % buffer.length;

            while (count > 0)
            {
                count -= step;
                yield return(buffer.items[head]);

                head = (head - step + buffer.length) % buffer.length;
            }
        }
예제 #2
0
        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;
            }
        }