From cebbcf294209a5d1d51611a1996557e6c47934df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BC=D0=B5=D0=BB=D0=BE=D0=B2=D1=81=D0=BA=D0=B0?= =?UTF-8?q?=D1=8F=20=D0=A2=D0=B0=D1=82=D1=8C=D1=8F=D0=BD=D0=B0?= Date: Sun, 15 Oct 2017 23:51:49 +0500 Subject: [PATCH 1/4] 11 friends --- robbery.js | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 3 deletions(-) diff --git a/robbery.js b/robbery.js index 4a8309d..1c11ac3 100644 --- a/robbery.js +++ b/robbery.js @@ -6,6 +6,190 @@ */ exports.isStar = true; +let MINUTES_IN_HOUR = 60; +let HOURS_IN_DAY = 24; +let MINUTES_IN_DAY = MINUTES_IN_HOUR * HOURS_IN_DAY; + +let WEEKDAYS = { + 'ПН': 0, + 'ВТ': 1, + 'СР': 2, + 'ЧТ': 3, + 'ПТ': 4, + 'СБ': 5, + 'ВС': 6 +}; + +function makeDateAsMinutes(date) { + let splitedDate = date.split(' '); + + let day = splitedDate[0]; + let timeWithUTC = splitedDate[1]; + + let splitedTimeWithUTC = timeWithUTC.split('+'); + + let time = splitedTimeWithUTC[0]; + let UTC = splitedTimeWithUTC[1]; + + let splitedTime = time.split(':'); + + let hours = parseInt(splitedTime[0]); + let minutes = parseInt(splitedTime[1]); + + return minutes + (hours - UTC) * MINUTES_IN_HOUR + WEEKDAYS[day] * MINUTES_IN_DAY; +} + +function getBankUTC(date) { + return parseInt(date.split('+')[1]); +} + +function getGangIntervals(gangSchedule) { + return Object.keys(gangSchedule) + .map(function (gang) { + return gangSchedule[gang].map(function (date) { + return { + from: makeDateAsMinutes(date.from), + to: makeDateAsMinutes(date.to) + }; + }); + }) + .reduce(function (acc, item) { + return acc.concat(item); + }) + .sort(function (item1, item2) { + return item1.from > item2.from; + }); +} + +function getBadIntervals(gangIntervals) { + if (!gangIntervals.length) { + return []; + } + + let badIntervals = []; + + let badFrom = gangIntervals[0].from; + let badTo = gangIntervals[0].to; + + for (let i = 1; i < gangIntervals.length; i++) { + if (badTo < gangIntervals[i].from) { + badIntervals.push({ + from: badFrom, + to: badTo + }); + badFrom = gangIntervals[i].from; + badTo = gangIntervals[i].to; + } else if (badTo < gangIntervals[i].to) { + badTo = gangIntervals[i].to; + } + } + + badIntervals.push({ + from: badFrom, + to: badTo + }); + + return badIntervals; +} + +function getBankInterval(bankSchedule) { + let bankIntervals = []; + + bankIntervals.push({ + from: makeDateAsMinutes('ПН ' + bankSchedule.from), + to: makeDateAsMinutes('ПН ' + bankSchedule.to) + }); + bankIntervals.push({ + from: makeDateAsMinutes('ВТ ' + bankSchedule.from), + to: makeDateAsMinutes('ВТ ' + bankSchedule.to) + }); + bankIntervals.push({ + from: makeDateAsMinutes('СР ' + bankSchedule.from), + to: makeDateAsMinutes('СР ' + bankSchedule.to) + }); + + return bankIntervals; +} + +function isIntersection(interval, from, to) { + return ((from <= interval.from && interval.from <= to) || + (from <= interval.to && interval.to <= to)); +} + +function isIntersectionFrom(interval, from, to) { + return (isIntersection(interval, from, to) && + from <= interval.from && + to < interval.to); +} + +function isIntersectionTo(interval, from, to) { + return (isIntersection(interval, from, to) && + interval.from < from && + interval.to <= to); +} + +function isIntersectionFull(interval, from, to) { + return (isIntersection(interval, from, to) && + from <= interval.from && + interval.to <= to); +} + +function getGoodIntervalsForOneDay(gangSchedule, bankDay) { + let goodIntervalsForOneDay = []; + + let goodFrom = bankDay.from; + let goodTo = bankDay.to; + + for (let i = 0; i < gangSchedule.length; i++) { + if (isIntersectionFrom(gangSchedule[i], goodFrom, goodTo)) { + goodIntervalsForOneDay.push({ + from: goodFrom, + to: gangSchedule[i].from + }); + } else if (isIntersectionTo(gangSchedule[i], goodFrom, goodTo)) { + goodFrom = gangSchedule[i].to; + } else if (isIntersectionFull(gangSchedule[i], goodFrom, goodTo)) { + goodIntervalsForOneDay.push({ + from: goodFrom, + to: gangSchedule[i].from + }); + goodFrom = gangSchedule[i].to; + } + } + + goodIntervalsForOneDay.push({ + from: goodFrom, + to: goodTo + }); + + return goodIntervalsForOneDay; +} + +function getGoodIntervals(gangSchedule, bankSchedule) { + let goodIntervals = []; + + for (let i = 0; i < bankSchedule.length; i++) { + let goodIntervalsForOneDay = getGoodIntervalsForOneDay(gangSchedule, bankSchedule[i]); + goodIntervals = goodIntervals.concat(goodIntervalsForOneDay); + } + + return goodIntervals; +} + +function getGoodTimes(goodIntervals, duration) { + let stepTime = 30; + + let goodTimes = []; + + for (let i = 0; i < goodIntervals.length; i++) { + for (let j = goodIntervals[i].from; j <= goodIntervals[i].to - duration; j += stepTime) { + goodTimes.push(j); + } + } + + return goodTimes; +} + /** * @param {Object} schedule – Расписание Банды * @param {Number} duration - Время на ограбление в минутах @@ -15,7 +199,14 @@ exports.isStar = true; * @returns {Object} */ exports.getAppropriateMoment = function (schedule, duration, workingHours) { - console.info(schedule, duration, workingHours); + let gangIntervals = getGangIntervals(schedule); + let badIntervals = getBadIntervals(gangIntervals); + + let bankIntervals = getBankInterval(workingHours); + let bankUTC = getBankUTC(workingHours.from); + + let goodIntervals = getGoodIntervals(badIntervals, bankIntervals); + let goodTimes = getGoodTimes(goodIntervals, duration); return { @@ -24,7 +215,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {Boolean} */ exists: function () { - return false; + return goodTimes.length > 0; }, /** @@ -35,7 +226,24 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {String} */ format: function (template) { - return template; + if (!this.exists()) { + return ''; + } + + let goodTime = goodTimes[0] + bankUTC * MINUTES_IN_HOUR; + + let day = Object.keys(WEEKDAYS)[Math.floor(goodTime / MINUTES_IN_DAY)]; + + let hours = Math.floor((goodTime % MINUTES_IN_DAY) / MINUTES_IN_HOUR); + hours = (hours < 10 ? '0' : '') + hours; + + let minutes = (goodTime % MINUTES_IN_DAY) % MINUTES_IN_HOUR; + minutes = (minutes < 10 ? '0' : '') + minutes; + + return template + .replace('%DD', day) + .replace('%HH', hours) + .replace('%MM', minutes); }, /** @@ -44,6 +252,12 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {Boolean} */ tryLater: function () { + if (goodTimes.length > 1) { + goodTimes.shift(); + + return true; + } + return false; } }; From 017beee6455d9a825f98df6ef59dbe84fd3d28b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BC=D0=B5=D0=BB=D0=BE=D0=B2=D1=81=D0=BA=D0=B0?= =?UTF-8?q?=D1=8F=20=D0=A2=D0=B0=D1=82=D1=8C=D1=8F=D0=BD=D0=B0?= Date: Mon, 16 Oct 2017 12:48:03 +0500 Subject: [PATCH 2/4] =?UTF-8?q?=D0=9B=D0=BE=D0=BA=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA?= 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 1c11ac3..49237bb 100644 --- a/robbery.js +++ b/robbery.js @@ -4,7 +4,7 @@ * Сделано задание на звездочку * Реализовано оба метода и tryLater */ -exports.isStar = true; +exports.isStar = false; let MINUTES_IN_HOUR = 60; let HOURS_IN_DAY = 24; From 1cb3504ed5e46ff5bce5e6356f3c7d39ae549fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BC=D0=B5=D0=BB=D0=BE=D0=B2=D1=81=D0=BA=D0=B0?= =?UTF-8?q?=D1=8F=20=D0=A2=D0=B0=D1=82=D1=8C=D1=8F=D0=BD=D0=B0?= Date: Mon, 16 Oct 2017 16:22:05 +0500 Subject: [PATCH 3/4] =?UTF-8?q?=D0=A3=D0=BF=D1=80=D0=BE=D1=89=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=BA=D0=B0=20=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D1=80=D0=B2=D0=B0=D0=BB=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/robbery.js b/robbery.js index 49237bb..8613726 100644 --- a/robbery.js +++ b/robbery.js @@ -4,7 +4,7 @@ * Сделано задание на звездочку * Реализовано оба метода и tryLater */ -exports.isStar = false; +exports.isStar = true; let MINUTES_IN_HOUR = 60; let HOURS_IN_DAY = 24; @@ -111,26 +111,22 @@ function getBankInterval(bankSchedule) { return bankIntervals; } -function isIntersection(interval, from, to) { - return ((from <= interval.from && interval.from <= to) || - (from <= interval.to && interval.to <= to)); -} - function isIntersectionFrom(interval, from, to) { - return (isIntersection(interval, from, to) && - from <= interval.from && + return (from <= interval.from && + interval.from <= to && to < interval.to); } function isIntersectionTo(interval, from, to) { - return (isIntersection(interval, from, to) && - interval.from < from && + return (interval.from < from && + from <= interval.to && interval.to <= to); } function isIntersectionFull(interval, from, to) { - return (isIntersection(interval, from, to) && - from <= interval.from && + return (from <= interval.from && + interval.from <= to && + from <= interval.to && interval.to <= to); } From d63a101700d40e4435ba458b01a5bdc8c7fffd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BC=D0=B5=D0=BB=D0=BE=D0=B2=D1=81=D0=BA=D0=B0?= =?UTF-8?q?=D1=8F=20=D0=A2=D0=B0=D1=82=D1=8C=D1=8F=D0=BD=D0=B0?= Date: Mon, 16 Oct 2017 18:23:10 +0500 Subject: [PATCH 4/4] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B2=D0=B0?= =?UTF-8?q?=D0=BB=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- robbery.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/robbery.js b/robbery.js index 8613726..72105e7 100644 --- a/robbery.js +++ b/robbery.js @@ -137,14 +137,16 @@ function getGoodIntervalsForOneDay(gangSchedule, bankDay) { let goodTo = bankDay.to; for (let i = 0; i < gangSchedule.length; i++) { - if (isIntersectionFrom(gangSchedule[i], goodFrom, goodTo)) { + if (isIntersectionFrom(gangSchedule[i], goodFrom, goodTo) && + goodFrom !== gangSchedule[i].from) { goodIntervalsForOneDay.push({ from: goodFrom, to: gangSchedule[i].from }); } else if (isIntersectionTo(gangSchedule[i], goodFrom, goodTo)) { goodFrom = gangSchedule[i].to; - } else if (isIntersectionFull(gangSchedule[i], goodFrom, goodTo)) { + } else if (isIntersectionFull(gangSchedule[i], goodFrom, goodTo) && + goodFrom !== gangSchedule[i].from) { goodIntervalsForOneDay.push({ from: goodFrom, to: gangSchedule[i].from