From 875e7bb5f77f168306055ae4af7e9ea62c4dc590 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 00:36:32 +0500 Subject: [PATCH 01/13] all --- robbery.js | 158 ++++++++++++++++++++++++++++++++++++++- test.html | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 368 insertions(+), 3 deletions(-) create mode 100644 test.html diff --git a/robbery.js b/robbery.js index 4a8309d..93fcea1 100644 --- a/robbery.js +++ b/robbery.js @@ -6,6 +6,141 @@ */ exports.isStar = true; +var HOURS_IN_DAY = 24; +var MINUTES_IN_HOUR = 60; +var MINUTES_IN_DAY = HOURS_IN_DAY * 60; +var DAYS_OF_THE_WEEK = ["ПН", "ВТ", "СР"]; +function DayOfTheWeek(dayText) { + this.days = DAYS_OF_THE_WEEK; + this.getNumber = function() { + return this.days.indexOf(this.text); + } + this.text = dayText; + this.addDays = function(days) { + this.number += days % 7; + }; + this.getText = function() { + return this.days[this.number]; + }; + + return this; +}; +function DateTime(dateTimeString) { + this.day = new DayOfTheWeek(dateTimeString.slice(0, 2)); + this.hours = parseInt(dateTimeString.slice(3, 5)); + this.minutes = parseInt(dateTimeString.slice(6, 8)); + this.timezone = parseInt(dateTimeString.split('+')[1]); + this.addMinutes = function(minutes) { + var daysToAdd = Math.floor(minutes / MINUTES_IN_DAY); + minutes -= MINUTES_IN_DAY * daysToAdd; + var hoursToAdd = Math.floor(minutes / MINUTES_IN_HOUR); + minutes -= MINUTES_IN_HOUR * hoursToAdd; + var minutesToAdd = minutes; + this.minutes += minutesToAdd; + this.hours += hoursToAdd; + this.day.addDays(daysToAdd); + + return; + } + this.convertToTimezone = function(timezone) { + var delta = timezone - this.timezone; + this.addMinutes(delta * MINUTES_IN_HOUR); + this.timezone = timezone; + }; + this.getMinutesCountFromWeekStart = function() { + return MINUTES_IN_DAY * this.day.getNumber() + MINUTES_IN_HOUR * this.hours + this.minutes; + }; + this.compareTo = function(other) { + return this.getMinutesCountFromWeekStart() - other.getMinutesCountFromWeekStart(); + }; + + return this; +} + +function Interval(start, end) { + this.start = start; + this.end = end; + this.intersect = function(otherInterval) { + var intersectionStart = this.start.compareTo(otherInterval.start) > 0 ? + this.start : otherInterval.start; + var intersectionEnd = this.end.compareTo(otherInterval.end) < 0 ? + this.end : otherInterval.end; + if(intersectionEnd.compareTo(intersectionStart) < 0) + return null; + + return new Interval(intersectionStart, intersectionEnd); + }; + this.union = function(otherInterval) { + var intersectionStart = this.start.compareTo(otherInterval.start) < 0 ? + this.start : otherInterval.start; + var intersectionEnd = this.end.compareTo(otherInterval.end) > 0 ? + this.end : otherInterval.end; + + return new Interval(intersectionStart, intersectionEnd); + }; + + return this; +} + +function NormalizeSchedule(memberSchedule, workingInterval) { + var newSchedule = []; + memberSchedule.forEach(function(busynessInfo) { + var bankTimezone = workingInterval.start.timezone; + var start = new DateTime(busynessInfo.from); + var end = new DateTime(busynessInfo.to); + start.convertToTimezone(bankTimezone); + end.convertToTimezone(bankTimezone); + var busynessInterval = new Interval(start, end); + DAYS_OF_THE_WEEK.forEach(function(dayOfTheWeek) { + workingInterval.start.day = new DayOfTheWeek(dayOfTheWeek); + workingInterval.end.day = new DayOfTheWeek(dayOfTheWeek); + var intersection = busynessInterval.intersect(workingInterval); + if(intersection != null) + newSchedule.push(intersection); + }); + }); + + return newSchedule; +} + +function GetRobberyStart(schedule, workingInterval, duration, day) { + workingInterval.start.day = new DayOfTheWeek(day); + workingInterval.end.day = new DayOfTheWeek(day); + var allIntervals = schedule.Danny.concat(schedule.Rusty).concat(schedule.Linus); + allIntervals = allIntervals.filter(function(interval) { + return interval.start.day.text == day; + }); + allIntervals = allIntervals.sort(function(a, b) { + return a.start.compareTo(b.start); + }); + var result = null; + var lastIntervalEnd = workingInterval.start; + var currentInterval = allIntervals[0]; + while (allIntervals.length > 0 || result != null) { + currentInterval = allIntervals[0]; + allIntervals = allIntervals.splice(1); + if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) + return currentInterval.start; + var newAllIntervals = []; + for(var i = 0; i < allIntervals.length; i +=1 ) { + var interval = allIntervals[i]; + if (currentInterval.intersect(interval) == null){ + newAllIntervals.push(interval); + lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 ? + currentInterval.end : lastIntervalEnd; + break; + } + else + currentInterval = currentInterval.union(interval); + }; + allIntervals = newAllIntervals.sort(function(a, b) { + return a.start.compareTo(b.start); + }); + } + + return result; +} + /** * @param {Object} schedule – Расписание Банды * @param {Number} duration - Время на ограбление в минутах @@ -16,7 +151,18 @@ exports.isStar = true; */ exports.getAppropriateMoment = function (schedule, duration, workingHours) { console.info(schedule, duration, workingHours); - + var bankStart = new DateTime("ПН " + workingHours.from); + var bankEnd = new DateTime("ПН " + workingHours.to); + var workingInterval = new Interval(bankStart, bankEnd); + schedule.Danny = NormalizeSchedule(schedule.Danny, workingInterval); + schedule.Rusty = NormalizeSchedule(schedule.Rusty, workingInterval); + schedule.Linus = NormalizeSchedule(schedule.Linus, workingInterval); + var robberyStart = null; + DAYS_OF_THE_WEEK.forEach(function(day) { + robberyStart = GetRobberyStart(schedule, workingInterval, duration, day); + }); + + return { /** @@ -24,7 +170,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {Boolean} */ exists: function () { - return false; + return robberyStart != null; }, /** @@ -35,7 +181,13 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {String} */ format: function (template) { - return template; + if (robberyStart == null) + return ""; + + return template + .replace("%DD", robberyStart.day.text) + .replace("%HH", robberyStart.hours) + .replace("%MM", robberyStart.minutes); }, /** diff --git a/test.html b/test.html new file mode 100644 index 0000000..1854fb0 --- /dev/null +++ b/test.html @@ -0,0 +1,213 @@ + + + + + + + + \ No newline at end of file From cb4d04fdd0453e1f3138571bd17ba8988e801b45 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 00:39:00 +0500 Subject: [PATCH 02/13] all --- robbery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robbery.js b/robbery.js index 93fcea1..dd6e695 100644 --- a/robbery.js +++ b/robbery.js @@ -4,7 +4,7 @@ * Сделано задание на звездочку * Реализовано оба метода и tryLater */ -exports.isStar = true; +exports.isStar = false; var HOURS_IN_DAY = 24; var MINUTES_IN_HOUR = 60; From 150dd5d011a79d7a26f9a128a3e08c15633556e5 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 00:46:08 +0500 Subject: [PATCH 03/13] all --- robbery.js | 78 ++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/robbery.js b/robbery.js index dd6e695..ba81caa 100644 --- a/robbery.js +++ b/robbery.js @@ -9,28 +9,28 @@ exports.isStar = false; var HOURS_IN_DAY = 24; var MINUTES_IN_HOUR = 60; var MINUTES_IN_DAY = HOURS_IN_DAY * 60; -var DAYS_OF_THE_WEEK = ["ПН", "ВТ", "СР"]; +var DAYS_OF_THE_WEEK = ['ПН', 'ВТ', 'СР']; function DayOfTheWeek(dayText) { this.days = DAYS_OF_THE_WEEK; - this.getNumber = function() { + this.getNumber = function () { return this.days.indexOf(this.text); - } + }; this.text = dayText; - this.addDays = function(days) { + this.addDays = function (days) { this.number += days % 7; }; - this.getText = function() { + this.getText = function () { return this.days[this.number]; }; - + return this; -}; +} function DateTime(dateTimeString) { this.day = new DayOfTheWeek(dateTimeString.slice(0, 2)); this.hours = parseInt(dateTimeString.slice(3, 5)); this.minutes = parseInt(dateTimeString.slice(6, 8)); this.timezone = parseInt(dateTimeString.split('+')[1]); - this.addMinutes = function(minutes) { + this.addMinutes = function (minutes) { var daysToAdd = Math.floor(minutes / MINUTES_IN_DAY); minutes -= MINUTES_IN_DAY * daysToAdd; var hoursToAdd = Math.floor(minutes / MINUTES_IN_HOUR); @@ -39,59 +39,57 @@ function DateTime(dateTimeString) { this.minutes += minutesToAdd; this.hours += hoursToAdd; this.day.addDays(daysToAdd); - + return; } - this.convertToTimezone = function(timezone) { + this.convertToTimezone = function (timezone) { var delta = timezone - this.timezone; this.addMinutes(delta * MINUTES_IN_HOUR); this.timezone = timezone; }; - this.getMinutesCountFromWeekStart = function() { + this.getMinutesCountFromWeekStart = function () { return MINUTES_IN_DAY * this.day.getNumber() + MINUTES_IN_HOUR * this.hours + this.minutes; }; - this.compareTo = function(other) { + this.compareTo = function (other) { return this.getMinutesCountFromWeekStart() - other.getMinutesCountFromWeekStart(); }; - + return this; } - function Interval(start, end) { this.start = start; this.end = end; - this.intersect = function(otherInterval) { + this.intersect = function (otherInterval) { var intersectionStart = this.start.compareTo(otherInterval.start) > 0 ? this.start : otherInterval.start; var intersectionEnd = this.end.compareTo(otherInterval.end) < 0 ? this.end : otherInterval.end; if(intersectionEnd.compareTo(intersectionStart) < 0) return null; - + return new Interval(intersectionStart, intersectionEnd); }; - this.union = function(otherInterval) { + this.union = function (otherInterval) { var intersectionStart = this.start.compareTo(otherInterval.start) < 0 ? this.start : otherInterval.start; var intersectionEnd = this.end.compareTo(otherInterval.end) > 0 ? this.end : otherInterval.end; - + return new Interval(intersectionStart, intersectionEnd); }; - + return this; } - function NormalizeSchedule(memberSchedule, workingInterval) { var newSchedule = []; - memberSchedule.forEach(function(busynessInfo) { + memberSchedule.forEach(function (busynessInfo) { var bankTimezone = workingInterval.start.timezone; var start = new DateTime(busynessInfo.from); var end = new DateTime(busynessInfo.to); start.convertToTimezone(bankTimezone); end.convertToTimezone(bankTimezone); var busynessInterval = new Interval(start, end); - DAYS_OF_THE_WEEK.forEach(function(dayOfTheWeek) { + DAYS_OF_THE_WEEK.forEach(function (dayOfTheWeek) { workingInterval.start.day = new DayOfTheWeek(dayOfTheWeek); workingInterval.end.day = new DayOfTheWeek(dayOfTheWeek); var intersection = busynessInterval.intersect(workingInterval); @@ -99,18 +97,17 @@ function NormalizeSchedule(memberSchedule, workingInterval) { newSchedule.push(intersection); }); }); - + return newSchedule; } - function GetRobberyStart(schedule, workingInterval, duration, day) { workingInterval.start.day = new DayOfTheWeek(day); workingInterval.end.day = new DayOfTheWeek(day); var allIntervals = schedule.Danny.concat(schedule.Rusty).concat(schedule.Linus); - allIntervals = allIntervals.filter(function(interval) { + allIntervals = allIntervals.filter(function (interval) { return interval.start.day.text == day; }); - allIntervals = allIntervals.sort(function(a, b) { + allIntervals = allIntervals.sort(function (a, b) { return a.start.compareTo(b.start); }); var result = null; @@ -133,11 +130,11 @@ function GetRobberyStart(schedule, workingInterval, duration, day) { else currentInterval = currentInterval.union(interval); }; - allIntervals = newAllIntervals.sort(function(a, b) { + allIntervals = newAllIntervals.sort(function (a, b) { return a.start.compareTo(b.start); }); } - + return result; } @@ -145,24 +142,23 @@ function GetRobberyStart(schedule, workingInterval, duration, day) { * @param {Object} schedule – Расписание Банды * @param {Number} duration - Время на ограбление в минутах * @param {Object} workingHours – Время работы банка - * @param {String} workingHours.from – Время открытия, например, "10:00+5" - * @param {String} workingHours.to – Время закрытия, например, "18:00+5" + * @param {String} workingHours.from – Время открытия, например, '10:00+5' + * @param {String} workingHours.to – Время закрытия, например, '18:00+5' * @returns {Object} */ exports.getAppropriateMoment = function (schedule, duration, workingHours) { console.info(schedule, duration, workingHours); - var bankStart = new DateTime("ПН " + workingHours.from); - var bankEnd = new DateTime("ПН " + workingHours.to); + var bankStart = new DateTime('ПН ' + workingHours.from); + var bankEnd = new DateTime('ПН ' + workingHours.to); var workingInterval = new Interval(bankStart, bankEnd); schedule.Danny = NormalizeSchedule(schedule.Danny, workingInterval); schedule.Rusty = NormalizeSchedule(schedule.Rusty, workingInterval); schedule.Linus = NormalizeSchedule(schedule.Linus, workingInterval); var robberyStart = null; - DAYS_OF_THE_WEEK.forEach(function(day) { + DAYS_OF_THE_WEEK.forEach(function (day) { robberyStart = GetRobberyStart(schedule, workingInterval, duration, day); }); - - + return { /** @@ -176,18 +172,18 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { /** * Возвращает отформатированную строку с часами для ограбления * Например, - * "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)" + * 'Начинаем в %HH:%MM (%DD)' -> 'Начинаем в 14:59 (СР)' * @param {String} template * @returns {String} */ format: function (template) { if (robberyStart == null) - return ""; - + return ''; + return template - .replace("%DD", robberyStart.day.text) - .replace("%HH", robberyStart.hours) - .replace("%MM", robberyStart.minutes); + .replace('%DD', robberyStart.day.text) + .replace('%HH', robberyStart.hours) + .replace('%MM', robberyStart.minutes); }, /** From bb4f596a434c971ad365b2a5f3988e233a06aab4 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 01:08:20 +0500 Subject: [PATCH 04/13] all --- robbery.js | 83 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/robbery.js b/robbery.js index ba81caa..e6d0db0 100644 --- a/robbery.js +++ b/robbery.js @@ -41,7 +41,7 @@ function DateTime(dateTimeString) { this.day.addDays(daysToAdd); return; - } + }; this.convertToTimezone = function (timezone) { var delta = timezone - this.timezone; this.addMinutes(delta * MINUTES_IN_HOUR); @@ -60,27 +60,28 @@ function Interval(start, end) { this.start = start; this.end = end; this.intersect = function (otherInterval) { - var intersectionStart = this.start.compareTo(otherInterval.start) > 0 ? - this.start : otherInterval.start; - var intersectionEnd = this.end.compareTo(otherInterval.end) < 0 ? - this.end : otherInterval.end; - if(intersectionEnd.compareTo(intersectionStart) < 0) + var intersectionStart = this.start.compareTo(otherInterval.start) > 0 + ? this.start : otherInterval.start; + var intersectionEnd = this.end.compareTo(otherInterval.end) < 0 + ? this.end : otherInterval.end; + if (intersectionEnd.compareTo(intersectionStart) < 0){ return null; + } return new Interval(intersectionStart, intersectionEnd); }; this.union = function (otherInterval) { - var intersectionStart = this.start.compareTo(otherInterval.start) < 0 ? - this.start : otherInterval.start; - var intersectionEnd = this.end.compareTo(otherInterval.end) > 0 ? - this.end : otherInterval.end; + var intersectionStart = this.start.compareTo(otherInterval.start) < 0 + ? this.start : otherInterval.start; + var intersectionEnd = this.end.compareTo(otherInterval.end) > 0 + ? this.end : otherInterval.end; return new Interval(intersectionStart, intersectionEnd); }; return this; } -function NormalizeSchedule(memberSchedule, workingInterval) { +function normalizeSchedule(memberSchedule, workingInterval) { var newSchedule = []; memberSchedule.forEach(function (busynessInfo) { var bankTimezone = workingInterval.start.timezone; @@ -93,49 +94,56 @@ function NormalizeSchedule(memberSchedule, workingInterval) { workingInterval.start.day = new DayOfTheWeek(dayOfTheWeek); workingInterval.end.day = new DayOfTheWeek(dayOfTheWeek); var intersection = busynessInterval.intersect(workingInterval); - if(intersection != null) + if (intersection !== null){ newSchedule.push(intersection); + } }); }); return newSchedule; } -function GetRobberyStart(schedule, workingInterval, duration, day) { - workingInterval.start.day = new DayOfTheWeek(day); - workingInterval.end.day = new DayOfTheWeek(day); - var allIntervals = schedule.Danny.concat(schedule.Rusty).concat(schedule.Linus); - allIntervals = allIntervals.filter(function (interval) { - return interval.start.day.text == day; - }); - allIntervals = allIntervals.sort(function (a, b) { - return a.start.compareTo(b.start); - }); +function findCompatibleInterval(allIntervals, workingInterval) { var result = null; var lastIntervalEnd = workingInterval.start; var currentInterval = allIntervals[0]; - while (allIntervals.length > 0 || result != null) { + while (allIntervals.length > 0 || result !== null) { currentInterval = allIntervals[0]; allIntervals = allIntervals.splice(1); - if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) + if (currentInterval.start.compareTo(lastIntervalEnd) >= duration){ return currentInterval.start; + } var newAllIntervals = []; - for(var i = 0; i < allIntervals.length; i +=1 ) { + for (var i = 0;i < allIntervals.length;i += 1 ) { var interval = allIntervals[i]; - if (currentInterval.intersect(interval) == null){ + if (currentInterval.intersect(interval) === null){ newAllIntervals.push(interval); - lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 ? - currentInterval.end : lastIntervalEnd; + lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 + ? currentInterval.end : lastIntervalEnd; break; } - else + else{ currentInterval = currentInterval.union(interval); - }; + } + } allIntervals = newAllIntervals.sort(function (a, b) { return a.start.compareTo(b.start); }); } - return result; + return result +} +function getRobberyStart(schedule, workingInterval, duration, day) { + workingInterval.start.day = new DayOfTheWeek(day); + workingInterval.end.day = new DayOfTheWeek(day); + var allIntervals = schedule.Danny.concat(schedule.Rusty).concat(schedule.Linus); + allIntervals = allIntervals.filter(function (interval) { + return interval.start.day.text === day; + }); + allIntervals = allIntervals.sort(function (a, b) { + return a.start.compareTo(b.start); + }); + + return findCompatibleInterval(allIntervals, workingInterval); } /** @@ -151,12 +159,12 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { var bankStart = new DateTime('ПН ' + workingHours.from); var bankEnd = new DateTime('ПН ' + workingHours.to); var workingInterval = new Interval(bankStart, bankEnd); - schedule.Danny = NormalizeSchedule(schedule.Danny, workingInterval); - schedule.Rusty = NormalizeSchedule(schedule.Rusty, workingInterval); - schedule.Linus = NormalizeSchedule(schedule.Linus, workingInterval); + schedule.Danny = normalizeSchedule(schedule.Danny, workingInterval); + schedule.Rusty = normalizeSchedule(schedule.Rusty, workingInterval); + schedule.Linus = normalizeSchedule(schedule.Linus, workingInterval); var robberyStart = null; DAYS_OF_THE_WEEK.forEach(function (day) { - robberyStart = GetRobberyStart(schedule, workingInterval, duration, day); + robberyStart = getRobberyStart(schedule, workingInterval, duration, day); }); return { @@ -166,7 +174,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {Boolean} */ exists: function () { - return robberyStart != null; + return robberyStart !== null; }, /** @@ -177,8 +185,9 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {String} */ format: function (template) { - if (robberyStart == null) + if (robberyStart === null){ return ''; + } return template .replace('%DD', robberyStart.day.text) From 498ab412bfcb475288365ff2382a0871115dd68c Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 01:23:35 +0500 Subject: [PATCH 05/13] all --- robbery.js | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/robbery.js b/robbery.js index e6d0db0..6db2095 100644 --- a/robbery.js +++ b/robbery.js @@ -61,10 +61,10 @@ function Interval(start, end) { this.end = end; this.intersect = function (otherInterval) { var intersectionStart = this.start.compareTo(otherInterval.start) > 0 - ? this.start : otherInterval.start; + ? this.start : otherInterval.start; var intersectionEnd = this.end.compareTo(otherInterval.end) < 0 - ? this.end : otherInterval.end; - if (intersectionEnd.compareTo(intersectionStart) < 0){ + ? this.end : otherInterval.end; + if (intersectionEnd.compareTo(intersectionStart) < 0) { return null; } @@ -72,9 +72,9 @@ function Interval(start, end) { }; this.union = function (otherInterval) { var intersectionStart = this.start.compareTo(otherInterval.start) < 0 - ? this.start : otherInterval.start; + ? this.start : otherInterval.start; var intersectionEnd = this.end.compareTo(otherInterval.end) > 0 - ? this.end : otherInterval.end; + ? this.end : otherInterval.end; return new Interval(intersectionStart, intersectionEnd); }; @@ -94,7 +94,7 @@ function normalizeSchedule(memberSchedule, workingInterval) { workingInterval.start.day = new DayOfTheWeek(dayOfTheWeek); workingInterval.end.day = new DayOfTheWeek(dayOfTheWeek); var intersection = busynessInterval.intersect(workingInterval); - if (intersection !== null){ + if (intersection !== null) { newSchedule.push(intersection); } }); @@ -102,35 +102,40 @@ function normalizeSchedule(memberSchedule, workingInterval) { return newSchedule; } -function findCompatibleInterval(allIntervals, workingInterval) { +function getNewAllIntervals(allIntervals, lastIntervalEnd) { + var newAllIntervals = []; + for (var i = 0; i < allIntervals.length; i += 1) { + var interval = allIntervals[i]; + if (currentInterval.intersect(interval) === null) { + newAllIntervals.push(interval); + lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 + ? currentInterval.end : lastIntervalEnd; + break; + } + else { + currentInterval = currentInterval.union(interval); + } + } + + return newAllIntervals; +} +function findCompatibleInterval(allIntervals, workingInterval, duration) { var result = null; var lastIntervalEnd = workingInterval.start; var currentInterval = allIntervals[0]; while (allIntervals.length > 0 || result !== null) { currentInterval = allIntervals[0]; allIntervals = allIntervals.splice(1); - if (currentInterval.start.compareTo(lastIntervalEnd) >= duration){ + if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) { return currentInterval.start; } - var newAllIntervals = []; - for (var i = 0;i < allIntervals.length;i += 1 ) { - var interval = allIntervals[i]; - if (currentInterval.intersect(interval) === null){ - newAllIntervals.push(interval); - lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 - ? currentInterval.end : lastIntervalEnd; - break; - } - else{ - currentInterval = currentInterval.union(interval); - } - } + var newAllIntervals = getNewAllIntervals(allIntervals, lastIntervalEnd); allIntervals = newAllIntervals.sort(function (a, b) { return a.start.compareTo(b.start); }); } - return result + return result; } function getRobberyStart(schedule, workingInterval, duration, day) { workingInterval.start.day = new DayOfTheWeek(day); @@ -185,7 +190,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { * @returns {String} */ format: function (template) { - if (robberyStart === null){ + if (robberyStart === null) { return ''; } From 5e129d93dd503e6625cf979b79c52e63204ec5a5 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 01:28:50 +0500 Subject: [PATCH 06/13] all --- robbery.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/robbery.js b/robbery.js index 6db2095..68c3bb0 100644 --- a/robbery.js +++ b/robbery.js @@ -102,7 +102,7 @@ function normalizeSchedule(memberSchedule, workingInterval) { return newSchedule; } -function getNewAllIntervals(allIntervals, lastIntervalEnd) { +function getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval) { var newAllIntervals = []; for (var i = 0; i < allIntervals.length; i += 1) { var interval = allIntervals[i]; @@ -111,8 +111,7 @@ function getNewAllIntervals(allIntervals, lastIntervalEnd) { lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 ? currentInterval.end : lastIntervalEnd; break; - } - else { + } else { currentInterval = currentInterval.union(interval); } } @@ -148,7 +147,7 @@ function getRobberyStart(schedule, workingInterval, duration, day) { return a.start.compareTo(b.start); }); - return findCompatibleInterval(allIntervals, workingInterval); + return findCompatibleInterval(allIntervals, workingInterval, duration); } /** From 91c9155f266fd63deb0397ed86dc6021965e0a3f Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 01:31:48 +0500 Subject: [PATCH 07/13] all --- robbery.js | 2 +- test.html | 170 ++++++++++++++++++++++++++++------------------------- 2 files changed, 91 insertions(+), 81 deletions(-) diff --git a/robbery.js b/robbery.js index 68c3bb0..6165b99 100644 --- a/robbery.js +++ b/robbery.js @@ -128,7 +128,7 @@ function findCompatibleInterval(allIntervals, workingInterval, duration) { if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) { return currentInterval.start; } - var newAllIntervals = getNewAllIntervals(allIntervals, lastIntervalEnd); + var newAllIntervals = getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval); allIntervals = newAllIntervals.sort(function (a, b) { return a.start.compareTo(b.start); }); diff --git a/test.html b/test.html index 1854fb0..31c5114 100644 --- a/test.html +++ b/test.html @@ -10,28 +10,28 @@ var HOURS_IN_DAY = 24; var MINUTES_IN_HOUR = 60; var MINUTES_IN_DAY = HOURS_IN_DAY * 60; - var DAYS_OF_THE_WEEK = ["ПН", "ВТ", "СР"]; + var DAYS_OF_THE_WEEK = ['ПН', 'ВТ', 'СР']; function DayOfTheWeek(dayText) { this.days = DAYS_OF_THE_WEEK; - this.getNumber = function() { + this.getNumber = function () { return this.days.indexOf(this.text); - } + }; this.text = dayText; - this.addDays = function(days) { + this.addDays = function (days) { this.number += days % 7; }; - this.getText = function() { + this.getText = function () { return this.days[this.number]; }; - + return this; - }; + } function DateTime(dateTimeString) { this.day = new DayOfTheWeek(dateTimeString.slice(0, 2)); this.hours = parseInt(dateTimeString.slice(3, 5)); this.minutes = parseInt(dateTimeString.slice(6, 8)); this.timezone = parseInt(dateTimeString.split('+')[1]); - this.addMinutes = function(minutes) { + this.addMinutes = function (minutes) { var daysToAdd = Math.floor(minutes / MINUTES_IN_DAY); minutes -= MINUTES_IN_DAY * daysToAdd; var hoursToAdd = Math.floor(minutes / MINUTES_IN_HOUR); @@ -40,130 +40,138 @@ this.minutes += minutesToAdd; this.hours += hoursToAdd; this.day.addDays(daysToAdd); - + return; - } - this.convertToTimezone = function(timezone) { + }; + this.convertToTimezone = function (timezone) { var delta = timezone - this.timezone; this.addMinutes(delta * MINUTES_IN_HOUR); this.timezone = timezone; }; - this.getMinutesCountFromWeekStart = function() { + this.getMinutesCountFromWeekStart = function () { return MINUTES_IN_DAY * this.day.getNumber() + MINUTES_IN_HOUR * this.hours + this.minutes; }; - this.compareTo = function(other) { + this.compareTo = function (other) { return this.getMinutesCountFromWeekStart() - other.getMinutesCountFromWeekStart(); }; - + return this; } - function Interval(start, end) { this.start = start; this.end = end; - this.intersect = function(otherInterval) { - var intersectionStart = this.start.compareTo(otherInterval.start) > 0 ? - this.start : otherInterval.start; - var intersectionEnd = this.end.compareTo(otherInterval.end) < 0 ? - this.end : otherInterval.end; - if(intersectionEnd.compareTo(intersectionStart) < 0) + this.intersect = function (otherInterval) { + var intersectionStart = this.start.compareTo(otherInterval.start) > 0 + ? this.start : otherInterval.start; + var intersectionEnd = this.end.compareTo(otherInterval.end) < 0 + ? this.end : otherInterval.end; + if (intersectionEnd.compareTo(intersectionStart) < 0) { return null; - + } + return new Interval(intersectionStart, intersectionEnd); }; - this.union = function(otherInterval) { - var intersectionStart = this.start.compareTo(otherInterval.start) < 0 ? - this.start : otherInterval.start; - var intersectionEnd = this.end.compareTo(otherInterval.end) > 0 ? - this.end : otherInterval.end; - + this.union = function (otherInterval) { + var intersectionStart = this.start.compareTo(otherInterval.start) < 0 + ? this.start : otherInterval.start; + var intersectionEnd = this.end.compareTo(otherInterval.end) > 0 + ? this.end : otherInterval.end; + return new Interval(intersectionStart, intersectionEnd); }; - + return this; } - - function NormalizeSchedule(memberSchedule, workingInterval) { + function normalizeSchedule(memberSchedule, workingInterval) { var newSchedule = []; - memberSchedule.forEach(function(busynessInfo) { + memberSchedule.forEach(function (busynessInfo) { var bankTimezone = workingInterval.start.timezone; var start = new DateTime(busynessInfo.from); var end = new DateTime(busynessInfo.to); start.convertToTimezone(bankTimezone); end.convertToTimezone(bankTimezone); var busynessInterval = new Interval(start, end); - DAYS_OF_THE_WEEK.forEach(function(dayOfTheWeek) { + DAYS_OF_THE_WEEK.forEach(function (dayOfTheWeek) { workingInterval.start.day = new DayOfTheWeek(dayOfTheWeek); workingInterval.end.day = new DayOfTheWeek(dayOfTheWeek); var intersection = busynessInterval.intersect(workingInterval); - if(intersection != null) + if (intersection !== null) { newSchedule.push(intersection); + } }); }); - + return newSchedule; } + function getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval) { + var newAllIntervals = []; + for (var i = 0; i < allIntervals.length; i += 1) { + var interval = allIntervals[i]; + if (currentInterval.intersect(interval) === null) { + newAllIntervals.push(interval); + lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 + ? currentInterval.end : lastIntervalEnd; + break; + } else { + currentInterval = currentInterval.union(interval); + } + } - function GetRobberyStart(schedule, workingInterval, duration, day) { - workingInterval.start.day = new DayOfTheWeek(day); - workingInterval.end.day = new DayOfTheWeek(day); - var allIntervals = schedule.Danny.concat(schedule.Rusty).concat(schedule.Linus); - allIntervals = allIntervals.filter(function(interval) { - return interval.start.day.text == day; - }); - allIntervals = allIntervals.sort(function(a, b) { - return a.start.compareTo(b.start); - }); + return newAllIntervals; + } + function findCompatibleInterval(allIntervals, workingInterval, duration) { var result = null; var lastIntervalEnd = workingInterval.start; var currentInterval = allIntervals[0]; - while (allIntervals.length > 0 || result != null) { + while (allIntervals.length > 0 || result !== null) { currentInterval = allIntervals[0]; allIntervals = allIntervals.splice(1); - if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) + if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) { return currentInterval.start; - var newAllIntervals = []; - for(var i = 0; i < allIntervals.length; i +=1 ) { - var interval = allIntervals[i]; - if (currentInterval.intersect(interval) == null){ - newAllIntervals.push(interval); - lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 ? - currentInterval.end : lastIntervalEnd; - break; - } - else - currentInterval = currentInterval.union(interval); - }; - allIntervals = newAllIntervals.sort(function(a, b) { + } + var newAllIntervals = getNewAllIntervals(allIntervals, lastIntervalEnd); + allIntervals = newAllIntervals.sort(function (a, b) { return a.start.compareTo(b.start); }); } - + return result; } + function getRobberyStart(schedule, workingInterval, duration, day) { + workingInterval.start.day = new DayOfTheWeek(day); + workingInterval.end.day = new DayOfTheWeek(day); + var allIntervals = schedule.Danny.concat(schedule.Rusty).concat(schedule.Linus); + allIntervals = allIntervals.filter(function (interval) { + return interval.start.day.text === day; + }); + allIntervals = allIntervals.sort(function (a, b) { + return a.start.compareTo(b.start); + }); + + return findCompatibleInterval(allIntervals, workingInterval, duration); + } /** * @param {Object} schedule – Расписание Банды * @param {Number} duration - Время на ограбление в минутах * @param {Object} workingHours – Время работы банка - * @param {String} workingHours.from – Время открытия, например, "10:00+5" - * @param {String} workingHours.to – Время закрытия, например, "18:00+5" + * @param {String} workingHours.from – Время открытия, например, '10:00+5' + * @param {String} workingHours.to – Время закрытия, например, '18:00+5' * @returns {Object} */ exports.getAppropriateMoment = function (schedule, duration, workingHours) { console.info(schedule, duration, workingHours); - var bankStart = new DateTime("ПН " + workingHours.from); - var bankEnd = new DateTime("ПН " + workingHours.to); + var bankStart = new DateTime('ПН ' + workingHours.from); + var bankEnd = new DateTime('ПН ' + workingHours.to); var workingInterval = new Interval(bankStart, bankEnd); - schedule.Danny = NormalizeSchedule(schedule.Danny, workingInterval); - schedule.Rusty = NormalizeSchedule(schedule.Rusty, workingInterval); - schedule.Linus = NormalizeSchedule(schedule.Linus, workingInterval); + schedule.Danny = normalizeSchedule(schedule.Danny, workingInterval); + schedule.Rusty = normalizeSchedule(schedule.Rusty, workingInterval); + schedule.Linus = normalizeSchedule(schedule.Linus, workingInterval); var robberyStart = null; - DAYS_OF_THE_WEEK.forEach(function(day) { - robberyStart = GetRobberyStart(schedule, workingInterval, duration, day); + DAYS_OF_THE_WEEK.forEach(function (day) { + robberyStart = getRobberyStart(schedule, workingInterval, duration, day); }); - - + return { /** @@ -171,24 +179,25 @@ * @returns {Boolean} */ exists: function () { - return robberyStart != null; + return robberyStart !== null; }, /** * Возвращает отформатированную строку с часами для ограбления * Например, - * "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)" + * 'Начинаем в %HH:%MM (%DD)' -> 'Начинаем в 14:59 (СР)' * @param {String} template * @returns {String} */ format: function (template) { - if (robberyStart == null) - return ""; - + if (robberyStart === null) { + return ''; + } + return template - .replace("%DD", robberyStart.day.text) - .replace("%HH", robberyStart.hours) - .replace("%MM", robberyStart.minutes); + .replace('%DD', robberyStart.day.text) + .replace('%HH', robberyStart.hours) + .replace('%MM', robberyStart.minutes); }, /** @@ -206,6 +215,7 @@ + From f94c00e1dd65195522113366cca4bdaf61fda18e Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 02:43:09 +0500 Subject: [PATCH 08/13] all --- robbery.js | 17 +++++++++++------ test.html | 17 +++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/robbery.js b/robbery.js index 6165b99..3de2e8a 100644 --- a/robbery.js +++ b/robbery.js @@ -110,13 +110,12 @@ function getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval) { newAllIntervals.push(interval); lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 ? currentInterval.end : lastIntervalEnd; - break; } else { currentInterval = currentInterval.union(interval); } } - return newAllIntervals; + return { intervals: newAllIntervals, lastIntervalEnd: lastIntervalEnd }; } function findCompatibleInterval(allIntervals, workingInterval, duration) { var result = null; @@ -126,9 +125,11 @@ function findCompatibleInterval(allIntervals, workingInterval, duration) { currentInterval = allIntervals[0]; allIntervals = allIntervals.splice(1); if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) { - return currentInterval.start; + return lastIntervalEnd; } - var newAllIntervals = getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval); + var newAllIntervalsResult = getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval); + var newAllIntervals = newAllIntervalsResult.intervals; + lastIntervalEnd = newAllIntervalsResult.lastIntervalEnd; allIntervals = newAllIntervals.sort(function (a, b) { return a.start.compareTo(b.start); }); @@ -167,9 +168,13 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { schedule.Rusty = normalizeSchedule(schedule.Rusty, workingInterval); schedule.Linus = normalizeSchedule(schedule.Linus, workingInterval); var robberyStart = null; - DAYS_OF_THE_WEEK.forEach(function (day) { + for (var i = 0; i < DAYS_OF_THE_WEEK.length; i += 1) { + var day = DAYS_OF_THE_WEEK[i]; robberyStart = getRobberyStart(schedule, workingInterval, duration, day); - }); + if (robberyStart !== null) { + break; + } + } return { diff --git a/test.html b/test.html index 31c5114..7e81c41 100644 --- a/test.html +++ b/test.html @@ -111,13 +111,12 @@ newAllIntervals.push(interval); lastIntervalEnd = currentInterval.end.compareTo(lastIntervalEnd) > 0 ? currentInterval.end : lastIntervalEnd; - break; } else { currentInterval = currentInterval.union(interval); } } - return newAllIntervals; + return { intervals: newAllIntervals, lastIntervalEnd: lastIntervalEnd }; } function findCompatibleInterval(allIntervals, workingInterval, duration) { var result = null; @@ -127,9 +126,11 @@ currentInterval = allIntervals[0]; allIntervals = allIntervals.splice(1); if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) { - return currentInterval.start; + return lastIntervalEnd; } - var newAllIntervals = getNewAllIntervals(allIntervals, lastIntervalEnd); + var newAllIntervalsResult = getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval); + var newAllIntervals = newAllIntervalsResult.intervals; + lastIntervalEnd = newAllIntervalsResult.lastIntervalEnd; allIntervals = newAllIntervals.sort(function (a, b) { return a.start.compareTo(b.start); }); @@ -168,9 +169,13 @@ schedule.Rusty = normalizeSchedule(schedule.Rusty, workingInterval); schedule.Linus = normalizeSchedule(schedule.Linus, workingInterval); var robberyStart = null; - DAYS_OF_THE_WEEK.forEach(function (day) { + for (var i = 0; i < DAYS_OF_THE_WEEK.length; i += 1) { + var day = DAYS_OF_THE_WEEK[i]; robberyStart = getRobberyStart(schedule, workingInterval, duration, day); - }); + if (robberyStart !== null) { + break; + } + } return { From 54f332f03fb5c153fde3b6bd224baa3b3f560ea8 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 02:45:25 +0500 Subject: [PATCH 09/13] all --- robbery.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/robbery.js b/robbery.js index 3de2e8a..3cb3fd3 100644 --- a/robbery.js +++ b/robbery.js @@ -127,7 +127,8 @@ function findCompatibleInterval(allIntervals, workingInterval, duration) { if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) { return lastIntervalEnd; } - var newAllIntervalsResult = getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval); + var newAllIntervalsResult = getNewAllIntervals(allIntervals, + lastIntervalEnd, currentInterval); var newAllIntervals = newAllIntervalsResult.intervals; lastIntervalEnd = newAllIntervalsResult.lastIntervalEnd; allIntervals = newAllIntervals.sort(function (a, b) { From 1f76adb0eba6cf6d77d3197027f02551ef93fc64 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 02:46:55 +0500 Subject: [PATCH 10/13] all --- robbery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robbery.js b/robbery.js index 3cb3fd3..cfa1095 100644 --- a/robbery.js +++ b/robbery.js @@ -127,7 +127,7 @@ function findCompatibleInterval(allIntervals, workingInterval, duration) { if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) { return lastIntervalEnd; } - var newAllIntervalsResult = getNewAllIntervals(allIntervals, + var newAllIntervalsResult = getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval); var newAllIntervals = newAllIntervalsResult.intervals; lastIntervalEnd = newAllIntervalsResult.lastIntervalEnd; From 18a3da5e29cd202b18cfed83c4368936bd2a48f4 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 02:51:17 +0500 Subject: [PATCH 11/13] all --- robbery.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/robbery.js b/robbery.js index cfa1095..806cf25 100644 --- a/robbery.js +++ b/robbery.js @@ -201,8 +201,10 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { return template .replace('%DD', robberyStart.day.text) - .replace('%HH', robberyStart.hours) - .replace('%MM', robberyStart.minutes); + .replace('%HH', robberyStart.hours < 10 + ? "0" + robberyStart.hours : robberyStart.hours) + .replace('%MM', robberyStart.minutes < 10 + ? "0" + robberyStart.minutes : robberyStart.minutes); }, /** From d4785cade81b5e6c13f3f220cc0a96911e0b466e Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 02:53:04 +0500 Subject: [PATCH 12/13] all --- robbery.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/robbery.js b/robbery.js index 806cf25..1c99814 100644 --- a/robbery.js +++ b/robbery.js @@ -202,9 +202,9 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { return template .replace('%DD', robberyStart.day.text) .replace('%HH', robberyStart.hours < 10 - ? "0" + robberyStart.hours : robberyStart.hours) + ? '0' + robberyStart.hours : robberyStart.hours) .replace('%MM', robberyStart.minutes < 10 - ? "0" + robberyStart.minutes : robberyStart.minutes); + ? '0' + robberyStart.minutes : robberyStart.minutes); }, /** From 1f2b745f49a33f6725acd71f6652c69efbb78bc6 Mon Sep 17 00:00:00 2001 From: ilearnf Date: Thu, 19 Oct 2017 03:06:13 +0500 Subject: [PATCH 13/13] all --- test.html | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test.html b/test.html index 7e81c41..5cc5c0b 100644 --- a/test.html +++ b/test.html @@ -10,7 +10,7 @@ var HOURS_IN_DAY = 24; var MINUTES_IN_HOUR = 60; var MINUTES_IN_DAY = HOURS_IN_DAY * 60; - var DAYS_OF_THE_WEEK = ['ПН', 'ВТ', 'СР']; + var DAYS_OF_THE_WEEK = ['ПН', 'ВТ', 'СР', "ЧТ", "ПТ", "СБ", "ВС"]; function DayOfTheWeek(dayText) { this.days = DAYS_OF_THE_WEEK; this.getNumber = function () { @@ -91,7 +91,7 @@ start.convertToTimezone(bankTimezone); end.convertToTimezone(bankTimezone); var busynessInterval = new Interval(start, end); - DAYS_OF_THE_WEEK.forEach(function (dayOfTheWeek) { + DAYS_OF_THE_WEEK.slice(0, 3).forEach(function (dayOfTheWeek) { workingInterval.start.day = new DayOfTheWeek(dayOfTheWeek); workingInterval.end.day = new DayOfTheWeek(dayOfTheWeek); var intersection = busynessInterval.intersect(workingInterval); @@ -128,7 +128,8 @@ if (currentInterval.start.compareTo(lastIntervalEnd) >= duration) { return lastIntervalEnd; } - var newAllIntervalsResult = getNewAllIntervals(allIntervals, lastIntervalEnd, currentInterval); + var newAllIntervalsResult = getNewAllIntervals(allIntervals, + lastIntervalEnd, currentInterval); var newAllIntervals = newAllIntervalsResult.intervals; lastIntervalEnd = newAllIntervalsResult.lastIntervalEnd; allIntervals = newAllIntervals.sort(function (a, b) { @@ -169,7 +170,7 @@ schedule.Rusty = normalizeSchedule(schedule.Rusty, workingInterval); schedule.Linus = normalizeSchedule(schedule.Linus, workingInterval); var robberyStart = null; - for (var i = 0; i < DAYS_OF_THE_WEEK.length; i += 1) { + for (var i = 0; i < DAYS_OF_THE_WEEK.slice(0, 3).length; i += 1) { var day = DAYS_OF_THE_WEEK[i]; robberyStart = getRobberyStart(schedule, workingInterval, duration, day); if (robberyStart !== null) { @@ -201,8 +202,10 @@ return template .replace('%DD', robberyStart.day.text) - .replace('%HH', robberyStart.hours) - .replace('%MM', robberyStart.minutes); + .replace('%HH', robberyStart.hours < 10 + ? '0' + robberyStart.hours : robberyStart.hours) + .replace('%MM', robberyStart.minutes < 10 + ? '0' + robberyStart.minutes : robberyStart.minutes); }, /** @@ -221,6 +224,7 @@ +