using System;
using System.Collections.Generic;
class Schedule {
public TimeSpan Begin {get;set;}
public TimeSpan End {get;set;}
}
class GalaxySector {
public TimeSpan Begin {get;set;}
public TimeSpan End {get;set;}
}
public class Test
{
private static readonly TimeSpan HalfHour = TimeSpan.Parse("0:30");
private static IEnumerable<Schedule> Group(IList<GalaxySector> all) {
// Protect from division by zero
if (all.Count == 0) {
yield break;
}
// Find initial location
var pos = 0;
while (pos < all.Count) {
var prior = (pos + all.Count - 1) % all.Count;
if (all[prior].End+HalfHour >= all[pos].Begin) {
pos++;
} else {
break;
}
}
pos = pos % all.Count;
// Start grouping items together
var stop = pos;
do {
var start = pos;
var next = (pos+1) % all.Count;
while (next != stop && all[pos].End+HalfHour >= all[next].Begin) {
pos = next;
next = (pos+1) % all.Count;
}
yield return new Schedule {Begin = all[start].Begin, End = all[pos].End};
pos = next;
} while (pos != stop);
}
public static void Main()
{
var all = new GalaxySector[] {
new GalaxySector {Begin=TimeSpan.Parse("0:15"), End=TimeSpan.Parse("2:30")}
, new GalaxySector {Begin=TimeSpan.Parse("2:45"), End=TimeSpan.Parse("3:30")}
, new GalaxySector {Begin=TimeSpan.Parse("8:00"), End=TimeSpan.Parse("9:30")}
, new GalaxySector {Begin=TimeSpan.Parse("10:00"), End=TimeSpan.Parse("11:00")}
, new GalaxySector {Begin=TimeSpan.Parse("11:20"), End=TimeSpan.Parse("12:30")}
, new GalaxySector {Begin=TimeSpan.Parse("14:00"), End=TimeSpan.Parse("16:00")}
, new GalaxySector {Begin=TimeSpan.Parse("18:30"), End=TimeSpan.Parse("19:30")}
, new GalaxySector {Begin=TimeSpan.Parse("19:45"), End=TimeSpan.Parse("21:00")}
, new GalaxySector {Begin=TimeSpan.Parse("22:00"), End=TimeSpan.Parse("23:50")}
};
foreach (var sched in Group(all)) {
Console.WriteLine("{0}..{1}", sched.Begin, sched.End);
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKCmNsYXNzIFNjaGVkdWxlIHsKCXB1YmxpYyBUaW1lU3BhbiBCZWdpbiB7Z2V0O3NldDt9CglwdWJsaWMgVGltZVNwYW4gRW5kIHtnZXQ7c2V0O30KfQpjbGFzcyBHYWxheHlTZWN0b3IgewoJcHVibGljIFRpbWVTcGFuIEJlZ2luIHtnZXQ7c2V0O30KCXB1YmxpYyBUaW1lU3BhbiBFbmQge2dldDtzZXQ7fQp9CgpwdWJsaWMgY2xhc3MgVGVzdAp7CgkKCXByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFRpbWVTcGFuIEhhbGZIb3VyID0gVGltZVNwYW4uUGFyc2UoIjA6MzAiKTsKCQoJcHJpdmF0ZSBzdGF0aWMgSUVudW1lcmFibGU8U2NoZWR1bGU+IEdyb3VwKElMaXN0PEdhbGF4eVNlY3Rvcj4gYWxsKSB7CgkJLy8gUHJvdGVjdCBmcm9tIGRpdmlzaW9uIGJ5IHplcm8KCQlpZiAoYWxsLkNvdW50ID09IDApIHsKCQkJeWllbGQgYnJlYWs7CgkJfQoJCS8vIEZpbmQgaW5pdGlhbCBsb2NhdGlvbgoJCXZhciBwb3MgPSAwOwoJCXdoaWxlIChwb3MgPCBhbGwuQ291bnQpIHsKCQkJdmFyIHByaW9yID0gKHBvcyArIGFsbC5Db3VudCAtIDEpICUgYWxsLkNvdW50OwoJCQlpZiAoYWxsW3ByaW9yXS5FbmQrSGFsZkhvdXIgPj0gYWxsW3Bvc10uQmVnaW4pIHsKCQkJCXBvcysrOwoJCQl9IGVsc2UgewoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJcG9zID0gcG9zICUgYWxsLkNvdW50OwoJCS8vIFN0YXJ0IGdyb3VwaW5nIGl0ZW1zIHRvZ2V0aGVyCgkJdmFyIHN0b3AgPSBwb3M7CgkJZG8gewoJCQl2YXIgc3RhcnQgPSBwb3M7CgkJCXZhciBuZXh0ID0gKHBvcysxKSAlIGFsbC5Db3VudDsKCQkJd2hpbGUgKG5leHQgIT0gc3RvcCAmJiBhbGxbcG9zXS5FbmQrSGFsZkhvdXIgPj0gYWxsW25leHRdLkJlZ2luKSB7CgkJCQlwb3MgPSBuZXh0OwoJCQkJbmV4dCA9IChwb3MrMSkgJSBhbGwuQ291bnQ7CgkJCX0KCQkJeWllbGQgcmV0dXJuIG5ldyBTY2hlZHVsZSB7QmVnaW4gPSBhbGxbc3RhcnRdLkJlZ2luLCBFbmQgPSBhbGxbcG9zXS5FbmR9OwoJCQlwb3MgPSBuZXh0OwoJCX0gd2hpbGUgKHBvcyAhPSBzdG9wKTsKCX0KCQoJcHVibGljIHN0YXRpYyB2b2lkIE1haW4oKQoJewoJCXZhciBhbGwgPSBuZXcgR2FsYXh5U2VjdG9yW10gewoJCQluZXcgR2FsYXh5U2VjdG9yIHtCZWdpbj1UaW1lU3Bhbi5QYXJzZSgiMDoxNSIpLCBFbmQ9VGltZVNwYW4uUGFyc2UoIjI6MzAiKX0KCQksICAgbmV3IEdhbGF4eVNlY3RvciB7QmVnaW49VGltZVNwYW4uUGFyc2UoIjI6NDUiKSwgRW5kPVRpbWVTcGFuLlBhcnNlKCIzOjMwIil9CgkJLAluZXcgR2FsYXh5U2VjdG9yIHtCZWdpbj1UaW1lU3Bhbi5QYXJzZSgiODowMCIpLCBFbmQ9VGltZVNwYW4uUGFyc2UoIjk6MzAiKX0KCQksCW5ldyBHYWxheHlTZWN0b3Ige0JlZ2luPVRpbWVTcGFuLlBhcnNlKCIxMDowMCIpLCBFbmQ9VGltZVNwYW4uUGFyc2UoIjExOjAwIil9CgkJLAluZXcgR2FsYXh5U2VjdG9yIHtCZWdpbj1UaW1lU3Bhbi5QYXJzZSgiMTE6MjAiKSwgRW5kPVRpbWVTcGFuLlBhcnNlKCIxMjozMCIpfQoJCSwJbmV3IEdhbGF4eVNlY3RvciB7QmVnaW49VGltZVNwYW4uUGFyc2UoIjE0OjAwIiksIEVuZD1UaW1lU3Bhbi5QYXJzZSgiMTY6MDAiKX0KCQksCW5ldyBHYWxheHlTZWN0b3Ige0JlZ2luPVRpbWVTcGFuLlBhcnNlKCIxODozMCIpLCBFbmQ9VGltZVNwYW4uUGFyc2UoIjE5OjMwIil9CgkJLAluZXcgR2FsYXh5U2VjdG9yIHtCZWdpbj1UaW1lU3Bhbi5QYXJzZSgiMTk6NDUiKSwgRW5kPVRpbWVTcGFuLlBhcnNlKCIyMTowMCIpfQoJCSwJbmV3IEdhbGF4eVNlY3RvciB7QmVnaW49VGltZVNwYW4uUGFyc2UoIjIyOjAwIiksIEVuZD1UaW1lU3Bhbi5QYXJzZSgiMjM6NTAiKX0KCQl9OwoJCWZvcmVhY2ggKHZhciBzY2hlZCBpbiBHcm91cChhbGwpKSB7CgkJCUNvbnNvbGUuV3JpdGVMaW5lKCJ7MH0uLnsxfSIsIHNjaGVkLkJlZ2luLCBzY2hlZC5FbmQpOwoJCX0KCX0KfQ==