From c6d8127a67f5df69521dcfb69b547a4ec3972682 Mon Sep 17 00:00:00 2001 From: Sergey Gogolev Date: Fri, 21 Oct 2016 14:11:21 +0500 Subject: [PATCH 1/2] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D0=B8=D1=80=D1=83?= =?UTF-8?q?=D0=B5=D0=BC=20=D1=81=D1=82=D0=B0=D1=82=D1=83=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robbery.js b/robbery.js index 4a8309d..8dcff44 100644 --- a/robbery.js +++ b/robbery.js @@ -24,7 +24,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {Boolean} */ exists: function () { - return false; + return true; }, /** From b4e1ed4844f0cb2b1959ae56608de5830d4dfc92 Mon Sep 17 00:00:00 2001 From: Sergey Gogolev Date: Fri, 21 Oct 2016 14:16:21 +0500 Subject: [PATCH 2/2] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D0=B8=D1=80=D1=83?= =?UTF-8?q?=D0=B5=D0=BC=20=D1=81=D1=82=D0=B0=D1=82=D1=83=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 3 deletions(-) diff --git a/robbery.js b/robbery.js index 8dcff44..05cf575 100644 --- a/robbery.js +++ b/robbery.js @@ -6,6 +6,80 @@ */ exports.isStar = true; +var DAYS = [ + 'ПН', 'ВТ', 'СР', 'ЧТ', + 'ПТ', 'СБ', 'ВС' +]; +var THIRTY_MINUTES = 1800; + +function dateToTimestamp(str) { + for (var i = 0; i < DAYS.length; i++) { + str = str.replace(DAYS[i], i + 1); + } + str = str.replace(/(\d) (\d{2}:\d{2})(\+\d+)?/, '1 $1 1970 $2 GMT$3'); + + return Date.parse(str) / 1000; +} + +function toTimestampInterval(interval) { + return { + 'from': dateToTimestamp(interval.from), + 'to': dateToTimestamp(interval.to) + }; +} + +function normalizeSchedule(schedule) { + var busyIntervals = []; + Object.keys(schedule).forEach(function (thug) { + var busy = schedule[thug].map(toTimestampInterval); + busyIntervals = busyIntervals.concat(busy); + }); + busyIntervals = busyIntervals.sort(function (one, another) { + if (one.from < another.from) { + return -1; + } + if (one.from > another.from) { + return 1; + } + + return 0; + }); + + return busyIntervals; +} + +function getWorkingDays(workingHours) { + var workingDays = []; + for (var i = 0; i < 3; i++) { + var from = DAYS[i] + ' ' + workingHours.from; + var to = DAYS[i] + ' ' + workingHours.to; + workingDays.push({ + 'from': dateToTimestamp(from), + 'to': dateToTimestamp(to) + }); + } + + return workingDays; +} + +function getSpareTimes(schedule, weekStart, deadline) { + var spareTime = []; + var current = weekStart; + for (var i = 0; i < schedule.length; i++) { + if (current >= schedule[i].from) { + current = current < schedule[i].to ? schedule[i].to : current; + continue; + } + spareTime.push({ 'from': current, 'to': schedule[i].from }); + current = schedule[i].to; + } + if (current < deadline) { + spareTime.push({ 'from': current, 'to': deadline }); + } + + return spareTime; +} + /** * @param {Object} schedule – Расписание Банды * @param {Number} duration - Время на ограбление в минутах @@ -15,7 +89,26 @@ exports.isStar = true; * @returns {Object} */ exports.getAppropriateMoment = function (schedule, duration, workingHours) { - console.info(schedule, duration, workingHours); + schedule = normalizeSchedule(schedule); + duration *= 60; + var workingDays = getWorkingDays(workingHours); + var bankTimezone = parseInt(/\+(\d+)$/.exec(workingHours.from)[1]); + var weekStart = Date.parse('1 1 1970 00:00 GMT+' + bankTimezone) / 1000; + var deadline = Date.parse('1 3 1970 23:59 GMT+' + bankTimezone) / 1000; + var spareTime = getSpareTimes(schedule, weekStart, deadline); + + var robberyTime = []; + workingDays.forEach(function (workingDay) { + var possible = []; + for (var j = 0; j < spareTime.length; j++) { + var minTo = Math.min(workingDay.to, spareTime[j].to); + var maxFrom = Math.max(workingDay.from, spareTime[j].from); + if (minTo - maxFrom >= duration) { + possible.push({ 'from': maxFrom, 'to': minTo }); + } + } + robberyTime = robberyTime.concat(possible); + }); return { @@ -24,7 +117,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {Boolean} */ exists: function () { - return true; + return robberyTime.length > 0; }, /** @@ -35,7 +128,23 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {String} */ format: function (template) { - return template; + if (robberyTime.length === 0) { + return ''; + } + var date = new Date(); + date.setTime((robberyTime[0].from + bankTimezone * 3600) * 1000); + + var minutes = date + .getUTCMinutes() + .toLocaleString(undefined, { 'minimumIntegerDigits': 2 }); + var hours = date + .getUTCHours() + .toLocaleString(undefined, { 'minimumIntegerDigits': 2 }); + + return template + .replace('%HH', hours) + .replace('%MM', minutes) + .replace('%DD', DAYS[date.getUTCDate() - 1]); }, /** @@ -44,6 +153,21 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {Boolean} */ tryLater: function () { + if (!this.exists()) { + return false; + } + + if (robberyTime[0].to - robberyTime[0].from - THIRTY_MINUTES >= duration) { + robberyTime[0].from = robberyTime[0].from + THIRTY_MINUTES; + + return true; + } + if (robberyTime.length > 1) { + robberyTime.shift(); + + return true; + } + return false; } };