예제 #1
0
 public AlignSortedIntervals(SortedIntervals <TFirst> firstIntervals,
                             SortedIntervals <TSecond> secondIntervals, Func <TFirst[], TSecond[], TResult> selector)
 {
     _firstIntervals  = firstIntervals;
     _secondIntervals = secondIntervals;
     _selector        = selector;
 }
예제 #2
0
        public static string Replace <T>(this string s, SortedIntervals <T> intervals, Func <Interval <T>, string> replacement)
        {
            var sb = new StringBuilder();

            try
            {
                var          idx          = 0;
                Interval <T> lastInterval = null;
                foreach (var interval in intervals)
                {
                    if (lastInterval != null && interval.Start < lastInterval.End)
                    {
                        throw new ArgumentException("Intervals should not overlap.");
                    }

                    sb.Append(s.Substring(idx, interval.Start - idx));

                    string replace = replacement(interval) ?? s.Substring(interval);
                    sb.Append(replace);

                    idx          = interval.End;
                    lastInterval = interval;
                }
                sb.Append(s.Substring(idx, s.Length - idx));
            }
            catch (ArgumentOutOfRangeException e)
            {
                throw new ArgumentOutOfRangeException("Interval exceeding string dimensions.", e);
            }

            return(sb.ToString());
        }
예제 #3
0
        private static IEnumerable <List <IInterval <T> > > UnionEnumerator <T>(this SortedIntervals <T> intervals)
        {
            var currentGroup = new List <IInterval <T> >();
            int lastEnd      = int.MinValue;

            foreach (var interval in intervals)
            {
                if (lastEnd == int.MinValue || interval.Start <= lastEnd)
                {
                    currentGroup.Add(interval);
                }
                else
                {
                    yield return(currentGroup);

                    currentGroup = new List <IInterval <T> >()
                    {
                        interval
                    };
                }
                lastEnd = Math.Max(lastEnd, interval.End);
            }

            if (currentGroup.Count > 0)
            {
                yield return(currentGroup);
            }
        }
예제 #4
0
        private static IEnumerable <Interval <T> > RemoveCoveredEnumerator <T>(this SortedIntervals <T> intervals,
                                                                               ContainsMode mode = ContainsMode.NON_STRICT)
        {
            IInterval <T> current = null;

            foreach (var interval in intervals)
            {
                if (current == null)
                {
                    current = interval;
                }
                else if (!current.Contains(interval, mode))
                {
                    yield return(interval);

                    current = interval;
                }
            }
        }
예제 #5
0
        public static IEnumerable <T> Replace <T>(this IEnumerable <T> ts, SortedIntervals <T[]> intervals)
        {
            var            enumerator   = ts.GetEnumerator();
            var            idx          = 0;
            Interval <T[]> lastInterval = null;

            foreach (var interval in intervals)
            {
                if (lastInterval != null && interval.Start < lastInterval.End)
                {
                    throw new ArgumentException("Intervals should not overlap.");
                }

                // Yield elements before interval starts
                for (int i = 0; i < interval.Start - idx; i++)
                {
                    enumerator.MoveNext();
                    yield return(enumerator.Current);
                }

                // Skip elements covered by interval
                for (int i = 0; i < interval.Length; i++)
                {
                    enumerator.MoveNext();
                }

                // Yield elements in interval value
                foreach (var elem in interval.Value())
                {
                    yield return(elem);
                }

                idx          = interval.End;
                lastInterval = interval;
            }

            // Yield elements after last interval end
            while (enumerator.MoveNext())
            {
                yield return(enumerator.Current);
            }
        }
예제 #6
0
        public static IEnumerable <Interval <T[]> > GroupMergedEnumerator <T>(this SortedIntervals <T> intervals)
        {
            var group = new List <Interval <T> >();

            foreach (var interval in intervals)
            {
                if (group.Count > 0 && !group[0].Equals(interval))
                {
                    yield return(new Interval <T[]>(group[0], group.Values().ToArray()));

                    group = new List <Interval <T> >();
                }
                group.Add(interval);
            }

            if (group.Count > 0)
            {
                yield return(new Interval <T[]>(group[0], group.Values().ToArray()));
            }
        }
예제 #7
0
 public static SortedIntervals <T> Inside <T>(this SortedIntervals <T> intervals, IInterval range,
                                              IIntervalInclusionComparer comparer = null)
 {
     return(new SortedIntervals <T>(intervals.AsEnumerable().Inside(range, comparer)));
 }
예제 #8
0
 public static SortedIntervals <T> Translate <T>(this SortedIntervals <T> intervals, int value)
 {
     return(new SortedIntervals <T>(intervals.AsEnumerable().Translate(value)));
 }
예제 #9
0
 public static SortedIntervals <U> Map <T, U>(this SortedIntervals <T> intervals, Func <T, U> selector)
 {
     return(new SortedIntervals <U>(intervals.ToIntervals().Map(selector)));
 }
예제 #10
0
 public static SortedIntervals <TResult> Align <TFirst, TSecond, TResult>(
     this SortedIntervals <TFirst> intervals, SortedIntervals <TSecond> otherIntervals,
     Func <TFirst[], TSecond[], TResult> selector)
 {
     return(new AlignSortedIntervals <TFirst, TSecond, TResult>(intervals, otherIntervals, selector).Execute());
 }
예제 #11
0
 public static SortedIntervals <U> Union <T, U>(this SortedIntervals <T> intervals, Func <IEnumerable <T>, U> reduce)
 {
     return(new SortedIntervals <U>(intervals.UnionEnumerator().Select(g => g.Range(reduce))));
 }
예제 #12
0
 public static SortedIntervals <T[]> Union <T>(this SortedIntervals <T> intervals)
 {
     return(new SortedIntervals <T[]>(intervals.UnionEnumerator().Select(g => g.Range())));
 }
예제 #13
0
 /// <summary>
 /// Filter out the intervals that are entirely covered by another interval, if provided
 /// condition is satisfied. The condition's first parameter is the covering interval,
 /// the second one is the covered interval. If the condition function returns `true` the
 /// covered interval will be removed.
 /// </summary>
 public static SortedIntervals <T> RemoveCovered <T>(this SortedIntervals <T> intervals,
                                                     Func <T, T, bool> condition, ContainsMode mode = ContainsMode.NON_STRICT)
 {
     return(new SortedIntervals <T>(RemoveCoveredEnumerator(intervals, condition, mode)));
 }
예제 #14
0
        public static Alignment <T, T[]> AlignReplace <T>(this T[] ts, SortedIntervals <T[]> intervals)
        {
            var builder = new List <T>();

            string toString;
            var    intervalAlignments = new List <IntervalAlignment <T[]> >();
            var    mappings           = new Dictionary <int, int>();

            try
            {
                var leftIdx  = 0;
                var rightIdx = 0;
                mappings.Add(0, 0);

                Interval <T[]> lastInterval = null;
                foreach (var interval in intervals)
                {
                    if (lastInterval != null && interval.Start < lastInterval.End)
                    {
                        throw new ArgumentException("Intervals should not overlap.");
                    }

                    // Append string segment before interval
                    T[] before = ts.SubArray(leftIdx, interval.Start - leftIdx);
                    builder.AddRange(before);

                    int shift = rightIdx - leftIdx;
                    for (int i = 0; i < before.Length; i++)
                    {
                        var beforeInterval = new Interval <T[]>(leftIdx + i, 1, new[] { before[i] });
                        intervalAlignments.Add(new IntervalAlignment <T[]>(beforeInterval,
                                                                           beforeInterval.Translate(shift), true));
                    }

                    rightIdx += before.Length;

                    var leftContent = ts.SubArray(interval);

                    // Append string replacement
                    var rightContent = interval.Value;
                    builder.AddRange(rightContent);

                    // Store from and to intervals
                    var leftInterval  = new Interval <T[]>(interval, leftContent);
                    var rightInterval = new Interval <T[]>(start: rightIdx, length: rightContent.Length, value: interval.Value);
                    intervalAlignments.Add(new IntervalAlignment <T[]>(leftInterval, rightInterval, false));

                    // Store mappings for intervals start and end positions
                    mappings[interval.Start] = rightInterval.Start;
                    mappings[interval.End]   = rightInterval.End;

                    leftIdx  = interval.End;
                    rightIdx = rightInterval.End;

                    lastInterval = interval;
                }

                // Append string segment after last interval
                var final = ts.SubArray(leftIdx, ts.Length - leftIdx);
                builder.AddRange(final);

                int shift2 = rightIdx - leftIdx;
                for (int i = 0; i < final.Length; i++)
                {
                    var finalInterval = new Interval <T[]>(leftIdx + i, 1, new[] { final[i] });
                    intervalAlignments.Add(new IntervalAlignment <T[]>(finalInterval,
                                                                       finalInterval.Translate(shift2), true));
                }

                // Finalize TO string and store mapping for end of strings
                toString            = builder.ToString();
                mappings[ts.Length] = toString.Length;
            }
            catch (ArgumentOutOfRangeException e)
            {
                throw new ArgumentOutOfRangeException("Interval exceeding string dimensions.", e);
            }

            return(new Alignment <T, T[]>(
                       left: ts,
                       right: builder.ToArray(),
                       intervals: intervalAlignments.ToArray(),
                       mappings: mappings));
        }
예제 #15
0
        public static Alignment <T> AlignReplace <T>(this string s, SortedIntervals <T> intervals, Func <string, string> replacement)
        {
            var    sb = new StringBuilder();
            string toString;
            var    intervalAlignments = new List <IntervalAlignment <T> >();
            var    mappings           = new Dictionary <int, int>();

            try
            {
                var fromIdx = 0;
                var toIdx   = 0;
                mappings.Add(0, 0);

                Interval <T> lastInterval = null;
                foreach (var fromInterval in intervals)
                {
                    if (lastInterval != null && fromInterval.Start < lastInterval.End)
                    {
                        throw new ArgumentException("Intervals should not overlap.");
                    }

                    // Append string segment before interval
                    string before = s.Substring(fromIdx, fromInterval.Start - fromIdx);
                    sb.Append(before);
                    toIdx += before.Length;

                    var fromContent = s.Substring(fromInterval);

                    // Append string replacement
                    var toContent = replacement(fromContent);
                    sb.Append(toContent);

                    // Store from and to intervals
                    var toInterval = new Interval <T>(start: toIdx, length: toContent.Length, value: fromInterval.Value);
                    intervalAlignments.Add(new IntervalAlignment <T>(fromInterval, toInterval, false));

                    // Store mappings for intervals start and end positions
                    mappings[fromInterval.Start] = toInterval.Start;
                    mappings[fromInterval.End]   = toInterval.End;

                    fromIdx = fromInterval.End;
                    toIdx   = toInterval.End;

                    lastInterval = fromInterval;
                }

                // Append string segment after last interval
                sb.Append(s.Substring(fromIdx, s.Length - fromIdx));

                // Finalize TO string and store mapping for end of strings
                toString           = sb.ToString();
                mappings[s.Length] = toString.Length;
            }
            catch (ArgumentOutOfRangeException e)
            {
                throw new ArgumentOutOfRangeException("Interval exceeding string dimensions.", e);
            }

            return(new Alignment <T>(
                       left: s,
                       right: sb.ToString(),
                       intervals: intervalAlignments.ToArray(),
                       mappings: mappings));
        }
예제 #16
0
 public static SortedIntervals <T> IntersectingWith <T>(this SortedIntervals <T> intervals,
                                                        IEnumerable <IInterval> others, ContainsMode mode = ContainsMode.NON_STRICT)
 {
     return(new SortedIntervals <T>(intervals.AsEnumerable().IntersectingWith(others, mode)));
 }
예제 #17
0
 /// <summary>
 /// Filter out the intervals that are entirely covered by another interval.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="intervals"></param>
 /// <returns></returns>
 public static SortedIntervals <T> RemoveCovered <T>(this SortedIntervals <T> intervals,
                                                     ContainsMode mode = ContainsMode.NON_STRICT)
 {
     return(new SortedIntervals <T>(RemoveCoveredEnumerator(intervals, mode)));
 }
예제 #18
0
 public static SortedIntervals <T> IntersectWith <T>(this SortedIntervals <T> intervals, IInterval range)
 {
     return(new SortedIntervals <T>(intervals.AsEnumerable().IntersectWith(range)));
 }
예제 #19
0
 public static SortedIntervals <T[]> GroupMerged <T>(this SortedIntervals <T> intervals)
 {
     return(new SortedIntervals <T[]>(GroupMergedEnumerator(intervals)));
 }
예제 #20
0
 public static string Replace <T>(this string s, SortedIntervals <T> intervals, Func <T, string> replacement)
 {
     return(s.Replace(intervals, i => replacement(i.Value)));
 }