DEC 202013
Problem Definition
If one has a set of numbers say
{ 2, 4, 7, 9 }
it has a broken sequence because there are missing numbers from the set 2-9. Those missing numbers are:
{ 3, 5, 6, 8 }
Find Missing Numbers In a Sequence
This method is the one I created first. It uses the Linq Aggregate extension to enumerate over the numbers in the set. If there is a gap which is greater than 1 between the numbers (the difference below is > 0 but same concept) then it reports the numbers missing between the two.
public static IEnumerable<int> SequenceFindMissings(this IList<int> sequence){ var missing = new List<int>(); if ((sequence != null) && (sequence.Any())) { sequence.Aggregate((seed, aggr) => { var diff = (aggr - seed) - 1; if (diff > 0) missing.AddRange(Enumerable.Range((aggr - diff), diff)); return aggr; }); } return missing;} |
Quickly Determine Broken Sequence
Is the sequence broken from the first number to the last in the set?
public static bool IsSequenceBroken(this IEnumerable<int> sequence){ bool broken = false; if (sequence != null) { var sequenceAsList = sequence.ToList(); if (sequenceAsList.Any()) { int lastValue = sequence.First(); broken = sequence.Any(value => { if ((value - lastValue) > 1) return true; lastValue = value; return false; }); } } return broken;} |
Report Last Valid Number Before The Break
This is useful in situations where one needs to report where the break happens, say the user is editing in a grid and one highlights the existing number which precedesthe missing number(s).
Example here returns a 2 and 5 which are the numbers which precede the break.
(new List() { 1, 2, 4, 5, 7, 8}).SequenceReportMissingsBreakStarts() |
Here is the method:
public static IEnumerable<int> SequenceReportMissingsBreakStarts(this IList<int> sequence){ var breaks = new List<int>(); if ((sequence != null) && (sequence.Any())) { sequence.Aggregate((seed, aggr) => { var diff = (aggr - seed) - 1; if (diff > 0) breaks.Add(seed); return aggr; }); } return breaks;} |
Full Extension Source With Comments
Here is the code for an easier copy
public static class SequenceExtensions{ /// /// Take a sequence of numbers and if there are any gaps greater than 1 between the numbers, /// report true. /// |
/// A set of numbers to check. /// True if the there is a break in the sequence of numbers. public static bool IsSequenceBroken(this IEnumerable<int> sequence) { bool broken = false; if (sequence != null) { var sequenceAsList = sequence.ToList(); if (sequenceAsList.Any()) { int lastValue = sequence.First(); broken = sequence.Any(value => { if ((value - lastValue) > 1) return true; lastValue = value; return false; }); } } return broken; } /// /// Take a sequence of numbers and report the missing numbers. Stop at first break found. /// /// Set of Numbers /// True of sequence has missing numbers public static IEnumerable<int> SequenceFindMissings(this IList<int> sequence) { var missing = new List<int>(); if ((sequence != null) && (sequence.Any())) { sequence.Aggregate((seed, aggr) => { var diff = (aggr - seed) - 1; if (diff > 0) missing.AddRange(Enumerable.Range((aggr - diff), diff)); return aggr; }); } return missing; } /// /// A missing break start in a sequence is where the drop off occurs in the sequence. /// For example 3, 5, has a missing break start of the #3 for #4 is the missing. /// /// Set of Numbers /// The list of break numbers which exist before the missing numbers. public static IEnumerable<int> SequenceReportMissingsBreakStarts(this IList<int> sequence) { var breaks = new List<int>(); if ((sequence != null) && (sequence.Any())) { sequence.Aggregate((seed, aggr) => { var diff = (aggr - seed) - 1; if (diff > 0) breaks.Add(seed); return aggr; }); } return breaks; }}Hope this helps!
No comments:
Post a Comment