main.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. function Time(m, d, h, min) {
  2. this.month = m;
  3. this.day = d;
  4. this.hour = h;
  5. this.minutes = min;
  6. }
  7. Time.prototype.minus = function(other) {
  8. if (this.month != other.month || this.day != other.day)
  9. return 60 -this.minutes;
  10. return this.minutes -other.minutes;
  11. }
  12. function LogEvent(line) {
  13. this.time = new Time(
  14. parseInt(line.substr(6, 2)),
  15. parseInt(line.substr(9, 2)),
  16. parseInt(line.substr(12, 2)),
  17. parseInt(line.substr(15, 2))
  18. );
  19. this.isWakeUp = false;
  20. this.isSleep = false;
  21. this.guardNo = -1;
  22. line = line.substr(19);
  23. if (line.startsWith("Guard "))
  24. this.guardNo = parseInt(line.substr(7));
  25. else if (line.startsWith("falls "))
  26. this.isSleep = true;
  27. else if (line.startsWith("wakes "))
  28. this.isWakeUp = true;
  29. }
  30. function Guard(n) {
  31. this.guardNo = n;
  32. this.evts = [];
  33. this.lastFallAsleep = null;
  34. this.lastEvt = null;
  35. this.totalSleep = 0;
  36. }
  37. Guard.prototype.fallAsleep = function(evtTime) {
  38. this.lastFallAsleep = this.lastFallAsleep || evtTime;
  39. }
  40. Guard.prototype.awaken = function(evtTime) {
  41. if (this.lastFallAsleep) {
  42. var duration = evtTime.minus(this.lastFallAsleep);
  43. this.evts.push({
  44. start: this.lastFallAsleep.minutes,
  45. duration: duration
  46. });
  47. this.totalSleep += duration;
  48. }
  49. this.lastFallAsleep = null;
  50. }
  51. Guard.prototype.end = function(evtTime) {
  52. if (this.lastFallAsleep) {
  53. var duration = 60 -this.lastFallAsleep.minutes;
  54. this.evts.push({
  55. start: this.lastFallAsleep.minutes,
  56. duration: duration
  57. });
  58. this.totalSleep += duration;
  59. this.lastFallAsleep = null;
  60. }
  61. }
  62. Guard.prototype.getMostSleepedMinute = function() {
  63. var sleeped = [];
  64. this.evts.forEach((e) => {
  65. for (var i =0; i < e.duration; ++i)
  66. sleeped[i +e.start] = 1 +(sleeped[i +e.start] || 0);
  67. });
  68. var maxSleepedMinute =0;
  69. for (var i =1; i < 60; ++i)
  70. if ((sleeped[i] || 0) > (sleeped[maxSleepedMinute] || 0))
  71. maxSleepedMinute = i;
  72. return maxSleepedMinute;
  73. }
  74. Guard.prototype.countSleepingTimeAtTime = function(time) {
  75. var total = 0;
  76. this.evts.forEach((e) => {
  77. if (time >= e.start && e.start +e.duration > time)
  78. total++;
  79. });
  80. return total;
  81. }
  82. function GuardPool() {
  83. this.guards = {};
  84. }
  85. GuardPool.prototype.getGuard = function(guardNo) {
  86. return this.guards[guardNo] = this.guards[guardNo] || new Guard(guardNo);
  87. }
  88. GuardPool.prototype.getMostSleepingGuard = function() {
  89. var maxSleepingGuard = null;
  90. for (var i in this.guards) {
  91. var g = this.guards[i];
  92. if (!maxSleepingGuard || g.totalSleep > maxSleepingGuard.totalSleep)
  93. maxSleepingGuard = g;
  94. }
  95. return maxSleepingGuard;
  96. }
  97. GuardPool.prototype.getMostSleepingGuardAtTime = function(time) {
  98. var maxSleepingGuard = null,
  99. maxSleepingGuardTime = 0;
  100. for (var i in this.guards) {
  101. var count = this.guards[i].countSleepingTimeAtTime(time);
  102. if (!maxSleepingGuard || count > maxSleepingGuardTime) {
  103. maxSleepingGuard = this.guards[i];
  104. maxSleepingGuardTime = count;
  105. }
  106. }
  107. return {
  108. time: maxSleepingGuardTime,
  109. guard: maxSleepingGuard
  110. };
  111. }
  112. function read(cb) {
  113. require("fs").readFile('./input', 'utf8', (err, data) => {
  114. var lines = data.split("\n").sort();
  115. lines.forEach((line) => {
  116. if (line.length > 0)
  117. cb(new LogEvent(line));
  118. });
  119. cb(null);
  120. });
  121. }
  122. function initGuardPool(cb) {
  123. var guardpool = new GuardPool(),
  124. currentGuard = null;
  125. read(function(logEvt) {
  126. if (logEvt != null) {
  127. if (currentGuard) {
  128. if (logEvt.isSleep)
  129. currentGuard.fallAsleep(logEvt.time);
  130. if (logEvt.isWakeUp)
  131. currentGuard.awaken(logEvt.time);
  132. }
  133. if (logEvt.guardNo >= 0) {
  134. if (currentGuard)
  135. currentGuard.end(logEvt.time);
  136. currentGuard = guardpool.getGuard(logEvt.guardNo);
  137. }
  138. } else {
  139. cb(guardpool);
  140. }
  141. });
  142. }
  143. function ex1() {
  144. initGuardPool((guardpool) => {
  145. var g = guardpool.getMostSleepingGuard();
  146. var mostSleepedMinute = g.getMostSleepedMinute();
  147. console.log("Guard most sleeped: " +g.guardNo +", most sleeped minute: " +mostSleepedMinute);
  148. });
  149. }
  150. function ex2() {
  151. initGuardPool((guardpool) => {
  152. var maxSleepingGuard = null,
  153. mostSleepingTimeGuard = 0,
  154. maxSleepingGuardTime = 0;
  155. for (var i =0; i < 60; ++i) {
  156. var g = guardpool.getMostSleepingGuardAtTime(i);
  157. if (!maxSleepingGuard || g.time > maxSleepingGuardTime) {
  158. mostSleepingTimeGuard = i;
  159. maxSleepingGuardTime = g.time;
  160. maxSleepingGuard = g.guard;
  161. }
  162. }
  163. console.log("Guard most sleeped: " +maxSleepingGuard.guardNo +", most sleeped minute: " +mostSleepingTimeGuard);
  164. });
  165. }
  166. //ex1();
  167. ex2();