fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. Console.WriteLine("Q1: " + new[]
  10. {
  11. new FromTo(12, 0, 13, 0),
  12. new FromTo(10, 0, 12, 15)
  13. }.Intersection().Normalize().Join(", "));
  14.  
  15. Console.WriteLine("Q2: " + new[]
  16. {
  17. new FromTo(16, 0, 23, 0),
  18. new FromTo(9, 0, 17, 0),
  19. new FromTo(5, 0, 10, 30)
  20. }.Intersection().Normalize().Join(", "));
  21.  
  22. Console.WriteLine("Q3: " + new[]
  23. {
  24. new FromTo(12, 0, 23, 0),
  25. new FromTo(13, 0, 14, 0),
  26. new FromTo(15, 0, 16, 0),
  27. new FromTo(17, 0, 18, 0),
  28. new FromTo(19, 0, 20, 0),
  29. new FromTo(21, 0, 22, 0)
  30. }.Intersection().Normalize().Join(", "));
  31.  
  32. Console.WriteLine("Q4: " + new[]
  33. {
  34. new FromTo(10, 0, 12, 0),
  35. new FromTo(11, 0, 11, 30),
  36. new FromTo(10, 30, 11, 15)
  37. }.Intersection().Normalize().Join(", "));
  38.  
  39. Console.WriteLine("Q5: " + new[]
  40. {
  41. new FromTo(9, 0, 17, 0),
  42. new FromTo(19, 0, 21, 0)
  43. }.Intersection().Normalize().Join(", "));
  44. }
  45. }
  46.  
  47. struct FromTo
  48. {
  49. public readonly TimeSpan From;
  50. public readonly TimeSpan To;
  51.  
  52. public FromTo(TimeSpan from, TimeSpan to)
  53. {
  54. if (!Validate(from, to))
  55. throw new ArgumentException();
  56. this.From = from;
  57. this.To = to;
  58. }
  59.  
  60. public FromTo(int fromHours, int fromMinutes, int toHours, int toMinutes)
  61. : this(Convert(fromHours, fromMinutes), Convert(toHours, toMinutes))
  62. {
  63. }
  64.  
  65. private static TimeSpan Convert(int hours, int minutes)
  66. {
  67. TimeSpan result = new TimeSpan(hours, minutes, 0);
  68. if (result.Hours != hours || result.Minutes != minutes)
  69. throw new ArgumentException();
  70. return result;
  71. }
  72.  
  73. private static bool Validate(TimeSpan from, TimeSpan to)
  74. {
  75. return (TimeSpan.Zero <= from && from <= to && to <= new TimeSpan(24, 0, 0));
  76. }
  77.  
  78. public bool IsEmpty
  79. {
  80. get { return this.From == this.To; }
  81. }
  82.  
  83. public override string ToString()
  84. {
  85. return string.Format(
  86. "{0:00}:{1:00}-{2:00}:{3:00}",
  87. this.From.Hours, this.From.Minutes, this.To.Hours, this.To.Minutes);
  88. }
  89. }
  90.  
  91. static class FromToEx
  92. {
  93. public static string Join(this IEnumerable<FromTo> source, string separator)
  94. {
  95. return string.Join(separator, source.Select(x => x.ToString()).ToArray());
  96. }
  97.  
  98. public static IEnumerable<FromTo> Normalize(this IEnumerable<FromTo> source)
  99. {
  100. var ordered = source.OrderBy(x => x.From);
  101. var prev = default(FromTo);
  102. foreach (var current in ordered)
  103. {
  104. if (prev.To <= current.From)
  105. {
  106. // prevとcurrentが重なっていない
  107. if (!prev.IsEmpty)
  108. yield return prev;
  109. prev = current;
  110. }
  111. else
  112. {
  113. // prevとcurrentが重なっているので、結合する
  114. var from = prev.From;
  115. var to = (prev.To < current.To) ? current.To : prev.To;
  116. prev = new FromTo(from, to);
  117. }
  118. }
  119. if (!prev.IsEmpty)
  120. {
  121. yield return prev;
  122. }
  123. }
  124.  
  125. public static IEnumerable<FromTo> Intersection(this IEnumerable<FromTo> source)
  126. {
  127. var ordered = source.OrderBy(x => x.From);
  128. var prev = default(FromTo);
  129. foreach (var current in ordered)
  130. {
  131. if (prev.To <= current.From)
  132. {
  133. // prevとcurrentが重なっていない
  134. prev = current;
  135. }
  136. else
  137. {
  138. // prevとcurrentが重なっているので、重なっている部分を取り出す
  139. var from = current.From;
  140. var to = (prev.To < current.To) ? prev.To : current.To;
  141. yield return new FromTo(from, to);
  142. prev = (prev.To < current.To) ? current : prev;
  143. }
  144. }
  145. }
  146. }
Success #stdin #stdout 0.03s 38200KB
stdin
Standard input is empty
stdout
Q1: 12:00-12:15
Q2: 09:00-10:30, 16:00-17:00
Q3: 13:00-14:00, 15:00-16:00, 17:00-18:00, 19:00-20:00, 21:00-22:00
Q4: 10:30-11:30
Q5: