function Time(m, d, h, min) { this.month = m; this.day = d; this.hour = h; this.minutes = min; } Time.prototype.minus = function(other) { if (this.month != other.month || this.day != other.day) return 60 -this.minutes; return this.minutes -other.minutes; } function LogEvent(line) { this.time = new Time( parseInt(line.substr(6, 2)), parseInt(line.substr(9, 2)), parseInt(line.substr(12, 2)), parseInt(line.substr(15, 2)) ); this.isWakeUp = false; this.isSleep = false; this.guardNo = -1; line = line.substr(19); if (line.startsWith("Guard ")) this.guardNo = parseInt(line.substr(7)); else if (line.startsWith("falls ")) this.isSleep = true; else if (line.startsWith("wakes ")) this.isWakeUp = true; } function Guard(n) { this.guardNo = n; this.evts = []; this.lastFallAsleep = null; this.lastEvt = null; this.totalSleep = 0; } Guard.prototype.fallAsleep = function(evtTime) { this.lastFallAsleep = this.lastFallAsleep || evtTime; } Guard.prototype.awaken = function(evtTime) { if (this.lastFallAsleep) { var duration = evtTime.minus(this.lastFallAsleep); this.evts.push({ start: this.lastFallAsleep.minutes, duration: duration }); this.totalSleep += duration; } this.lastFallAsleep = null; } Guard.prototype.end = function(evtTime) { if (this.lastFallAsleep) { var duration = 60 -this.lastFallAsleep.minutes; this.evts.push({ start: this.lastFallAsleep.minutes, duration: duration }); this.totalSleep += duration; this.lastFallAsleep = null; } } Guard.prototype.getMostSleepedMinute = function() { var sleeped = []; this.evts.forEach((e) => { for (var i =0; i < e.duration; ++i) sleeped[i +e.start] = 1 +(sleeped[i +e.start] || 0); }); var maxSleepedMinute =0; for (var i =1; i < 60; ++i) if ((sleeped[i] || 0) > (sleeped[maxSleepedMinute] || 0)) maxSleepedMinute = i; return maxSleepedMinute; } Guard.prototype.countSleepingTimeAtTime = function(time) { var total = 0; this.evts.forEach((e) => { if (time >= e.start && e.start +e.duration > time) total++; }); return total; } function GuardPool() { this.guards = {}; } GuardPool.prototype.getGuard = function(guardNo) { return this.guards[guardNo] = this.guards[guardNo] || new Guard(guardNo); } GuardPool.prototype.getMostSleepingGuard = function() { var maxSleepingGuard = null; for (var i in this.guards) { var g = this.guards[i]; if (!maxSleepingGuard || g.totalSleep > maxSleepingGuard.totalSleep) maxSleepingGuard = g; } return maxSleepingGuard; } GuardPool.prototype.getMostSleepingGuardAtTime = function(time) { var maxSleepingGuard = null, maxSleepingGuardTime = 0; for (var i in this.guards) { var count = this.guards[i].countSleepingTimeAtTime(time); if (!maxSleepingGuard || count > maxSleepingGuardTime) { maxSleepingGuard = this.guards[i]; maxSleepingGuardTime = count; } } return { time: maxSleepingGuardTime, guard: maxSleepingGuard }; } function read(cb) { require("fs").readFile('./input', 'utf8', (err, data) => { var lines = data.split("\n").sort(); lines.forEach((line) => { if (line.length > 0) cb(new LogEvent(line)); }); cb(null); }); } function initGuardPool(cb) { var guardpool = new GuardPool(), currentGuard = null; read(function(logEvt) { if (logEvt != null) { if (currentGuard) { if (logEvt.isSleep) currentGuard.fallAsleep(logEvt.time); if (logEvt.isWakeUp) currentGuard.awaken(logEvt.time); } if (logEvt.guardNo >= 0) { if (currentGuard) currentGuard.end(logEvt.time); currentGuard = guardpool.getGuard(logEvt.guardNo); } } else { cb(guardpool); } }); } function ex1() { initGuardPool((guardpool) => { var g = guardpool.getMostSleepingGuard(); var mostSleepedMinute = g.getMostSleepedMinute(); console.log("Guard most sleeped: " +g.guardNo +", most sleeped minute: " +mostSleepedMinute); }); } function ex2() { initGuardPool((guardpool) => { var maxSleepingGuard = null, mostSleepingTimeGuard = 0, maxSleepingGuardTime = 0; for (var i =0; i < 60; ++i) { var g = guardpool.getMostSleepingGuardAtTime(i); if (!maxSleepingGuard || g.time > maxSleepingGuardTime) { mostSleepingTimeGuard = i; maxSleepingGuardTime = g.time; maxSleepingGuard = g.guard; } } console.log("Guard most sleeped: " +maxSleepingGuard.guardNo +", most sleeped minute: " +mostSleepingTimeGuard); }); } //ex1(); ex2();