From e87a07d87eec4e754cd857fee8916e8eda2a74a5 Mon Sep 17 00:00:00 2001 From: zokeer Date: Wed, 26 Oct 2016 17:27:24 +0500 Subject: [PATCH 1/7] =?UTF-8?q?=D0=93=D0=BE=D0=BB=D1=83=D0=B1=D0=B5=D0=B2?= =?UTF-8?q?=20=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 221 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 188 insertions(+), 33 deletions(-) diff --git a/robbery.js b/robbery.js index 4a8309d..197ea13 100644 --- a/robbery.js +++ b/robbery.js @@ -1,50 +1,205 @@ '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 DayCast = { + 'ПН': 17, + 'ВТ': 18, + 'СР': 19 +}; + +var InvertDayCast = { + 1: 'ПН', + 2: 'ВТ', + 3: 'СР' +}; + +var BankGMT; + +function convertToDate(time) { + var match = /([а-я]{2})\s(\d{2}:\d{2})([+-]\d+)/gi.exec(time); + + return match !== null ? new Date('October ' + DayCast[match[1]] + + ', 2016 ' + match[2] + ':00 GMT' + match[3] + '00') : time; +} + +function convertSchedule(schedule) { + var newSchedule = []; + for (var buddy in schedule) { + for (var i = 0; i < schedule[buddy].length; i++) { + newSchedule.push( + { + from: convertToDate(schedule[buddy][i].from), + to: convertToDate(schedule[buddy][i].to) + }); + } + } + newSchedule.sort(compareTime); + + return newSchedule; +} + +function convertWorkingHours(workingHours) { + var matchFrom = /(\d{2}:\d{2})([+-]\d+)/gi.exec(workingHours.from); + var matchTo = /(\d{2}:\d{2})([+-]\d+)/gi.exec(workingHours.to); + BankGMT = matchFrom[2]; + var newWorkingHours = []; + for (var i = 0; i < 3; i++) { + newWorkingHours.push( + { + from: new Date('October ' + (17 + i) + + ', 2016 ' + matchFrom[1] + ':00 GMT' + matchFrom[2] + '00'), + to: new Date('October ' + (17 + i) + + ', 2016 ' + matchTo[1] + ':00 GMT' + matchTo[2] + '00') + }); + } + + return newWorkingHours; +} + +function compareTime(first, second) { + return first.from - second.from; +} + +function getNewCurrent(schedule, time) { + var newCurrent = new Date(1970); + schedule.forEach(function (prevTime) { + if (prevTime.to >= time.to && prevTime.from <= time.to) { + newCurrent = new Date(Math.max(newCurrent, prevTime.to)); + } + }); + + return newCurrent; +} + +function getFreeMoments(schedule) { + var freeMoments = []; + var currentTime = convertToDate('ПН 00:00' + BankGMT); + var robEnd = new Date(2016, 9, 19, 23, 59, 0); + schedule.forEach(function (time) { + if (time.from > currentTime) { + freeMoments.push( + { + from: currentTime, to: time.from + }); + currentTime = getNewCurrent(schedule, time); + } + }); + if (currentTime < robEnd) { + freeMoments.push( + { + from: currentTime, + to: robEnd + }); + } + + return freeMoments; +} + +function getApprMomentDaySame(time, duration, workingHours) { + if (time.from < workingHours[time.from.getDay() - 1].from) { + time.from = workingHours[time.from.getDay() - 1].from; + } + if (time.to > workingHours[time.to.getDay() - 1].to) { + time.to = workingHours[time.to.getDay() - 1].to; + } + + return time.to - time.from >= duration ? { + from: time.from, to: time.to + } : null; +} + +function getApprMomentDayDiff(time, duration, workingHours) { + var apprMoments = []; + if (time.from < workingHours[time.from.getDay() - 1].from) { + time.from = workingHours[time.from.getDay() - 1].from; + } + workingHours[time.from.getDay() - 1].to - time.from >= duration ? apprMoments.push( + { + from: time.from, to: workingHours[time.from.getDay() - 1].to + } + ) : apprMoments.push(null); + time.to - workingHours[time.to.getDay() - 1].from >= duration ? apprMoments.push( + { + from: workingHours[time.to.getDay() - 1].from, to: time.to + } + ) : apprMoments.push(null); + + return apprMoments; +} + +function getApprMoments(freeMoments, duration, workingHours) { + var apprMoments = []; + var apprMoment; + freeMoments.forEach(function (time) { + if (time.from.getDay() === time.to.getDay()) { + apprMoment = getApprMomentDaySame(time, duration, workingHours); + if (apprMoment) { + apprMoments.push(apprMoment); + } + } else { + apprMoment = getApprMomentDayDiff(time, duration, workingHours); + apprMoment.forEach(function (thing) { + if (thing) { + apprMoments.push(thing); + } + }); + } + }); + + return apprMoments; +} + +function formatTemplate(apprMoment, template) { + var hourInMs = 60 * 60 * 1000; + var apprOffset = apprMoment.from.getTimezoneOffset() / -60 * hourInMs; + var bankOffset = Number(BankGMT) * hourInMs; + apprMoment.from = new Date(apprMoment.from - apprOffset + bankOffset); + + return template + .replace('%DD', InvertDayCast[apprMoment.from.getDay()]) + .replace('%HH', apprMoment.from.getHours()) + .replace('%MM', apprMoment.from.getMinutes()); +} + exports.getAppropriateMoment = function (schedule, duration, workingHours) { - console.info(schedule, duration, workingHours); + schedule = convertSchedule(schedule); + workingHours = convertWorkingHours(workingHours); + var freeMoments = getFreeMoments(schedule); + duration = duration * 60 * 1000; + var apprMoments = getApprMoments(freeMoments, duration, workingHours); + var pointer = 0; + console.info(apprMoments); return { - /** - * Найдено ли время - * @returns {Boolean} - */ exists: function () { - return false; + return apprMoments.length > 0; }, - /** - * Возвращает отформатированную строку с часами для ограбления - * Например, - * "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)" - * @param {String} template - * @returns {String} - */ format: function (template) { - return template; + return apprMoments.length > 0 ? formatTemplate(apprMoments[pointer], template) : ''; }, - - /** - * Попробовать найти часы для ограбления позже [*] - * @star - * @returns {Boolean} - */ tryLater: function () { - return false; + var currentMoment = apprMoments[pointer].from; + currentMoment = currentMoment.getTime() + 1800000; + currentMoment = new Date(currentMoment); + if (apprMoments[pointer].to.getTime() - currentMoment.getTime() >= duration) { + apprMoments[pointer].from = currentMoment; + + return true; + } + var oldPointer = pointer; + while (apprMoments[pointer].from - apprMoments[oldPointer].from < 1800000) { + if (pointer < apprMoments.length - 1) { + pointer++; + } else { + return false; + } + } + + return true; } }; }; + From 8cac62defae2c6ae86fbc2ebb6357031d4dbc5f1 Mon Sep 17 00:00:00 2001 From: zokeer Date: Wed, 26 Oct 2016 17:41:01 +0500 Subject: [PATCH 2/7] =?UTF-8?q?=D0=93=D0=BE=D0=BB=D1=83=D0=B1=D0=B5=D0=B2?= =?UTF-8?q?=20=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 63 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/robbery.js b/robbery.js index 197ea13..59c0abd 100644 --- a/robbery.js +++ b/robbery.js @@ -23,15 +23,23 @@ function convertToDate(time) { ', 2016 ' + match[2] + ':00 GMT' + match[3] + '00') : time; } +function transfromSchedule(buddy, schedule, newSchedule) { + for (var i = 0; i < schedule[buddy].length; i++) { + newSchedule.push( + { + from: convertToDate(schedule[buddy][i].from), + to: convertToDate(schedule[buddy][i].to) + }); + } + + return newSchedule; +} + function convertSchedule(schedule) { var newSchedule = []; for (var buddy in schedule) { - for (var i = 0; i < schedule[buddy].length; i++) { - newSchedule.push( - { - from: convertToDate(schedule[buddy][i].from), - to: convertToDate(schedule[buddy][i].to) - }); + if ({}.hasOwnProperty.call(schedule, buddy)) { + newSchedule = transfromSchedule(buddy, schedule, newSchedule); } } newSchedule.sort(compareTime); @@ -114,16 +122,24 @@ function getApprMomentDayDiff(time, duration, workingHours) { if (time.from < workingHours[time.from.getDay() - 1].from) { time.from = workingHours[time.from.getDay() - 1].from; } - workingHours[time.from.getDay() - 1].to - time.from >= duration ? apprMoments.push( - { - from: time.from, to: workingHours[time.from.getDay() - 1].to - } - ) : apprMoments.push(null); - time.to - workingHours[time.to.getDay() - 1].from >= duration ? apprMoments.push( - { - from: workingHours[time.to.getDay() - 1].from, to: time.to - } - ) : apprMoments.push(null); + if (workingHours[time.from.getDay() - 1].to - time.from >= duration) { + apprMoments.push( + { + from: time.from, to: workingHours[time.from.getDay() - 1].to + } + ); + } else { + apprMoments.push(null); + } + if (time.to - workingHours[time.to.getDay() - 1].from >= duration) { + apprMoments.push( + { + from: workingHours[time.to.getDay() - 1].from, to: time.to + } + ); + } else { + apprMoments.push(null); + } return apprMoments; } @@ -150,6 +166,15 @@ function getApprMoments(freeMoments, duration, workingHours) { return apprMoments; } +function transfromInTwoDig(number) { + if (number <= 9) { + + return '0' + number; + } + + return number; +} + function formatTemplate(apprMoment, template) { var hourInMs = 60 * 60 * 1000; var apprOffset = apprMoment.from.getTimezoneOffset() / -60 * hourInMs; @@ -158,8 +183,8 @@ function formatTemplate(apprMoment, template) { return template .replace('%DD', InvertDayCast[apprMoment.from.getDay()]) - .replace('%HH', apprMoment.from.getHours()) - .replace('%MM', apprMoment.from.getMinutes()); + .replace('%HH', transfromInTwoDig(apprMoment.from.getHours())) + .replace('%MM', transfromInTwoDig(apprMoment.from.getMinutes())); } exports.getAppropriateMoment = function (schedule, duration, workingHours) { @@ -169,7 +194,6 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { duration = duration * 60 * 1000; var apprMoments = getApprMoments(freeMoments, duration, workingHours); var pointer = 0; - console.info(apprMoments); return { @@ -202,4 +226,3 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { } }; }; - From 41f0ea9546925d6548cde987de584ef8f9ebba4c Mon Sep 17 00:00:00 2001 From: zokeer Date: Wed, 26 Oct 2016 17:43:29 +0500 Subject: [PATCH 3/7] =?UTF-8?q?=D0=93=D0=BE=D0=BB=D1=83=D0=B1=D0=B5=D0=B2?= =?UTF-8?q?=20=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/robbery.js b/robbery.js index 59c0abd..bb39e6e 100644 --- a/robbery.js +++ b/robbery.js @@ -82,7 +82,7 @@ function getNewCurrent(schedule, time) { function getFreeMoments(schedule) { var freeMoments = []; - var currentTime = convertToDate('ПН 00:00' + BankGMT); + var currentTime = new Date(2016, 9, 17, 0, 0, 0); var robEnd = new Date(2016, 9, 19, 23, 59, 0); schedule.forEach(function (time) { if (time.from > currentTime) { @@ -226,3 +226,4 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { } }; }; + From 9a665e9a87cced425f8b9013bd08966d34cea402 Mon Sep 17 00:00:00 2001 From: zokeer Date: Wed, 26 Oct 2016 21:42:23 +0500 Subject: [PATCH 4/7] =?UTF-8?q?=D0=93=D0=BE=D0=BB=D1=83=D0=B1=D0=B5=D0=B2?= =?UTF-8?q?=20=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/robbery.js b/robbery.js index bb39e6e..c4b36a2 100644 --- a/robbery.js +++ b/robbery.js @@ -179,12 +179,12 @@ function formatTemplate(apprMoment, template) { var hourInMs = 60 * 60 * 1000; var apprOffset = apprMoment.from.getTimezoneOffset() / -60 * hourInMs; var bankOffset = Number(BankGMT) * hourInMs; - apprMoment.from = new Date(apprMoment.from - apprOffset + bankOffset); + var time = new Date(apprMoment.from - apprOffset + bankOffset); return template - .replace('%DD', InvertDayCast[apprMoment.from.getDay()]) - .replace('%HH', transfromInTwoDig(apprMoment.from.getHours())) - .replace('%MM', transfromInTwoDig(apprMoment.from.getMinutes())); + .replace('%DD', InvertDayCast[time.getDay()]) + .replace('%HH', transfromInTwoDig(time.getHours())) + .replace('%MM', transfromInTwoDig(time.getMinutes())); } exports.getAppropriateMoment = function (schedule, duration, workingHours) { @@ -205,11 +205,10 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { return apprMoments.length > 0 ? formatTemplate(apprMoments[pointer], template) : ''; }, tryLater: function () { - var currentMoment = apprMoments[pointer].from; - currentMoment = currentMoment.getTime() + 1800000; - currentMoment = new Date(currentMoment); - if (apprMoments[pointer].to.getTime() - currentMoment.getTime() >= duration) { - apprMoments[pointer].from = currentMoment; + var currentMoment = apprMoments[pointer].from.getTime(); + currentMoment += 1800000; + if (apprMoments[pointer].to.getTime() - currentMoment >= duration) { + apprMoments[pointer].from = new Date(currentMoment); return true; } From 73745712b3c0bd4c1e2a2b35ba9907bab8bcf10f Mon Sep 17 00:00:00 2001 From: zokeer Date: Wed, 26 Oct 2016 22:26:09 +0500 Subject: [PATCH 5/7] =?UTF-8?q?=D0=93=D0=BE=D0=BB=D1=83=D0=B1=D0=B5=D0=B2?= =?UTF-8?q?=20=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/robbery.js b/robbery.js index c4b36a2..f12fed5 100644 --- a/robbery.js +++ b/robbery.js @@ -134,7 +134,40 @@ function getApprMomentDayDiff(time, duration, workingHours) { if (time.to - workingHours[time.to.getDay() - 1].from >= duration) { apprMoments.push( { - from: workingHours[time.to.getDay() - 1].from, to: time.to + from: workingHours[time.to.getDay() - 1].from, + to: new Date(Math.min(time.to, workingHours[time.to.getDay() - 1].to)) + } + ); + } else { + apprMoments.push(null); + } + + return apprMoments; +} + +function getApprMomentDay2Diff(time, duration, workingHours) { + var apprMoments = []; + if (time.from < workingHours[time.from.getDay() - 1].from) { + time.from = workingHours[time.from.getDay() - 1].from; + } + if (workingHours[time.from.getDay() - 1].to - time.from >= duration) { + apprMoments.push( + { + from: time.from, to: workingHours[time.from.getDay() - 1].to + } + ); + } else { + apprMoments.push(null); + } + apprMoments.push({ + from: workingHours[time.to.getDay() - 2].from, + to: workingHours[time.to.getDay() - 2].to + }); + if (time.to - workingHours[time.to.getDay() - 1].from >= duration) { + apprMoments.push( + { + from: workingHours[time.to.getDay() - 1].from, + to: new Date(Math.min(time.to, workingHours[time.to.getDay() - 1].to)) } ); } else { @@ -153,7 +186,8 @@ function getApprMoments(freeMoments, duration, workingHours) { if (apprMoment) { apprMoments.push(apprMoment); } - } else { + } + if (time.from.getDay() === time.to.getDay() - 1) { apprMoment = getApprMomentDayDiff(time, duration, workingHours); apprMoment.forEach(function (thing) { if (thing) { @@ -161,6 +195,14 @@ function getApprMoments(freeMoments, duration, workingHours) { } }); } + if (time.from.getDay() === time.to.getDay() - 2) { + apprMoment = getApprMomentDay2Diff(time, duration, workingHours); + apprMoment.forEach(function (thing) { + if (thing) { + apprMoments.push(thing); + } + }); + } }); return apprMoments; From f1602294483646d5da7b4152151c2f95d3e3925a Mon Sep 17 00:00:00 2001 From: zokeer Date: Wed, 26 Oct 2016 22:30:11 +0500 Subject: [PATCH 6/7] =?UTF-8?q?=D0=93=D0=BE=D0=BB=D1=83=D0=B1=D0=B5=D0=B2?= =?UTF-8?q?=20=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/robbery.js b/robbery.js index f12fed5..f2d35fe 100644 --- a/robbery.js +++ b/robbery.js @@ -247,6 +247,9 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { return apprMoments.length > 0 ? formatTemplate(apprMoments[pointer], template) : ''; }, tryLater: function () { + if (apprMoments.length === 0) { + return false; + } var currentMoment = apprMoments[pointer].from.getTime(); currentMoment += 1800000; if (apprMoments[pointer].to.getTime() - currentMoment >= duration) { From 8a9f0c4b595fcd61529c5b8974b79ecc4e788c53 Mon Sep 17 00:00:00 2001 From: zokeer Date: Thu, 27 Oct 2016 16:33:33 +0500 Subject: [PATCH 7/7] =?UTF-8?q?=D0=93=D0=BE=D0=BB=D1=83=D0=B1=D0=B5=D0=B2?= =?UTF-8?q?=20=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/robbery.js b/robbery.js index f2d35fe..8b06120 100644 --- a/robbery.js +++ b/robbery.js @@ -131,7 +131,8 @@ function getApprMomentDayDiff(time, duration, workingHours) { } else { apprMoments.push(null); } - if (time.to - workingHours[time.to.getDay() - 1].from >= duration) { + if (Math.min(time.to, workingHours[time.to.getDay() - 1].to) - + workingHours[time.to.getDay() - 1].from >= duration) { apprMoments.push( { from: workingHours[time.to.getDay() - 1].from,