diff --git a/robbery.js b/robbery.js index 4a8309d..f1980e5 100644 --- a/robbery.js +++ b/robbery.js @@ -4,7 +4,91 @@ * Сделано задание на звездочку * Реализовано оба метода и tryLater */ -exports.isStar = true; +exports.isStar = false; + +var MINUTES_IN_HOUR = 60; +var MINUTES_IN_DAY = 24 * MINUTES_IN_HOUR; +var DAYS_OF_WEEK = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС']; +var bankTimezone = 0; + +function getTimezone(dateString) { + return dateString.match(/(\d+)$/)[0]; +} + +function pad(time) { + time = time.toString(); + + return time.length === 2 ? time : '0' + time; +} + +function parseDateFromString(dateString) { + var dateComponents = dateString.match(/([А-Я]{2}) (\d{2}):(\d{2})\+(\d)/); + + return { + dayOfWeek: DAYS_OF_WEEK.indexOf(dateComponents[1]), + hours: Number(dateComponents[2]), + minutes: Number(dateComponents[3]), + timezone: Number(dateComponents[4]) + }; +} + +function getUnifiedTime(dateString) { + var parsedDate = parseDateFromString(dateString); + var unifiedTime = parsedDate.dayOfWeek * MINUTES_IN_DAY + + parsedDate.hours * MINUTES_IN_HOUR + + parsedDate.minutes + + (bankTimezone - parsedDate.timezone) * MINUTES_IN_HOUR; + + if (unifiedTime < 0) { + unifiedTime = 0; + } else if (unifiedTime > 3 * MINUTES_IN_DAY - 1) { + unifiedTime = 3 * MINUTES_IN_DAY - 1; + } + + return unifiedTime; +} + +function convertIntervalToBankTimezone(interval) { + return { + from: getUnifiedTime(interval.from), + to: getUnifiedTime(interval.to) + }; +} + +function getDateComponents(minutesSince) { + var dayOfWeek = Math.floor(minutesSince / MINUTES_IN_DAY); + minutesSince -= dayOfWeek * MINUTES_IN_DAY; + var hours = Math.floor(minutesSince / MINUTES_IN_HOUR); + minutesSince -= hours * MINUTES_IN_HOUR; + var minutes = minutesSince; + + return { + dayOfWeek: DAYS_OF_WEEK[dayOfWeek], + hours: hours, + minutes: minutes + }; +} + +function intersect(set, el) { + for (var i = 0; i < set.length; i++) { + if (el.from > set[i].from && el.to < set[i].to) { // inside + set.splice(i, 1, { + from: set[i].from, + to: el.from + }, { + from: el.to, + to: set[i].to + }); + i--; + } else if (el.from <= set[i].from && el.to >= set[i].to) { // bigger + set.splice(i, 1); + } else if (el.from < set[i].to && el.to > set[i].to) { + set[i].to = el.from; + } else if (el.from < set[i].from && el.to > set[i].from) { + set[i].from = el.to; + } + } +} /** * @param {Object} schedule – Расписание Банды @@ -15,7 +99,38 @@ exports.isStar = true; * @returns {Object} */ exports.getAppropriateMoment = function (schedule, duration, workingHours) { - console.info(schedule, duration, workingHours); + bankTimezone = getTimezone(workingHours.from); + + var appropriateIntervals = ['ПН', 'ВТ', 'СР'] + .map(function (day) { + return convertIntervalToBankTimezone({ + from: day + ' ' + workingHours.from, + to: day + ' ' + workingHours.to + }); + }) + .filter(function (interval) { + return interval.from !== interval.to; + }); + + schedule = (schedule.Danny || []).concat(schedule.Rusty || [], schedule.Linus || []) + .map(function (interval) { + return convertIntervalToBankTimezone(interval); + }) + .filter(function (interval) { + return interval.from !== interval.to; + }); + + schedule.forEach(function (interval) { + intersect(appropriateIntervals, interval); + }); + + appropriateIntervals = appropriateIntervals + .filter(function (el) { + return el.to - el.from >= duration; + }) + .sort(function (a, b) { + return a.from > b.from; + }); return { @@ -24,7 +139,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {Boolean} */ exists: function () { - return false; + return appropriateIntervals.length > 0; }, /** @@ -35,7 +150,15 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {String} */ format: function (template) { - return template; + if (!this.exists()) { + return ''; + } + var components = getDateComponents(appropriateIntervals[0].from); + + return template + .replace(/%HH/, components.hours) + .replace(/%MM/, pad(components.minutes)) + .replace(/%DD/, pad(components.dayOfWeek)); }, /**