Skip to content

Instantly share code, notes, and snippets.

@ZacharyPatten
Last active May 24, 2021 20:12
Show Gist options
  • Save ZacharyPatten/0dab050cb21796daba610f70076bdee2 to your computer and use it in GitHub Desktop.
Save ZacharyPatten/0dab050cb21796daba610f70076bdee2 to your computer and use it in GitHub Desktop.
Helper method for combining ranges.
using System;
using System.Collections.Generic;
using Towel.DataStructures;
using static Towel.Statics;
namespace ConsoleApp9001
{
class Program
{
static void Main(string[] args)
{
(DateTime, DateTime)[] input = new[]
{
(new DateTime(2000, 1, 1), new DateTime(2002, 1, 1)),
(new DateTime(2000, 1, 1), new DateTime(2009, 1, 1)),
(new DateTime(2003, 1, 1), new DateTime(2009, 1, 1)),
(new DateTime(2011, 1, 1), new DateTime(2016, 1, 1)),
};
var result = CombineRanges(input);
foreach (var range in result)
{
Console.WriteLine(range);
}
}
/// <summary>Simplifies a sequence of ranges by merging ranges without gaps between them.</summary>
/// <param name="ranges">The ranges to be simplified.</param>
/// <returns>A potentially smaller sequence of ranges that have been merged if there were no gaps.</returns>
static IEnumerable<(T A, T B)> CombineRanges<T>(IEnumerable<(T A, T B)> ranges)
{
OmnitreeBoundsLinked<(T A, T B), T> omnitree =
new(
((T A, T B) x, out T min1, out T max1) =>
{
min1 = x.A;
max1 = x.B;
});
foreach (var (A, B) in ranges)
{
bool overlap = false;
T min = default;
T max = default;
omnitree.StepperOverlapped(x =>
{
min = !overlap ? x.A : Minimum(min, x.A);
max = !overlap ? x.B : MaximumValue(max, x.B);
overlap = true;
}, A, B);
if (overlap)
{
min = Minimum(min, A);
max = MaximumValue(max, B);
omnitree.RemoveOverlapped(min, max);
omnitree.Add(new(min, max));
}
else
{
omnitree.Add(new(A, B));
}
}
return omnitree;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment