using System;
using System.Collections.Generic;
using System.Linq;
public class Range
{
public int Start { get; private set; }
public int End { get; private set; }
public Range(int start, int end)
{
this.Start = (start <= end) ? start : end;
this.End = (end >= start) ? end : start;
}
public bool Contains(int value)
{
if(value >= this.Start && value <= this.End)
{
return true;
}
return false;
}
public bool Overlaps(Range other)
{
if(other == null)
{
return false;
}
if(this.Contains(other.Start) || this.Contains(other.End)
|| other.Contains(this.Start) || other.Contains(this.End))
{
return true;
}
return false;
}
public Range Merge(Range other)
{
if(!this.Overlaps(other))
{
throw new ApplicationException("Can't merge two ranges.");
}
int newStart = (this.Start < other.Start) ? this.Start : other.Start;
int newEnd = (this.End > other.End) ? this.End : other.End;
return new Range(newStart, newEnd);
}
public static Range[] Merge(Range[] ranges)
{
Stack<Range> results = new Stack<Range>();
if(ranges != null)
{
Array.Sort(ranges, CompareRangeByStart);
foreach(var range in ranges)
{
if(results.Count == 0)
{
results.Push(range);
}
else
{
var top = results.Peek();
if(top.Overlaps(range))
{
var union = top.Merge(range);
results.Pop();
results.Push(union);
}
else
{
results.Push(range);
}
}
}
}
return results.Reverse().ToArray();
}
private static int CompareRangeByStart(Range range1, Range range2)
{
return range1.Start - range2.Start;
}
}
// ========================= Test Code =========================
public static class TestClass
{
private static bool AreEqual(Range[] ranges1, Range[] ranges2)
{
if(ranges1 == null && ranges2 == null)
{
return true;
}
if(ranges1 == null || ranges2 == null)
{
return false;
}
if(ranges1.Length != ranges2.Length)
{
return false;
}
for(int i = 0; i < ranges1.Length; ++i)
{
Range range1 = ranges1[i];
Range range2 = ranges2[i];
if(range1.Start != range2.Start || range1.End != range2.End)
{
return false;
}
}
return true;
}
private static void Test(string testName, Range[] input, Range[] expected)
{
Range[] output = Range.Merge(input);
if(AreEqual(output, expected))
{
Console.WriteLine(string.Format("{0} passed", testName));
}
else
{
Console.WriteLine(string.Format("{0} FAILED", testName));
}
}
private static void Test1()
{
Range[] input = new Range[]
{
new Range(5, 15),
new Range(20, 30),
new Range(35, 45),
new Range(10, 25),
new Range(30, 40)
};
Range[] expected = new Range[]
{
new Range(5, 45)
};
Test("Test1", input, expected);
}
private static void Test2()
{
Range[] input = new Range[]
{
new Range(5, 15),
new Range(20, 30),
new Range(35, 45),
new Range(15, 15),
new Range(50, 50)
};
Range[] expected = new Range[]
{
new Range(5, 15),
new Range(20, 30),
new Range(35, 45),
new Range(50, 50)
};
Test("Test2", input, expected);
}
private static void Test3()
{
Range[] input = new Range[]
{
new Range(5, 15),
new Range(35, 45),
new Range(20, 30),
};
Range[] expected = new Range[]
{
new Range(5, 15),
new Range(20, 30),
new Range(35, 45),
};
Test("Test3", input, expected);
}
private static void Test4()
{
Range[] input = new Range[]
{
new Range(10, 25),
new Range(30, 40),
new Range(8, 10),
new Range(32, 40)
};
Range[] expected = new Range[]
{
new Range(8, 25),
new Range(30, 40)
};
Test("Test4", input, expected);
}
private static void Test5()
{
Range[] input = new Range[]
{
new Range(5, 13),
new Range(27, 39),
new Range(8, 19),
new Range(31, 37)
};
Range[] expected = new Range[]
{
new Range(5, 19),
new Range(27, 39)
};
Test("Test5", input, expected);
}
private static void Test6()
{
Range[] input = new Range[]
{
new Range(5, 13),
new Range(27, 39)
};
Range[] expected = new Range[]
{
new Range(5, 13),
new Range(27, 39)
};
Test("Test6", input, expected);
}
private static void Test7()
{
Range[] input = new Range[]
{
new Range(5, 13),
new Range(5, 23),
new Range(30, 43),
new Range(30, 33)
};
Range[] expected = new Range[]
{
new Range(5, 23),
new Range(30, 43)
};
Test("Test7", input, expected);
}
public static void Main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLkxpbnE7CgpwdWJsaWMgY2xhc3MgUmFuZ2UKewogICAgcHVibGljIGludCBTdGFydCB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0KICAgIHB1YmxpYyBpbnQgRW5kIHsgZ2V0OyBwcml2YXRlIHNldDsgfQogICAgCiAgICBwdWJsaWMgUmFuZ2UoaW50IHN0YXJ0LCBpbnQgZW5kKQogICAgewogICAgICAgIHRoaXMuU3RhcnQgPSAoc3RhcnQgPD0gZW5kKSA/IHN0YXJ0IDogZW5kOwogICAgICAgIHRoaXMuRW5kID0gKGVuZCA+PSBzdGFydCkgPyBlbmQgOiBzdGFydDsKICAgIH0KICAgIAogICAgcHVibGljIGJvb2wgQ29udGFpbnMoaW50IHZhbHVlKQogICAgewogICAgICAgIGlmKHZhbHVlID49IHRoaXMuU3RhcnQgJiYgdmFsdWUgPD0gdGhpcy5FbmQpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgCiAgICBwdWJsaWMgYm9vbCBPdmVybGFwcyhSYW5nZSBvdGhlcikKICAgIHsKICAgICAgICBpZihvdGhlciA9PSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZih0aGlzLkNvbnRhaW5zKG90aGVyLlN0YXJ0KSB8fCB0aGlzLkNvbnRhaW5zKG90aGVyLkVuZCkKICAgICAgICAgICAgfHwgb3RoZXIuQ29udGFpbnModGhpcy5TdGFydCkgfHwgb3RoZXIuQ29udGFpbnModGhpcy5FbmQpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIAogICAgcHVibGljIFJhbmdlIE1lcmdlKFJhbmdlIG90aGVyKQogICAgewogICAgICAgIGlmKCF0aGlzLk92ZXJsYXBzKG90aGVyKSkKICAgICAgICB7CiAgICAgICAgICAgIHRocm93IG5ldyBBcHBsaWNhdGlvbkV4Y2VwdGlvbigiQ2FuJ3QgbWVyZ2UgdHdvIHJhbmdlcy4iKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IG5ld1N0YXJ0ID0gKHRoaXMuU3RhcnQgPCBvdGhlci5TdGFydCkgPyB0aGlzLlN0YXJ0IDogb3RoZXIuU3RhcnQ7CiAgICAgICAgaW50IG5ld0VuZCA9ICh0aGlzLkVuZCA+IG90aGVyLkVuZCkgPyB0aGlzLkVuZCA6IG90aGVyLkVuZDsKICAgICAgICAKICAgICAgICByZXR1cm4gbmV3IFJhbmdlKG5ld1N0YXJ0LCBuZXdFbmQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgUmFuZ2VbXSBNZXJnZShSYW5nZVtdIHJhbmdlcykKICAgIHsKICAgICAgICBTdGFjazxSYW5nZT4gcmVzdWx0cyA9IG5ldyBTdGFjazxSYW5nZT4oKTsKICAgICAgICBpZihyYW5nZXMgIT0gbnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIEFycmF5LlNvcnQocmFuZ2VzLCBDb21wYXJlUmFuZ2VCeVN0YXJ0KTsKICAgICAgICAKICAgICAgICAgICAgZm9yZWFjaCh2YXIgcmFuZ2UgaW4gcmFuZ2VzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZihyZXN1bHRzLkNvdW50ID09IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5QdXNoKHJhbmdlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdG9wID0gcmVzdWx0cy5QZWVrKCk7CiAgICAgICAgICAgICAgICAgICAgaWYodG9wLk92ZXJsYXBzKHJhbmdlKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB1bmlvbiA9IHRvcC5NZXJnZShyYW5nZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuUG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuUHVzaCh1bmlvbik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuUHVzaChyYW5nZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiByZXN1bHRzLlJldmVyc2UoKS5Ub0FycmF5KCk7CiAgICB9CiAgICAKICAgIHByaXZhdGUgc3RhdGljIGludCBDb21wYXJlUmFuZ2VCeVN0YXJ0KFJhbmdlIHJhbmdlMSwgUmFuZ2UgcmFuZ2UyKQogICAgewogICAgICAgIHJldHVybiByYW5nZTEuU3RhcnQgLSByYW5nZTIuU3RhcnQ7CiAgICB9Cn0KCi8vID09PT09PT09PT09PT09PT09PT09PT09PT0gVGVzdCBDb2RlID09PT09PT09PT09PT09PT09PT09PT09PT0KcHVibGljIHN0YXRpYyBjbGFzcyBUZXN0Q2xhc3MKewogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbCBBcmVFcXVhbChSYW5nZVtdIHJhbmdlczEsIFJhbmdlW10gcmFuZ2VzMikKICAgIHsKICAgICAgICBpZihyYW5nZXMxID09IG51bGwgJiYgcmFuZ2VzMiA9PSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmKHJhbmdlczEgPT0gbnVsbCB8fCByYW5nZXMyID09IG51bGwpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmKHJhbmdlczEuTGVuZ3RoICE9IHJhbmdlczIuTGVuZ3RoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgcmFuZ2VzMS5MZW5ndGg7ICsraSkKICAgICAgICB7CiAgICAgICAgICAgIFJhbmdlIHJhbmdlMSA9IHJhbmdlczFbaV07CiAgICAgICAgICAgIFJhbmdlIHJhbmdlMiA9IHJhbmdlczJbaV07CiAgICAgICAgICAgIGlmKHJhbmdlMS5TdGFydCAhPSByYW5nZTIuU3RhcnQgfHwgcmFuZ2UxLkVuZCAhPSByYW5nZTIuRW5kKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgVGVzdChzdHJpbmcgdGVzdE5hbWUsIFJhbmdlW10gaW5wdXQsIFJhbmdlW10gZXhwZWN0ZWQpCiAgICB7CiAgICAgICAgUmFuZ2VbXSBvdXRwdXQgPSBSYW5nZS5NZXJnZShpbnB1dCk7CiAgICAgICAgaWYoQXJlRXF1YWwob3V0cHV0LCBleHBlY3RlZCkpCiAgICAgICAgewogICAgICAgICAgICBDb25zb2xlLldyaXRlTGluZShzdHJpbmcuRm9ybWF0KCJ7MH0gcGFzc2VkIiwgdGVzdE5hbWUpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoc3RyaW5nLkZvcm1hdCgiezB9IEZBSUxFRCIsIHRlc3ROYW1lKSk7CiAgICAgICAgfQogICAgfQogICAgCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIFRlc3QxKCkKICAgIHsKICAgICAgICBSYW5nZVtdIGlucHV0ID0gbmV3IFJhbmdlW10gCiAgICAgICAgewogICAgICAgICAgICBuZXcgUmFuZ2UoNSwgMTUpLAogICAgICAgICAgICBuZXcgUmFuZ2UoMjAsIDMwKSwKICAgICAgICAgICAgbmV3IFJhbmdlKDM1LCA0NSksCiAgICAgICAgICAgIG5ldyBSYW5nZSgxMCwgMjUpLAogICAgICAgICAgICBuZXcgUmFuZ2UoMzAsIDQwKQogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgUmFuZ2VbXSBleHBlY3RlZCA9IG5ldyBSYW5nZVtdCiAgICAgICAgewogICAgICAgICAgICBuZXcgUmFuZ2UoNSwgNDUpCiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBUZXN0KCJUZXN0MSIsIGlucHV0LCBleHBlY3RlZCk7CiAgICB9CiAgICAKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgVGVzdDIoKQogICAgewogICAgICAgIFJhbmdlW10gaW5wdXQgPSBuZXcgUmFuZ2VbXSAKICAgICAgICB7CiAgICAgICAgICAgIG5ldyBSYW5nZSg1LCAxNSksCiAgICAgICAgICAgIG5ldyBSYW5nZSgyMCwgMzApLAogICAgICAgICAgICBuZXcgUmFuZ2UoMzUsIDQ1KSwKICAgICAgICAgICAgbmV3IFJhbmdlKDE1LCAxNSksCiAgICAgICAgICAgIG5ldyBSYW5nZSg1MCwgNTApCiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBSYW5nZVtdIGV4cGVjdGVkID0gbmV3IFJhbmdlW10KICAgICAgICB7CiAgICAgICAgICAgIG5ldyBSYW5nZSg1LCAxNSksCiAgICAgICAgICAgIG5ldyBSYW5nZSgyMCwgMzApLAogICAgICAgICAgICBuZXcgUmFuZ2UoMzUsIDQ1KSwKICAgICAgICAgICAgbmV3IFJhbmdlKDUwLCA1MCkKICAgICAgICB9OwogICAgICAgIAogICAgICAgIFRlc3QoIlRlc3QyIiwgaW5wdXQsIGV4cGVjdGVkKTsKICAgIH0KICAgIAogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBUZXN0MygpCiAgICB7CiAgICAgICAgUmFuZ2VbXSBpbnB1dCA9IG5ldyBSYW5nZVtdIAogICAgICAgIHsKICAgICAgICAgICAgbmV3IFJhbmdlKDUsIDE1KSwKICAgICAgICAgICAgbmV3IFJhbmdlKDM1LCA0NSksCiAgICAgICAgICAgIG5ldyBSYW5nZSgyMCwgMzApLAogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgUmFuZ2VbXSBleHBlY3RlZCA9IG5ldyBSYW5nZVtdCiAgICAgICAgewogICAgICAgICAgICBuZXcgUmFuZ2UoNSwgMTUpLAogICAgICAgICAgICBuZXcgUmFuZ2UoMjAsIDMwKSwKICAgICAgICAgICAgbmV3IFJhbmdlKDM1LCA0NSksCiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBUZXN0KCJUZXN0MyIsIGlucHV0LCBleHBlY3RlZCk7CiAgICB9CiAgICAKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgVGVzdDQoKQogICAgewogICAgICAgIFJhbmdlW10gaW5wdXQgPSBuZXcgUmFuZ2VbXSAKICAgICAgICB7CiAgICAgICAgICAgIG5ldyBSYW5nZSgxMCwgMjUpLAogICAgICAgICAgICBuZXcgUmFuZ2UoMzAsIDQwKSwKICAgICAgICAgICAgbmV3IFJhbmdlKDgsIDEwKSwKICAgICAgICAgICAgbmV3IFJhbmdlKDMyLCA0MCkKICAgICAgICB9OwogICAgICAgIAogICAgICAgIFJhbmdlW10gZXhwZWN0ZWQgPSBuZXcgUmFuZ2VbXQogICAgICAgIHsKICAgICAgICAgICAgbmV3IFJhbmdlKDgsIDI1KSwKICAgICAgICAgICAgbmV3IFJhbmdlKDMwLCA0MCkKICAgICAgICB9OwogICAgICAgIAogICAgICAgIFRlc3QoIlRlc3Q0IiwgaW5wdXQsIGV4cGVjdGVkKTsKICAgIH0KICAgIAogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBUZXN0NSgpCiAgICB7CiAgICAgICAgUmFuZ2VbXSBpbnB1dCA9IG5ldyBSYW5nZVtdIAogICAgICAgIHsKICAgICAgICAgICAgbmV3IFJhbmdlKDUsIDEzKSwKICAgICAgICAgICAgbmV3IFJhbmdlKDI3LCAzOSksCiAgICAgICAgICAgIG5ldyBSYW5nZSg4LCAxOSksCiAgICAgICAgICAgIG5ldyBSYW5nZSgzMSwgMzcpCiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBSYW5nZVtdIGV4cGVjdGVkID0gbmV3IFJhbmdlW10KICAgICAgICB7CiAgICAgICAgICAgIG5ldyBSYW5nZSg1LCAxOSksCiAgICAgICAgICAgIG5ldyBSYW5nZSgyNywgMzkpCiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBUZXN0KCJUZXN0NSIsIGlucHV0LCBleHBlY3RlZCk7CiAgICB9CiAgICAKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgVGVzdDYoKQogICAgewogICAgICAgIFJhbmdlW10gaW5wdXQgPSBuZXcgUmFuZ2VbXSAKICAgICAgICB7CiAgICAgICAgICAgIG5ldyBSYW5nZSg1LCAxMyksCiAgICAgICAgICAgIG5ldyBSYW5nZSgyNywgMzkpCiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBSYW5nZVtdIGV4cGVjdGVkID0gbmV3IFJhbmdlW10KICAgICAgICB7CiAgICAgICAgICAgIG5ldyBSYW5nZSg1LCAxMyksCiAgICAgICAgICAgIG5ldyBSYW5nZSgyNywgMzkpCiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBUZXN0KCJUZXN0NiIsIGlucHV0LCBleHBlY3RlZCk7CiAgICB9CiAgICAKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgVGVzdDcoKQogICAgewogICAgICAgIFJhbmdlW10gaW5wdXQgPSBuZXcgUmFuZ2VbXSAKICAgICAgICB7CiAgICAgICAgICAgIG5ldyBSYW5nZSg1LCAxMyksCiAgICAgICAgICAgIG5ldyBSYW5nZSg1LCAyMyksCiAgICAgICAgICAgIG5ldyBSYW5nZSgzMCwgNDMpLAogICAgICAgICAgICBuZXcgUmFuZ2UoMzAsIDMzKQogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgUmFuZ2VbXSBleHBlY3RlZCA9IG5ldyBSYW5nZVtdCiAgICAgICAgewogICAgICAgICAgICBuZXcgUmFuZ2UoNSwgMjMpLAogICAgICAgICAgICBuZXcgUmFuZ2UoMzAsIDQzKQogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgVGVzdCgiVGVzdDciLCBpbnB1dCwgZXhwZWN0ZWQpOwogICAgfQogICAgCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgTWFpbigpCiAgICB7CiAgICAgICAgVGVzdDEoKTsKICAgICAgICBUZXN0MigpOwogICAgICAgIFRlc3QzKCk7CiAgICAgICAgVGVzdDQoKTsKICAgICAgICBUZXN0NSgpOwogICAgICAgIFRlc3Q2KCk7CiAgICAgICAgVGVzdDcoKTsKICAgIH0KfQ==