예제 #1
0
        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;
            }
        }
예제 #2
0
        internal static IEnumerable <T> PNP <T>(IEnumerable <T> source, int from, int to, int step)
        {
            to = -to;
            using (var enumerator = source.GetEnumerator())
            {
                if (enumerator.Skip(from) != from)
                {
                    yield break;
                }

                var buffer = new DynamicRotativeBuffer <T>();
                if (step == 1)
                {
                    buffer.BufferUpToCount(enumerator, to);
                    if (buffer.length < to)
                    {
                        yield break;
                    }

                    var head          = 0;
                    var sanitizedHead = 0;
                    while (enumerator.MoveNext())
                    {
                        sanitizedHead = head % to;
                        yield return(buffer.items[sanitizedHead]);

                        buffer.items[sanitizedHead] = enumerator.Current;
                        head++;
                    }
                }
                else
                {
                    if (!buffer.BufferWithStepUpToCount(enumerator, step, to))
                    {
                        yield break;
                    }

                    var head    = 0;
                    var tmpIter = 0;
                    while (enumerator.MoveNext())
                    {
                        if (tmpIter == 0)
                        {
                            yield return(buffer.items[head]);
                        }

                        tmpIter = (tmpIter + 1) % step;
                        to      = to % step;

                        if (to == 0)
                        {
                            buffer.items[head] = enumerator.Current;
                            head = (head + 1) % buffer.length;
                        }
                        ++to;
                    }
                }
            }
        }
예제 #3
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;
            }
        }
예제 #4
0
        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;
            }
        }
예제 #5
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;
            }
        }