From 4aab65b1886137f9efa8dbd30433620d6e13e216 Mon Sep 17 00:00:00 2001 From: xTave Date: Sun, 23 Oct 2016 15:34:02 +0500 Subject: [PATCH 1/8] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D1=8B=D0=B9=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 191 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 161 insertions(+), 30 deletions(-) diff --git a/robbery.js b/robbery.js index 4a8309d..9f3c381 100644 --- a/robbery.js +++ b/robbery.js @@ -1,49 +1,180 @@ 'use strict'; -/** - * Сделано задание на звездочку - * Реализовано оба метода и tryLater - */ exports.isStar = true; -/** - * @param {Object} schedule – Расписание Банды - * @param {Number} duration - Время на ограбление в минутах - * @param {Object} workingHours – Время работы банка - * @param {String} workingHours.from – Время открытия, например, "10:00+5" - * @param {String} workingHours.to – Время закрытия, например, "18:00+5" - * @returns {Object} - */ +var daysDict = { 'ПН': 0, 'ВТ': 1, 'СР': 2 }; +var daysArray = ['ПН', 'ВТ', 'СР']; + +function TimeInterval(start, end) { + this.start = start; + this.end = end; + + this.getLength = function () { + return this.end - this.start; + }; + + this.getNextDay = function () { + return new TimeInterval(this.start + 24 * 60, this.end + 24 * 60); + }; + + this.timeInInterval = function (time) { + return this.start <= time && time <= this.end; + }; +} + +function timeInIntervals(timeIntervalsArray, time) { + for (var i = 0; i < timeIntervalsArray.length; i++) { + if (timeIntervalsArray[i].timeInInterval(time)) { + + return true; + } + } + + return false; +} + +function strToIntDate(str) { + var day = 0; + if (daysDict[str.slice(0, 2)] !== undefined) { + day = daysDict[str.split(' ')[0]]; + str = str.split(' ')[1]; + } + var timezone = parseInt(str.split('+')[1]); + str = str.split('+')[0]; + var h = parseInt(str.split(':')[0]); + var m = parseInt(str.split(':')[1]); + + return day * 24 * 60 + (h - timezone) * 60 + m; +} + exports.getAppropriateMoment = function (schedule, duration, workingHours) { - console.info(schedule, duration, workingHours); + var newSchedule = { + Danny: [], + Rusty: [], + Linus: [], + Bank: [] + }; + + var bankTimezone = parseInt(workingHours.from.split('+')[1]); + + var gangsterNames = ['Danny', 'Rusty', 'Linus']; + + gangsterNames.forEach(function (gangsterName) { + schedule[gangsterName].forEach(function (time) { + newSchedule[gangsterName].push(new TimeInterval(strToIntDate(time.from) + 1 + + bankTimezone * 60, strToIntDate(time.to) - 1 + bankTimezone * 60)); + }); + }); + newSchedule.Bank.push(new TimeInterval(strToIntDate(workingHours.from) + + bankTimezone * 60, strToIntDate(workingHours.to) + bankTimezone * 60)); + newSchedule.Bank.push(newSchedule.Bank[0].getNextDay()); + newSchedule.Bank.push(newSchedule.Bank[1].getNextDay()); + + function getGoodTimeIntervals() { + var goodTimesInt = []; + function createGoodTimesIntArray() { + + var goodTimeToHack = true; + var i = 0; + function gangsterNotBusy(gangster) { + if (timeInIntervals(newSchedule[gangster], i)) { + goodTimeToHack = false; + } + } + + for (; i < 3 * 24 * 60; i++) { + goodTimeToHack = true; + + if (!timeInIntervals(newSchedule.Bank, i)) { + continue; + } + + gangsterNames.forEach(gangsterNotBusy); + + if (goodTimeToHack) { + goodTimesInt.push(i); + } + } + } + + createGoodTimesIntArray(); + + var goodTimesIntervals = []; + + for (var i = 0; i < goodTimesInt.length; i++) { + if (i === 0 || goodTimesInt[i - 1] + 1 !== goodTimesInt[i]) { + goodTimesIntervals.push(new TimeInterval(goodTimesInt[i], goodTimesInt[i])); + } else { + goodTimesIntervals[goodTimesIntervals.length - 1].end += 1; + } + } + + return goodTimesIntervals; + } + + var goodTimesIntervals = getGoodTimeIntervals(); + + function simplifyTimesIntervals() { + var newTimeIntervals = []; + goodTimesIntervals.forEach(function (timeInterval) { + if (!(timeInterval.getLength() < duration)) { + newTimeIntervals.push(timeInterval); + } + }); + goodTimesIntervals = newTimeIntervals; + } + + simplifyTimesIntervals(); return { - /** - * Найдено ли время - * @returns {Boolean} - */ exists: function () { + for (var i = 0; i < goodTimesIntervals.length; i++) { + if (goodTimesIntervals[i].getLength() >= duration) { + + return true; + } + } + return false; }, - /** - * Возвращает отформатированную строку с часами для ограбления - * Например, - * "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)" - * @param {String} template - * @returns {String} - */ format: function (template) { - return template; + if (!this.exists()) { + + return ''; + } + + function timeToString(time) { + if (time < 10) { + + return '0' + time.toString(); + } + + return time.toString(); + } + var startInterval = goodTimesIntervals[0]; + var day = parseInt(startInterval.start / (24 * 60)); + var hour = parseInt(startInterval.start / 60) - day * 24; + var minutes = startInterval.start % 60; + + return template.replace('%DD', daysArray[day]).replace('%HH', timeToString(hour)) + .replace('%MM', timeToString(minutes)); }, - /** - * Попробовать найти часы для ограбления позже [*] - * @star - * @returns {Boolean} - */ tryLater: function () { + if (this.exists()) { + var startInterval = goodTimesIntervals[0]; + if (goodTimesIntervals.length > 1 || startInterval.getLength() >= duration + 30) { + startInterval.start += 30; + simplifyTimesIntervals(); + + return true; + } + + return false; + } + return false; } }; From 82eda4eba31d1562d20326999e5e04fce53e11c6 Mon Sep 17 00:00:00 2001 From: xTave Date: Mon, 24 Oct 2016 23:23:04 +0500 Subject: [PATCH 2/8] =?UTF-8?q?+=D0=9A=D0=BE=D0=BD=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D1=82=D1=8B,=20+=D0=B3=D0=BB=D0=B0=D0=B3=D0=BE=D0=BB=D1=8B-?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8,=20-=D0=BA=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8B=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 88 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/robbery.js b/robbery.js index 9f3c381..1bad09b 100644 --- a/robbery.js +++ b/robbery.js @@ -4,6 +4,12 @@ exports.isStar = true; var daysDict = { 'ПН': 0, 'ВТ': 1, 'СР': 2 }; var daysArray = ['ПН', 'ВТ', 'СР']; +var MINUTES_IN_HOUR = 60; +var HOURS_IN_DAY = 24; +var MINUTES_IN_DAY = HOURS_IN_DAY * MINUTES_IN_HOUR; +var MINUTES_TO_START_LATER = 30; +var DAYS_TO_HACK = 3; + function TimeInterval(start, end) { this.start = start; @@ -14,18 +20,17 @@ function TimeInterval(start, end) { }; this.getNextDay = function () { - return new TimeInterval(this.start + 24 * 60, this.end + 24 * 60); + return new TimeInterval(this.start + MINUTES_IN_DAY, this.end + MINUTES_IN_DAY); }; - this.timeInInterval = function (time) { + this.timeIsInInterval = function (time) { return this.start <= time && time <= this.end; }; } -function timeInIntervals(timeIntervalsArray, time) { +function timeIsInIntervals(timeIntervalsArray, time) { for (var i = 0; i < timeIntervalsArray.length; i++) { - if (timeIntervalsArray[i].timeInInterval(time)) { - + if (timeIntervalsArray[i].timeIsInInterval(time)) { return true; } } @@ -33,18 +38,22 @@ function timeInIntervals(timeIntervalsArray, time) { return false; } -function strToIntDate(str) { +function strToIntDate(strDate) { var day = 0; - if (daysDict[str.slice(0, 2)] !== undefined) { - day = daysDict[str.split(' ')[0]]; - str = str.split(' ')[1]; + var str_split = []; + if (daysDict[strDate.slice(0, 2)] !== undefined) { + str_split = strDate.split(' '); + day = daysDict[str_split[0]]; + strDate = str_split[1]; } - var timezone = parseInt(str.split('+')[1]); - str = str.split('+')[0]; - var h = parseInt(str.split(':')[0]); - var m = parseInt(str.split(':')[1]); - - return day * 24 * 60 + (h - timezone) * 60 + m; + str_split = strDate.split('+'); + var timezone = parseInt(str_split[1]); + strDate = str_split[0]; + str_split = strDate.split(':'); + var hours = parseInt(str_split[0]); + var minutes = parseInt(str_split[1]); + + return day * MINUTES_IN_DAY + (hours - timezone) * MINUTES_IN_HOUR + minutes; } exports.getAppropriateMoment = function (schedule, duration, workingHours) { @@ -61,35 +70,39 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { gangsterNames.forEach(function (gangsterName) { schedule[gangsterName].forEach(function (time) { - newSchedule[gangsterName].push(new TimeInterval(strToIntDate(time.from) + 1 + - bankTimezone * 60, strToIntDate(time.to) - 1 + bankTimezone * 60)); + newSchedule[gangsterName].push(new TimeInterval( + strToIntDate(time.from) + 1 + bankTimezone * MINUTES_IN_HOUR, + strToIntDate(time.to) - 1 + bankTimezone * MINUTES_IN_HOUR)); }); }); - newSchedule.Bank.push(new TimeInterval(strToIntDate(workingHours.from) + - bankTimezone * 60, strToIntDate(workingHours.to) + bankTimezone * 60)); - newSchedule.Bank.push(newSchedule.Bank[0].getNextDay()); - newSchedule.Bank.push(newSchedule.Bank[1].getNextDay()); + newSchedule.Bank.push(new TimeInterval( + strToIntDate(workingHours.from) + bankTimezone * MINUTES_IN_HOUR, + strToIntDate(workingHours.to) + bankTimezone * MINUTES_IN_HOUR)); + for (var dayIndex = 0; dayIndex < DAYS_TO_HACK - 1; dayIndex++) { + newSchedule.Bank.push(newSchedule.Bank[newSchedule.Bank.length - 1].getNextDay()); + } function getGoodTimeIntervals() { var goodTimesInt = []; + function createGoodTimesIntArray() { var goodTimeToHack = true; var i = 0; - function gangsterNotBusy(gangster) { - if (timeInIntervals(newSchedule[gangster], i)) { + function gangsterIsNotBusy(gangster) { + if (timeIsInIntervals(newSchedule[gangster], i)) { goodTimeToHack = false; } } - for (; i < 3 * 24 * 60; i++) { + for (; i < DAYS_TO_HACK * MINUTES_IN_DAY; i++) { goodTimeToHack = true; - if (!timeInIntervals(newSchedule.Bank, i)) { + if (!timeIsInIntervals(newSchedule.Bank, i)) { continue; } - gangsterNames.forEach(gangsterNotBusy); + gangsterNames.forEach(gangsterIsNotBusy); if (goodTimeToHack) { goodTimesInt.push(i); @@ -117,7 +130,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { function simplifyTimesIntervals() { var newTimeIntervals = []; goodTimesIntervals.forEach(function (timeInterval) { - if (!(timeInterval.getLength() < duration)) { + if (timeInterval.getLength() >= duration) { newTimeIntervals.push(timeInterval); } }); @@ -154,25 +167,22 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { return time.toString(); } var startInterval = goodTimesIntervals[0]; - var day = parseInt(startInterval.start / (24 * 60)); - var hour = parseInt(startInterval.start / 60) - day * 24; - var minutes = startInterval.start % 60; + var day = parseInt(startInterval.start / (MINUTES_IN_DAY)); + var hour = parseInt(startInterval.start / MINUTES_IN_HOUR) - day * HOURS_IN_DAY; + var minutes = startInterval.start % MINUTES_IN_HOUR; return template.replace('%DD', daysArray[day]).replace('%HH', timeToString(hour)) .replace('%MM', timeToString(minutes)); }, tryLater: function () { - if (this.exists()) { - var startInterval = goodTimesIntervals[0]; - if (goodTimesIntervals.length > 1 || startInterval.getLength() >= duration + 30) { - startInterval.start += 30; - simplifyTimesIntervals(); - - return true; - } + var startInterval = goodTimesIntervals[0]; + if (this.exists() && (goodTimesIntervals.length > 1 || + startInterval.getLength() >= duration + MINUTES_TO_START_LATER)) { + startInterval.start += MINUTES_TO_START_LATER; + simplifyTimesIntervals(); - return false; + return true; } return false; From c5e2d5a91a60a700ef684de6b940ccf5bc0acbe2 Mon Sep 17 00:00:00 2001 From: xTave Date: Mon, 24 Oct 2016 23:24:39 +0500 Subject: [PATCH 3/8] =?UTF-8?q?=D0=9A=20=D1=81=D0=BB=D0=BE=D0=B2=D1=83=20?= =?UTF-8?q?=D0=BE=20=D0=BA=D0=BE=D1=81=D1=82=D1=8B=D0=BB=D1=8F=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/robbery.js b/robbery.js index 1bad09b..d375112 100644 --- a/robbery.js +++ b/robbery.js @@ -40,18 +40,18 @@ function timeIsInIntervals(timeIntervalsArray, time) { function strToIntDate(strDate) { var day = 0; - var str_split = []; + var strSplit = []; if (daysDict[strDate.slice(0, 2)] !== undefined) { - str_split = strDate.split(' '); - day = daysDict[str_split[0]]; - strDate = str_split[1]; + strSplit = strDate.split(' '); + day = daysDict[strSplit[0]]; + strDate = strSplit[1]; } - str_split = strDate.split('+'); - var timezone = parseInt(str_split[1]); - strDate = str_split[0]; - str_split = strDate.split(':'); - var hours = parseInt(str_split[0]); - var minutes = parseInt(str_split[1]); + strSplit = strDate.split('+'); + var timezone = parseInt(strSplit[1]); + strDate = strSplit[0]; + strSplit = strDate.split(':'); + var hours = parseInt(strSplit[0]); + var minutes = parseInt(strSplit[1]); return day * MINUTES_IN_DAY + (hours - timezone) * MINUTES_IN_HOUR + minutes; } From d9b1f9501fba6c936a1f0b004f8e7f97a49df3d8 Mon Sep 17 00:00:00 2001 From: xTave Date: Thu, 27 Oct 2016 15:47:53 +0500 Subject: [PATCH 4/8] =?UTF-8?q?=D0=A4=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D1=8B,=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=B8=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=B7=D0=B0=D0=BD=D0=B8=D0=BC=D0=B0=D1=8E=D1=82?= =?UTF-8?q?=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=2030=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=BA=20=D0=B8=20=D0=BF=D1=80=D0=BE=D1=87=D0=B5?= =?UTF-8?q?=D0=B5=20=D0=BF=D0=BE=20=D0=BC=D0=B5=D0=BB=D0=BE=D1=87=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 196 ++++++++++++++++++++++++++--------------------------- 1 file changed, 95 insertions(+), 101 deletions(-) diff --git a/robbery.js b/robbery.js index d375112..8d09028 100644 --- a/robbery.js +++ b/robbery.js @@ -2,8 +2,8 @@ exports.isStar = true; -var daysDict = { 'ПН': 0, 'ВТ': 1, 'СР': 2 }; -var daysArray = ['ПН', 'ВТ', 'СР']; +var DAYS_INDEXES = { 'ПН': 0, 'ВТ': 1, 'СР': 2, 'ЧТ': 3, 'ПТ': 4, 'СБ': 5, 'ВС': 6 }; +var DAYS_NAMES = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС']; var MINUTES_IN_HOUR = 60; var HOURS_IN_DAY = 24; var MINUTES_IN_DAY = HOURS_IN_DAY * MINUTES_IN_HOUR; @@ -23,14 +23,14 @@ function TimeInterval(start, end) { return new TimeInterval(this.start + MINUTES_IN_DAY, this.end + MINUTES_IN_DAY); }; - this.timeIsInInterval = function (time) { + this.isTimeInInterval = function (time) { return this.start <= time && time <= this.end; }; } -function timeIsInIntervals(timeIntervalsArray, time) { +function isTimeInIntervals(timeIntervalsArray, time) { for (var i = 0; i < timeIntervalsArray.length; i++) { - if (timeIntervalsArray[i].timeIsInInterval(time)) { + if (timeIntervalsArray[i].isTimeInInterval(time)) { return true; } } @@ -38,118 +38,120 @@ function timeIsInIntervals(timeIntervalsArray, time) { return false; } -function strToIntDate(strDate) { +function strDateToInt(strDate) { var day = 0; - var strSplit = []; - if (daysDict[strDate.slice(0, 2)] !== undefined) { - strSplit = strDate.split(' '); - day = daysDict[strSplit[0]]; - strDate = strSplit[1]; + var strDateCopy = strDate.slice(); + if (DAYS_INDEXES[strDateCopy.slice(0, 2)] !== undefined) { + var strDayAndTime = strDateCopy.split(' '); + day = DAYS_INDEXES[strDayAndTime[0]]; + strDateCopy = strDayAndTime[1]; } - strSplit = strDate.split('+'); - var timezone = parseInt(strSplit[1]); - strDate = strSplit[0]; - strSplit = strDate.split(':'); - var hours = parseInt(strSplit[0]); - var minutes = parseInt(strSplit[1]); + var timeAndTimezone = strDateCopy.split('+'); + var timezone = parseInt(timeAndTimezone[1]); + var strTime = timeAndTimezone[0]; + var hoursAndMinutes = strTime.split(':'); + var hours = parseInt(hoursAndMinutes[0]); + var minutes = parseInt(hoursAndMinutes[1]); return day * MINUTES_IN_DAY + (hours - timezone) * MINUTES_IN_HOUR + minutes; } -exports.getAppropriateMoment = function (schedule, duration, workingHours) { - var newSchedule = { - Danny: [], - Rusty: [], - Linus: [], - Bank: [] - }; - - var bankTimezone = parseInt(workingHours.from.split('+')[1]); - - var gangsterNames = ['Danny', 'Rusty', 'Linus']; - - gangsterNames.forEach(function (gangsterName) { - schedule[gangsterName].forEach(function (time) { - newSchedule[gangsterName].push(new TimeInterval( - strToIntDate(time.from) + 1 + bankTimezone * MINUTES_IN_HOUR, - strToIntDate(time.to) - 1 + bankTimezone * MINUTES_IN_HOUR)); - }); - }); - newSchedule.Bank.push(new TimeInterval( - strToIntDate(workingHours.from) + bankTimezone * MINUTES_IN_HOUR, - strToIntDate(workingHours.to) + bankTimezone * MINUTES_IN_HOUR)); - for (var dayIndex = 0; dayIndex < DAYS_TO_HACK - 1; dayIndex++) { - newSchedule.Bank.push(newSchedule.Bank[newSchedule.Bank.length - 1].getNextDay()); +function getGangsterNames(schedule) { + var gangsterNames = []; + for (var gangsterName in schedule) { + if (schedule.hasOwnProperty(gangsterName)) { + gangsterNames.push(gangsterName); + } } - function getGoodTimeIntervals() { - var goodTimesInt = []; - - function createGoodTimesIntArray() { + return gangsterNames; +} - var goodTimeToHack = true; - var i = 0; - function gangsterIsNotBusy(gangster) { - if (timeIsInIntervals(newSchedule[gangster], i)) { - goodTimeToHack = false; - } - } +function createTimeIntervalWithShift(time, shift) { + return new TimeInterval(strDateToInt(time.from) + shift, strDateToInt(time.to) + shift); +} - for (; i < DAYS_TO_HACK * MINUTES_IN_DAY; i++) { - goodTimeToHack = true; +function simplifyTimesIntervals(timeIntervals, duration) { + var newTimeIntervals = []; + timeIntervals.forEach(function (timeInterval) { + if (timeInterval.getLength() >= duration) { + newTimeIntervals.push(timeInterval); + } + }); - if (!timeIsInIntervals(newSchedule.Bank, i)) { - continue; - } + return newTimeIntervals; +} - gangsterNames.forEach(gangsterIsNotBusy); +function addOrChangeLastTimeInterval(arrayIntervals, timeToStartNewInterval) { + if (arrayIntervals.length === 0 || + arrayIntervals[arrayIntervals.length - 1].end !== timeToStartNewInterval - 1) { + arrayIntervals.push(new TimeInterval(timeToStartNewInterval, timeToStartNewInterval)); + } else { + arrayIntervals[arrayIntervals.length - 1].end += 1; + } +} - if (goodTimeToHack) { - goodTimesInt.push(i); - } - } +function getGoodTimeIntervals(schedule, gangsterNames) { + var goodTimesIntervals = []; + var isGoodTimeToHack = true; + var i = -1; + function isGangsterNotBusy(gangster) { + if (isTimeInIntervals(schedule[gangster], i)) { + isGoodTimeToHack = false; } + } - createGoodTimesIntArray(); - - var goodTimesIntervals = []; - - for (var i = 0; i < goodTimesInt.length; i++) { - if (i === 0 || goodTimesInt[i - 1] + 1 !== goodTimesInt[i]) { - goodTimesIntervals.push(new TimeInterval(goodTimesInt[i], goodTimesInt[i])); - } else { - goodTimesIntervals[goodTimesIntervals.length - 1].end += 1; - } + while (i < DAYS_TO_HACK * MINUTES_IN_DAY) { + i++; + isGoodTimeToHack = true; + if (!isTimeInIntervals(schedule.Bank, i)) { + continue; } + gangsterNames.forEach(isGangsterNotBusy); - return goodTimesIntervals; + if (isGoodTimeToHack) { + addOrChangeLastTimeInterval(goodTimesIntervals, i); + } } - var goodTimesIntervals = getGoodTimeIntervals(); + return goodTimesIntervals; +} - function simplifyTimesIntervals() { - var newTimeIntervals = []; - goodTimesIntervals.forEach(function (timeInterval) { - if (timeInterval.getLength() >= duration) { - newTimeIntervals.push(timeInterval); - } +function createScheduleWithTimeIntervals(bankWorkingHours, schedule, gangsterNames) { + var newSchedule = {}; + var bankShift = parseInt(bankWorkingHours.from.split('+')[1]) * MINUTES_IN_HOUR; + + gangsterNames.forEach(function (gangsterName) { + newSchedule[gangsterName] = []; + schedule[gangsterName].forEach(function (time) { + var intervalWithShift = createTimeIntervalWithShift(time, bankShift); + intervalWithShift.start++; + intervalWithShift.end--; + newSchedule[gangsterName].push(intervalWithShift); }); - goodTimesIntervals = newTimeIntervals; + }); + newSchedule.Bank = []; + newSchedule.Bank.push(createTimeIntervalWithShift(bankWorkingHours, bankShift)); + for (var dayIndex = 0; dayIndex < DAYS_TO_HACK - 1; dayIndex++) { + newSchedule.Bank.push(newSchedule.Bank[newSchedule.Bank.length - 1].getNextDay()); } - simplifyTimesIntervals(); - - return { + return newSchedule; +} - exists: function () { - for (var i = 0; i < goodTimesIntervals.length; i++) { - if (goodTimesIntervals[i].getLength() >= duration) { +function timeToString(time) { + return time < 10 ? '0' + time.toString() : time.toString(); +} - return true; - } - } +exports.getAppropriateMoment = function (schedule, duration, workingHours) { + var gangsterNames = getGangsterNames(schedule); + var newSchedule = createScheduleWithTimeIntervals(workingHours, schedule, gangsterNames); + var goodTimesIntervals = getGoodTimeIntervals(newSchedule, gangsterNames); + goodTimesIntervals = simplifyTimesIntervals(goodTimesIntervals, duration); - return false; + return { + exists: function () { + return goodTimesIntervals.length; }, format: function (template) { @@ -158,20 +160,12 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { return ''; } - function timeToString(time) { - if (time < 10) { - - return '0' + time.toString(); - } - - return time.toString(); - } var startInterval = goodTimesIntervals[0]; var day = parseInt(startInterval.start / (MINUTES_IN_DAY)); var hour = parseInt(startInterval.start / MINUTES_IN_HOUR) - day * HOURS_IN_DAY; var minutes = startInterval.start % MINUTES_IN_HOUR; - return template.replace('%DD', daysArray[day]).replace('%HH', timeToString(hour)) + return template.replace('%DD', DAYS_NAMES[day]).replace('%HH', timeToString(hour)) .replace('%MM', timeToString(minutes)); }, @@ -180,7 +174,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { if (this.exists() && (goodTimesIntervals.length > 1 || startInterval.getLength() >= duration + MINUTES_TO_START_LATER)) { startInterval.start += MINUTES_TO_START_LATER; - simplifyTimesIntervals(); + goodTimesIntervals = simplifyTimesIntervals(goodTimesIntervals, duration); return true; } From ba94dabf6cd81bf394193cf4e3f247a36147bcbd Mon Sep 17 00:00:00 2001 From: xTave Date: Thu, 27 Oct 2016 15:51:54 +0500 Subject: [PATCH 5/8] =?UTF-8?q?=D0=9E=D1=88=D0=B8=D0=B1=D0=BA=D0=B0?= 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 8d09028..d8b42c6 100644 --- a/robbery.js +++ b/robbery.js @@ -151,7 +151,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { return { exists: function () { - return goodTimesIntervals.length; + return goodTimesIntervals.length !== 0; }, format: function (template) { From ad30429a8b0022941d6d9a5b8682240e50ea12b2 Mon Sep 17 00:00:00 2001 From: xTave Date: Thu, 27 Oct 2016 15:58:49 +0500 Subject: [PATCH 6/8] =?UTF-8?q?=D0=A1=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=83?= =?UTF-8?q?=20=D1=81=D1=87=D0=B8=D1=81=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B2=D1=81=D0=B5=D0=BC=20parseInt'=D0=B0=D0=BC=20=D0=B7=D0=B0?= =?UTF-8?q?=20=D0=BC=D0=BE=D0=B9=20=D1=81=D1=87=D0=B5=D1=82!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/robbery.js b/robbery.js index d8b42c6..a21694f 100644 --- a/robbery.js +++ b/robbery.js @@ -47,11 +47,11 @@ function strDateToInt(strDate) { strDateCopy = strDayAndTime[1]; } var timeAndTimezone = strDateCopy.split('+'); - var timezone = parseInt(timeAndTimezone[1]); + var timezone = parseInt(timeAndTimezone[1], 10); var strTime = timeAndTimezone[0]; var hoursAndMinutes = strTime.split(':'); - var hours = parseInt(hoursAndMinutes[0]); - var minutes = parseInt(hoursAndMinutes[1]); + var hours = parseInt(hoursAndMinutes[0], 10); + var minutes = parseInt(hoursAndMinutes[1], 10); return day * MINUTES_IN_DAY + (hours - timezone) * MINUTES_IN_HOUR + minutes; } @@ -119,7 +119,7 @@ function getGoodTimeIntervals(schedule, gangsterNames) { function createScheduleWithTimeIntervals(bankWorkingHours, schedule, gangsterNames) { var newSchedule = {}; - var bankShift = parseInt(bankWorkingHours.from.split('+')[1]) * MINUTES_IN_HOUR; + var bankShift = parseInt(bankWorkingHours.from.split('+')[1], 10) * MINUTES_IN_HOUR; gangsterNames.forEach(function (gangsterName) { newSchedule[gangsterName] = []; @@ -161,8 +161,8 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { } var startInterval = goodTimesIntervals[0]; - var day = parseInt(startInterval.start / (MINUTES_IN_DAY)); - var hour = parseInt(startInterval.start / MINUTES_IN_HOUR) - day * HOURS_IN_DAY; + var day = parseInt(startInterval.start / (MINUTES_IN_DAY), 10); + var hour = parseInt(startInterval.start / MINUTES_IN_HOUR, 10) - day * HOURS_IN_DAY; var minutes = startInterval.start % MINUTES_IN_HOUR; return template.replace('%DD', DAYS_NAMES[day]).replace('%HH', timeToString(hour)) From 73a3ba5280e30a530ac0fa740d16d4c4d649e348 Mon Sep 17 00:00:00 2001 From: LevshinMisha Date: Fri, 28 Oct 2016 15:57:31 +0500 Subject: [PATCH 7/8] =?UTF-8?q?=D0=B2=D1=81=D0=B5=20=D1=87=D1=82=D0=BE=20?= =?UTF-8?q?=D1=81=D0=BC=D0=BE=D0=B3=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 88 +++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/robbery.js b/robbery.js index a21694f..78becd3 100644 --- a/robbery.js +++ b/robbery.js @@ -38,22 +38,20 @@ function isTimeInIntervals(timeIntervalsArray, time) { return false; } -function strDateToInt(strDate) { - var day = 0; +function strDateToDateObj(strDate) { var strDateCopy = strDate.slice(); - if (DAYS_INDEXES[strDateCopy.slice(0, 2)] !== undefined) { - var strDayAndTime = strDateCopy.split(' '); - day = DAYS_INDEXES[strDayAndTime[0]]; - strDateCopy = strDayAndTime[1]; + if (DAYS_INDEXES[strDateCopy.slice(0, 2)] === undefined) { + strDateCopy = 'ПН ' + strDateCopy; } - var timeAndTimezone = strDateCopy.split('+'); - var timezone = parseInt(timeAndTimezone[1], 10); - var strTime = timeAndTimezone[0]; - var hoursAndMinutes = strTime.split(':'); - var hours = parseInt(hoursAndMinutes[0], 10); - var minutes = parseInt(hoursAndMinutes[1], 10); - - return day * MINUTES_IN_DAY + (hours - timezone) * MINUTES_IN_HOUR + minutes; + var o = { + day: DAYS_INDEXES[strDateCopy.slice(0, 2)], + timezone: parseInt(strDateCopy.slice(9, strDateCopy.length), 10), + hours: parseInt(strDateCopy.slice(3, 5), 10), + minutes: parseInt(strDateCopy.slice(6, 8), 10) + }; + o.intValue = o.day * MINUTES_IN_DAY + (o.hours - o.timezone) * MINUTES_IN_HOUR + o.minutes; + + return o; } function getGangsterNames(schedule) { @@ -68,7 +66,8 @@ function getGangsterNames(schedule) { } function createTimeIntervalWithShift(time, shift) { - return new TimeInterval(strDateToInt(time.from) + shift, strDateToInt(time.to) + shift); + return new TimeInterval(strDateToDateObj(time.from).intValue + shift, + strDateToDateObj(time.to).intValue + shift); } function simplifyTimesIntervals(timeIntervals, duration) { @@ -91,25 +90,25 @@ function addOrChangeLastTimeInterval(arrayIntervals, timeToStartNewInterval) { } } +function isGangstersNotBusy(schedule, gangsterNames, time) { + var gangstersIsNotBusy = true; + gangsterNames.forEach(function (gangster) { + if (isTimeInIntervals(schedule[gangster], time)) { + gangstersIsNotBusy = false; + } + }); + + return gangstersIsNotBusy; +} + function getGoodTimeIntervals(schedule, gangsterNames) { var goodTimesIntervals = []; - var isGoodTimeToHack = true; - var i = -1; - function isGangsterNotBusy(gangster) { - if (isTimeInIntervals(schedule[gangster], i)) { - isGoodTimeToHack = false; - } - } - while (i < DAYS_TO_HACK * MINUTES_IN_DAY) { - i++; - isGoodTimeToHack = true; + for (var i = 0; i < DAYS_TO_HACK * MINUTES_IN_DAY; i++) { if (!isTimeInIntervals(schedule.Bank, i)) { continue; } - gangsterNames.forEach(isGangsterNotBusy); - - if (isGoodTimeToHack) { + if (isGangstersNotBusy(schedule, gangsterNames, i)) { addOrChangeLastTimeInterval(goodTimesIntervals, i); } } @@ -117,9 +116,8 @@ function getGoodTimeIntervals(schedule, gangsterNames) { return goodTimesIntervals; } -function createScheduleWithTimeIntervals(bankWorkingHours, schedule, gangsterNames) { +function createGangsterScheduleWithTimeIntervals(schedule, gangsterNames, bankShift) { var newSchedule = {}; - var bankShift = parseInt(bankWorkingHours.from.split('+')[1], 10) * MINUTES_IN_HOUR; gangsterNames.forEach(function (gangsterName) { newSchedule[gangsterName] = []; @@ -130,11 +128,21 @@ function createScheduleWithTimeIntervals(bankWorkingHours, schedule, gangsterNam newSchedule[gangsterName].push(intervalWithShift); }); }); - newSchedule.Bank = []; - newSchedule.Bank.push(createTimeIntervalWithShift(bankWorkingHours, bankShift)); + + return newSchedule; +} + +function addToScheduleBankTimeIntervals(schedule, bankWorkingHours, bankShift) { + schedule.Bank = [createTimeIntervalWithShift(bankWorkingHours, bankShift)]; for (var dayIndex = 0; dayIndex < DAYS_TO_HACK - 1; dayIndex++) { - newSchedule.Bank.push(newSchedule.Bank[newSchedule.Bank.length - 1].getNextDay()); + schedule.Bank.push(schedule.Bank[schedule.Bank.length - 1].getNextDay()); } +} + +function createScheduleWithTimeIntervals(bankWorkingHours, schedule, gangsterNames) { + var bankShift = strDateToDateObj(bankWorkingHours.from).timezone * MINUTES_IN_HOUR; + var newSchedule = createGangsterScheduleWithTimeIntervals(schedule, gangsterNames, bankShift); + addToScheduleBankTimeIntervals(newSchedule, bankWorkingHours, bankShift); return newSchedule; } @@ -147,20 +155,19 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { var gangsterNames = getGangsterNames(schedule); var newSchedule = createScheduleWithTimeIntervals(workingHours, schedule, gangsterNames); var goodTimesIntervals = getGoodTimeIntervals(newSchedule, gangsterNames); - goodTimesIntervals = simplifyTimesIntervals(goodTimesIntervals, duration); + var goodTimesIntervalsWithGoodDuration = simplifyTimesIntervals(goodTimesIntervals, duration); return { exists: function () { - return goodTimesIntervals.length !== 0; + return goodTimesIntervalsWithGoodDuration.length !== 0; }, format: function (template) { if (!this.exists()) { - return ''; } - var startInterval = goodTimesIntervals[0]; + var startInterval = goodTimesIntervalsWithGoodDuration[0]; var day = parseInt(startInterval.start / (MINUTES_IN_DAY), 10); var hour = parseInt(startInterval.start / MINUTES_IN_HOUR, 10) - day * HOURS_IN_DAY; var minutes = startInterval.start % MINUTES_IN_HOUR; @@ -170,11 +177,12 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { }, tryLater: function () { - var startInterval = goodTimesIntervals[0]; - if (this.exists() && (goodTimesIntervals.length > 1 || + var startInterval = goodTimesIntervalsWithGoodDuration[0]; + if (this.exists() && (goodTimesIntervalsWithGoodDuration.length > 1 || startInterval.getLength() >= duration + MINUTES_TO_START_LATER)) { startInterval.start += MINUTES_TO_START_LATER; - goodTimesIntervals = simplifyTimesIntervals(goodTimesIntervals, duration); + goodTimesIntervalsWithGoodDuration = simplifyTimesIntervals( + goodTimesIntervalsWithGoodDuration, duration); return true; } From 652f8e8a57ce84cc62d6ac157e792270f5d98c1d Mon Sep 17 00:00:00 2001 From: LevshinMisha Date: Fri, 28 Oct 2016 17:55:14 +0500 Subject: [PATCH 8/8] =?UTF-8?q?=D0=92=D0=B5=D1=80=D0=BD=D1=83=D0=BB=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B8,=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=BD=D0=B5=D0=BA=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D1=8B=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/robbery.js b/robbery.js index 78becd3..eefe82c 100644 --- a/robbery.js +++ b/robbery.js @@ -1,5 +1,9 @@ 'use strict'; +/** + * Сделано задание на звездочку + * Реализовано оба метода и tryLater + */ exports.isStar = true; var DAYS_INDEXES = { 'ПН': 0, 'ВТ': 1, 'СР': 2, 'ЧТ': 3, 'ПТ': 4, 'СБ': 5, 'ВС': 6 }; @@ -43,15 +47,16 @@ function strDateToDateObj(strDate) { if (DAYS_INDEXES[strDateCopy.slice(0, 2)] === undefined) { strDateCopy = 'ПН ' + strDateCopy; } - var o = { + var dateInfo = { day: DAYS_INDEXES[strDateCopy.slice(0, 2)], - timezone: parseInt(strDateCopy.slice(9, strDateCopy.length), 10), hours: parseInt(strDateCopy.slice(3, 5), 10), - minutes: parseInt(strDateCopy.slice(6, 8), 10) + minutes: parseInt(strDateCopy.slice(6, 8), 10), + timezone: parseInt(strDateCopy.slice(9, strDateCopy.length), 10) }; - o.intValue = o.day * MINUTES_IN_DAY + (o.hours - o.timezone) * MINUTES_IN_HOUR + o.minutes; + dateInfo.intValue = dateInfo.day * MINUTES_IN_DAY + + (dateInfo.hours - dateInfo.timezone) * MINUTES_IN_HOUR + dateInfo.minutes; - return o; + return dateInfo; } function getGangsterNames(schedule) { @@ -82,11 +87,11 @@ function simplifyTimesIntervals(timeIntervals, duration) { } function addOrChangeLastTimeInterval(arrayIntervals, timeToStartNewInterval) { - if (arrayIntervals.length === 0 || - arrayIntervals[arrayIntervals.length - 1].end !== timeToStartNewInterval - 1) { + var arrayLen = arrayIntervals.length; + if (arrayLen === 0 || arrayIntervals[arrayLen - 1].end !== timeToStartNewInterval - 1) { arrayIntervals.push(new TimeInterval(timeToStartNewInterval, timeToStartNewInterval)); } else { - arrayIntervals[arrayIntervals.length - 1].end += 1; + arrayIntervals[arrayLen - 1].end += 1; } } @@ -151,6 +156,14 @@ function timeToString(time) { return time < 10 ? '0' + time.toString() : time.toString(); } +/** + * @param {Object} schedule – Расписание Банды + * @param {Number} duration - Время на ограбление в минутах + * @param {Object} workingHours – Время работы банка + * @param {String} workingHours.from – Время открытия, например, "10:00+5" + * @param {String} workingHours.to – Время закрытия, например, "18:00+5" + * @returns {Object} + */ exports.getAppropriateMoment = function (schedule, duration, workingHours) { var gangsterNames = getGangsterNames(schedule); var newSchedule = createScheduleWithTimeIntervals(workingHours, schedule, gangsterNames); @@ -158,10 +171,22 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { var goodTimesIntervalsWithGoodDuration = simplifyTimesIntervals(goodTimesIntervals, duration); return { + + /** + * Найдено ли время + * @returns {Boolean} + */ exists: function () { return goodTimesIntervalsWithGoodDuration.length !== 0; }, + /** + * Возвращает отформатированную строку с часами для ограбления + * Например, + * "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)" + * @param {String} template + * @returns {String} + */ format: function (template) { if (!this.exists()) { return ''; @@ -176,6 +201,11 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { .replace('%MM', timeToString(minutes)); }, + /** + * Попробовать найти часы для ограбления позже [*] + * @star + * @returns {Boolean} + */ tryLater: function () { var startInterval = goodTimesIntervalsWithGoodDuration[0]; if (this.exists() && (goodTimesIntervalsWithGoodDuration.length > 1 ||