From 50cdde7f7c2ebfdf9fe4307a75c8becb660c9215 Mon Sep 17 00:00:00 2001 From: lenastar Date: Tue, 30 Oct 2018 00:07:26 +0300 Subject: [PATCH 1/9] First solution --- robbery.js | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 3 deletions(-) diff --git a/robbery.js b/robbery.js index ed84b5d..6fd5698 100755 --- a/robbery.js +++ b/robbery.js @@ -4,7 +4,50 @@ * Сделано задание на звездочку * Реализовано оба метода и tryLater */ -const isStar = true; +const isStar = false; +const dayOfWeek = []; +dayOfWeek['ПН'] = 0; +dayOfWeek['ВТ'] = 1; +dayOfWeek['СР'] = 2; +const backToDay = ['ПН', 'ВТ', 'СР']; +let timezone = 0; + + +class Time { + constructor(minutes, day) { + this.minutes = minutes; + this.day = day; + } + + getMinutes() { + return this.minutes; + } + + getTimeFromMinutes() { + return { + day: backToDay[this.day], + hours: Math.floor(this.minutes / 60) + timezone, + minutes: this.minutes - 60 * Math.floor(this.minutes / 60) + }; + } + + getDifference(time) { + return Math.abs(this.getMinutes() - time.getMinutes()); + } + +} + +class Section { + constructor(from, to) { + this.from = from; + this.to = to; + } + + isNoIntersection(section) { + return section.to.getMinutes() < this.from.getMinutes() || + section.from.getMinutes() > this.to.getMinutes(); + } +} /** * @param {Object} schedule – Расписание Банды @@ -24,7 +67,7 @@ function getAppropriateMoment(schedule, duration, workingHours) { * @returns {Boolean} */ exists: function () { - return false; + return this.format('%DD %HH:%MM') !== ''; }, /** @@ -34,7 +77,35 @@ function getAppropriateMoment(schedule, duration, workingHours) { * @returns {String} */ format: function (template) { - return template; + let _schedule = Object.keys(schedule).map(x => schedule[x]); + let sections = []; + for (let i = 0; i < 3; i++) { + sections[i] = []; + } + for (let i of _schedule) { + for (let j of i) { + let from = parseTime(j.from); + let to = parseTime(j.to); + if (from.day !== to.day) { + sections[from.day].push(new Section(from, new Time(1440, from.day))); + sections[to.day].push(new Section(new Time(0, to.day), to)); + } else { + sections[from.day].push(new Section(from, to)); + } + } + } + let result = findTime(duration, sections, workingHours); + if (result === null) { + return ''; + } + result = result.getTimeFromMinutes(); + let _template = template.replace(/%HH:%MM/, + `${result.hours}:${result.minutes}`); + _template = _template.replace(/%DD/, + result.day.toString()); + + return _template; + }, /** @@ -48,6 +119,107 @@ function getAppropriateMoment(schedule, duration, workingHours) { }; } +function findTime(duration, sections, workingHours) { + let result = null; + let whFromTime = parseWorkingHours(workingHours.from); + let whToTime = parseWorkingHours(workingHours.to); + for (let i = 0; i < 3; i++) { + let intersections = []; + let section = sections[i].sort((a, b) => { + return a.from.getMinutes() - b.from.getMinutes(); + }); + for (let j = 0; j < section.length; j++) { + let intersection = section.filter(x => x === section[j] || + !section[j].isNoIntersection(x)); + if (intersection.length !== 0) { + intersections.push(intersection); + intersections = intersections.filter(x => { + return (x === intersection || + JSON.stringify(x) !== JSON.stringify(intersection)); + }); + } + if (intersection.length === section.length) { + break; + } + } + if (intersections.length === 1) { + console.info(intersections[0][0]); + let min = Array.min(intersections.map(x => x[0].from.getMinutes())); + let max = Array.max(intersections.map(x => x[0].to.getMinutes())); + if (min - whFromTime.getMinutes() >= duration) { + result = new Time(whFromTime.getMinutes(), i); + } + if (whToTime.getMinutes() - max >= duration) { + result = new Time(max, i); + } + } else if (intersections.length === 0) { + result = findWithoutIntersection(intersections, i, whFromTime, whToTime, duration); + if (result !== null) { + return result; + } + } else { + let _sections = []; + for (let n = 0; n < intersections.length; n++) { + let _from = Array.min(intersections[n].map(x => x.from.getMinutes())); + let _to = Array.max(intersections[n].map(x => x.to.getMinutes())); + _sections.push(new Section(_from, _to)); + } + result = findWithoutIntersection(_sections, i, whFromTime, whToTime, duration); + if (result !== null) { + return result; + } + } + } + + return result; +} + +function findWithoutIntersection(section, day, whFromTime, whToTime, duration) { + let result = null; + let start = whFromTime.getMinutes(); + for (let m of section) { + if (m.from - start >= duration && m.from < whToTime.getMinutes()) { + console.info('зашли сюда, когда', m.from, start); + result = new Time(start, day); + break; + } + start = m.to; + } + if (whToTime.getMinutes() - section[section.length - 1] >= duration) { + result = new Time(section[section.length - 1], day); + } + + return result; +} + +Array.max = function (array) { + return Math.max.apply(Math, array); +}; + +Array.min = function (array) { + return Math.min.apply(Math, array); +}; + +function parseWorkingHours(str) { + timezone = parseInt(str.substr(6, 2)); + let hours = parseInt(str.substr(0, 2)) - timezone; + let minutes = parseInt(str.substr(3, 2)); + + return new Time(hoursToMinutes(hours, minutes), 'all'); +} + +function hoursToMinutes(hours, minutes) { + return hours * 60 + minutes; +} + +function parseTime(str) { + let hours = parseInt(str.substr(3, 2)) - parseInt(str.substr(-1, 2)); + let minutes = parseInt(str.substr(6, 2)); + let day = dayOfWeek[str.substr(0, 2)]; + + return new Time(hoursToMinutes(hours, minutes), day); +} + module.exports = { getAppropriateMoment, From 5ef07f1c787133f942a8d74f29f203a96fddc2df Mon Sep 17 00:00:00 2001 From: lenastar Date: Tue, 30 Oct 2018 01:08:25 +0300 Subject: [PATCH 2/9] Refactore --- robbery.js | 141 +++++++++++++++++++++++++++-------------------------- 1 file changed, 72 insertions(+), 69 deletions(-) diff --git a/robbery.js b/robbery.js index 6fd5698..5406e13 100755 --- a/robbery.js +++ b/robbery.js @@ -77,35 +77,28 @@ function getAppropriateMoment(schedule, duration, workingHours) { * @returns {String} */ format: function (template) { - let _schedule = Object.keys(schedule).map(x => schedule[x]); + let _schedule = []; + Object + .keys(schedule) + .map(x => schedule[x]) + .forEach(x => x.forEach(y=>_schedule.push(y))); let sections = []; for (let i = 0; i < 3; i++) { sections[i] = []; } for (let i of _schedule) { - for (let j of i) { - let from = parseTime(j.from); - let to = parseTime(j.to); - if (from.day !== to.day) { - sections[from.day].push(new Section(from, new Time(1440, from.day))); - sections[to.day].push(new Section(new Time(0, to.day), to)); - } else { - sections[from.day].push(new Section(from, to)); - } + let from = parseTime(i.from); + let to = parseTime(i.to); + if (from.day !== to.day) { + sections[from.day].push(new Section(from, new Time(1440, from.day))); + sections[to.day].push(new Section(new Time(0, to.day), to)); + } else { + sections[from.day].push(new Section(from, to)); } } let result = findTime(duration, sections, workingHours); - if (result === null) { - return ''; - } - result = result.getTimeFromMinutes(); - let _template = template.replace(/%HH:%MM/, - `${result.hours}:${result.minutes}`); - _template = _template.replace(/%DD/, - result.day.toString()); - - return _template; + return result !== null ? formatTime(template, result.getTimeFromMinutes()) : ''; }, /** @@ -119,63 +112,81 @@ function getAppropriateMoment(schedule, duration, workingHours) { }; } -function findTime(duration, sections, workingHours) { +function formatTime(template, time) { + let _template = template.replace(/%HH:%MM/, + `${time.hours}:${time.minutes}`); + _template = _template.replace(/%DD/, + time.day); + + return _template; +} + +function findWithOneIntersection(intersections, day, workingHours, duration) { let result = null; let whFromTime = parseWorkingHours(workingHours.from); let whToTime = parseWorkingHours(workingHours.to); + let min = intersections[0][0].from.getMinutes(); + let max = intersections[0][intersections.length - 1].to.getMinutes(); + if (min - whFromTime.getMinutes() >= duration) { + result = new Time(whFromTime.getMinutes(), day); + } + if (whToTime.getMinutes() - max >= duration) { + result = new Time(max, day); + } + + return result; +} + +function findWithSomeIntersections(intersections, day, workingHours, duration) { + let result = null; + let _sections = []; + for (let n of intersections) { + let _from = n[0].from.getMinutes(); + let _to = n[0].to.getMinutes(); + _sections.push(new Section(_from, _to)); + } + result = findWithoutIntersection(_sections, day, workingHours, duration); + + return result; +} + +function findTime(duration, sections, workingHours) { + let result = null; + sections = sections.map(x=> x.sort((a, b) => { + return a.from.getMinutes() - b.from.getMinutes(); + })); + for (let i = 0; i < 3; i++) { let intersections = []; - let section = sections[i].sort((a, b) => { - return a.from.getMinutes() - b.from.getMinutes(); - }); - for (let j = 0; j < section.length; j++) { - let intersection = section.filter(x => x === section[j] || - !section[j].isNoIntersection(x)); - if (intersection.length !== 0) { - intersections.push(intersection); - intersections = intersections.filter(x => { - return (x === intersection || - JSON.stringify(x) !== JSON.stringify(intersection)); - }); - } - if (intersection.length === section.length) { - break; - } + let section = sections[i] + .sort((a, b) => { + return a.from.getMinutes() - b.from.getMinutes(); + }); + for (let j of section) { + let intersection = section.filter(x => x === j || + !j.isNoIntersection(x)); + intersections.push(intersection); + intersections = intersections.filter(x => { + return (x === intersection || + JSON.stringify(x) !== JSON.stringify(intersection)); + }); } if (intersections.length === 1) { - console.info(intersections[0][0]); - let min = Array.min(intersections.map(x => x[0].from.getMinutes())); - let max = Array.max(intersections.map(x => x[0].to.getMinutes())); - if (min - whFromTime.getMinutes() >= duration) { - result = new Time(whFromTime.getMinutes(), i); - } - if (whToTime.getMinutes() - max >= duration) { - result = new Time(max, i); - } + findWithOneIntersection(intersections, i, workingHours, duration); } else if (intersections.length === 0) { - result = findWithoutIntersection(intersections, i, whFromTime, whToTime, duration); - if (result !== null) { - return result; - } + result = findWithoutIntersection(intersections, i, workingHours, duration); } else { - let _sections = []; - for (let n = 0; n < intersections.length; n++) { - let _from = Array.min(intersections[n].map(x => x.from.getMinutes())); - let _to = Array.max(intersections[n].map(x => x.to.getMinutes())); - _sections.push(new Section(_from, _to)); - } - result = findWithoutIntersection(_sections, i, whFromTime, whToTime, duration); - if (result !== null) { - return result; - } + result = findWithSomeIntersections(intersections, i, workingHours, duration); } } return result; } -function findWithoutIntersection(section, day, whFromTime, whToTime, duration) { +function findWithoutIntersection(section, day, workingHours, duration) { let result = null; + let whFromTime = parseWorkingHours(workingHours.from); + let whToTime = parseWorkingHours(workingHours.to); let start = whFromTime.getMinutes(); for (let m of section) { if (m.from - start >= duration && m.from < whToTime.getMinutes()) { @@ -192,14 +203,6 @@ function findWithoutIntersection(section, day, whFromTime, whToTime, duration) { return result; } -Array.max = function (array) { - return Math.max.apply(Math, array); -}; - -Array.min = function (array) { - return Math.min.apply(Math, array); -}; - function parseWorkingHours(str) { timezone = parseInt(str.substr(6, 2)); let hours = parseInt(str.substr(0, 2)) - timezone; From 707a89e0c12ef23dcdcd1f29505d5d0462036324 Mon Sep 17 00:00:00 2001 From: lenastar Date: Fri, 2 Nov 2018 22:10:49 +0300 Subject: [PATCH 3/9] Changed logic --- robbery.js | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/robbery.js b/robbery.js index 5406e13..15c58c0 100755 --- a/robbery.js +++ b/robbery.js @@ -24,17 +24,15 @@ class Time { } getTimeFromMinutes() { + let hours = Math.floor(this.minutes / 60) + timezone; + let day = hours < 0 ? this.day - 1 : this.day; + return { - day: backToDay[this.day], - hours: Math.floor(this.minutes / 60) + timezone, + day: backToDay[day], + hours: hours < 0 ? 24 + hours : hours, minutes: this.minutes - 60 * Math.floor(this.minutes / 60) }; } - - getDifference(time) { - return Math.abs(this.getMinutes() - time.getMinutes()); - } - } class Section { @@ -43,9 +41,9 @@ class Section { this.to = to; } - isNoIntersection(section) { - return section.to.getMinutes() < this.from.getMinutes() || - section.from.getMinutes() > this.to.getMinutes(); + isIntersection(section) { + return section.to.getMinutes() >= this.from.getMinutes() && + section.from.getMinutes() <= this.to.getMinutes(); } } @@ -81,7 +79,7 @@ function getAppropriateMoment(schedule, duration, workingHours) { Object .keys(schedule) .map(x => schedule[x]) - .forEach(x => x.forEach(y=>_schedule.push(y))); + .forEach(x => x.forEach(y => _schedule.push(y))); let sections = []; for (let i = 0; i < 3; i++) { sections[i] = []; @@ -90,7 +88,8 @@ function getAppropriateMoment(schedule, duration, workingHours) { let from = parseTime(i.from); let to = parseTime(i.to); if (from.day !== to.day) { - sections[from.day].push(new Section(from, new Time(1440, from.day))); + console.info(from.day); + sections[from.day].push(new Section(from, new Time(1439, from.day))); sections[to.day].push(new Section(new Time(0, to.day), to)); } else { sections[from.day].push(new Section(from, to)); @@ -113,8 +112,9 @@ function getAppropriateMoment(schedule, duration, workingHours) { } function formatTime(template, time) { + let minutes = time.minutes < 10 ? '0' + time.minutes : time.minutes; let _template = template.replace(/%HH:%MM/, - `${time.hours}:${time.minutes}`); + `${time.hours}:${minutes}`); _template = _template.replace(/%DD/, time.day); @@ -142,7 +142,7 @@ function findWithSomeIntersections(intersections, day, workingHours, duration) { let _sections = []; for (let n of intersections) { let _from = n[0].from.getMinutes(); - let _to = n[0].to.getMinutes(); + let _to = n[n.length - 1].to.getMinutes();; _sections.push(new Section(_from, _to)); } result = findWithoutIntersection(_sections, day, workingHours, duration); @@ -164,7 +164,7 @@ function findTime(duration, sections, workingHours) { }); for (let j of section) { let intersection = section.filter(x => x === j || - !j.isNoIntersection(x)); + j.isIntersection(x)); intersections.push(intersection); intersections = intersections.filter(x => { return (x === intersection || @@ -190,7 +190,6 @@ function findWithoutIntersection(section, day, workingHours, duration) { let start = whFromTime.getMinutes(); for (let m of section) { if (m.from - start >= duration && m.from < whToTime.getMinutes()) { - console.info('зашли сюда, когда', m.from, start); result = new Time(start, day); break; } @@ -206,9 +205,10 @@ function findWithoutIntersection(section, day, workingHours, duration) { function parseWorkingHours(str) { timezone = parseInt(str.substr(6, 2)); let hours = parseInt(str.substr(0, 2)) - timezone; + let _hours = hours < 0 ? hours + 24 : hours; let minutes = parseInt(str.substr(3, 2)); - return new Time(hoursToMinutes(hours, minutes), 'all'); + return new Time(hoursToMinutes(_hours, minutes), 'all'); } function hoursToMinutes(hours, minutes) { @@ -216,9 +216,17 @@ function hoursToMinutes(hours, minutes) { } function parseTime(str) { - let hours = parseInt(str.substr(3, 2)) - parseInt(str.substr(-1, 2)); + let hours = parseInt(str.substr(3, 2)) - parseInt(str.substr(9, 2)); let minutes = parseInt(str.substr(6, 2)); let day = dayOfWeek[str.substr(0, 2)]; + if (hours < 0) { + if (day - 1 >= 0) { + day -= 1; + hours += 24; + } else { + hours = 0; + } + } return new Time(hoursToMinutes(hours, minutes), day); } From c167b04d17af0fecb6c858fc5c5500d5fc5346c9 Mon Sep 17 00:00:00 2001 From: lenastar Date: Fri, 2 Nov 2018 22:15:28 +0300 Subject: [PATCH 4/9] DElete ; --- robbery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robbery.js b/robbery.js index 15c58c0..9d8f0e1 100755 --- a/robbery.js +++ b/robbery.js @@ -142,7 +142,7 @@ function findWithSomeIntersections(intersections, day, workingHours, duration) { let _sections = []; for (let n of intersections) { let _from = n[0].from.getMinutes(); - let _to = n[n.length - 1].to.getMinutes();; + let _to = n[n.length - 1].to.getMinutes(); _sections.push(new Section(_from, _to)); } result = findWithoutIntersection(_sections, day, workingHours, duration); From d8e38ba822955c986a8470b80a62a8bbd2c14574 Mon Sep 17 00:00:00 2001 From: lenastar Date: Fri, 2 Nov 2018 22:49:53 +0300 Subject: [PATCH 5/9] Added sets --- robbery.js | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/robbery.js b/robbery.js index 9d8f0e1..9d293a3 100755 --- a/robbery.js +++ b/robbery.js @@ -25,13 +25,27 @@ class Time { getTimeFromMinutes() { let hours = Math.floor(this.minutes / 60) + timezone; - let day = hours < 0 ? this.day - 1 : this.day; + let minutes = this.minutes - 60 * Math.floor(this.minutes / 60); + if (hours < 0) { + return { + day: backToDay[this.day - 1], + hours: 24 + hours, + minutes + }; + } else if (hours >= 24) { + return { + day: backToDay[this.day + 1], + hours: 24 - hours, + minutes + }; + } return { - day: backToDay[day], - hours: hours < 0 ? 24 + hours : hours, - minutes: this.minutes - 60 * Math.floor(this.minutes / 60) + day: backToDay[this.day], + hours, + minutes }; + } } @@ -88,7 +102,6 @@ function getAppropriateMoment(schedule, duration, workingHours) { let from = parseTime(i.from); let to = parseTime(i.to); if (from.day !== to.day) { - console.info(from.day); sections[from.day].push(new Section(from, new Time(1439, from.day))); sections[to.day].push(new Section(new Time(0, to.day), to)); } else { @@ -125,8 +138,9 @@ function findWithOneIntersection(intersections, day, workingHours, duration) { let result = null; let whFromTime = parseWorkingHours(workingHours.from); let whToTime = parseWorkingHours(workingHours.to); - let min = intersections[0][0].from.getMinutes(); - let max = intersections[0][intersections.length - 1].to.getMinutes(); + let intersection = Array.from(intersections[0].values()); + let min = intersection[0].from.getMinutes(); + let max = intersection[intersections.length - 1].to.getMinutes(); if (min - whFromTime.getMinutes() >= duration) { result = new Time(whFromTime.getMinutes(), day); } @@ -141,6 +155,7 @@ function findWithSomeIntersections(intersections, day, workingHours, duration) { let result = null; let _sections = []; for (let n of intersections) { + n = Array.from(n); let _from = n[0].from.getMinutes(); let _to = n[n.length - 1].to.getMinutes(); _sections.push(new Section(_from, _to)); @@ -163,13 +178,13 @@ function findTime(duration, sections, workingHours) { return a.from.getMinutes() - b.from.getMinutes(); }); for (let j of section) { - let intersection = section.filter(x => x === j || - j.isIntersection(x)); - intersections.push(intersection); - intersections = intersections.filter(x => { - return (x === intersection || - JSON.stringify(x) !== JSON.stringify(intersection)); + let intersection = new Set(); + section.forEach(x => { + if (j === x || j.isIntersection(x)) { + intersection.add(x); + } }); + intersections.push(intersection); } if (intersections.length === 1) { findWithOneIntersection(intersections, i, workingHours, duration); @@ -190,12 +205,14 @@ function findWithoutIntersection(section, day, workingHours, duration) { let start = whFromTime.getMinutes(); for (let m of section) { if (m.from - start >= duration && m.from < whToTime.getMinutes()) { + console.info(m.from - start); result = new Time(start, day); break; } start = m.to; } if (whToTime.getMinutes() - section[section.length - 1] >= duration) { + console.info(whToTime.getMinutes() - section[section.length - 1]); result = new Time(section[section.length - 1], day); } From a4944cda997932fd328e877ab4e3339ee4000637 Mon Sep 17 00:00:00 2001 From: lenastar Date: Sat, 3 Nov 2018 00:48:09 +0300 Subject: [PATCH 6/9] Changed withoutIntersection --- robbery.js | 145 +++++++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/robbery.js b/robbery.js index 9d293a3..9783ced 100755 --- a/robbery.js +++ b/robbery.js @@ -11,6 +11,9 @@ dayOfWeek['ВТ'] = 1; dayOfWeek['СР'] = 2; const backToDay = ['ПН', 'ВТ', 'СР']; let timezone = 0; +let bankTimeFrom; +let bankTimeTo; +let _duration; class Time { @@ -70,6 +73,9 @@ class Section { * @returns {Object} */ function getAppropriateMoment(schedule, duration, workingHours) { + _duration = duration; + bankTimeFrom = parseWorkingHours(workingHours.from).getMinutes(); + bankTimeTo = parseWorkingHours(workingHours.to).getMinutes(); console.info(schedule, duration, workingHours); return { @@ -108,7 +114,7 @@ function getAppropriateMoment(schedule, duration, workingHours) { sections[from.day].push(new Section(from, to)); } } - let result = findTime(duration, sections, workingHours); + let result = findTime(sections); return result !== null ? formatTime(template, result.getTimeFromMinutes()) : ''; }, @@ -124,101 +130,90 @@ function getAppropriateMoment(schedule, duration, workingHours) { }; } -function formatTime(template, time) { - let minutes = time.minutes < 10 ? '0' + time.minutes : time.minutes; - let _template = template.replace(/%HH:%MM/, - `${time.hours}:${minutes}`); - _template = _template.replace(/%DD/, - time.day); +function findTime(sections) { + let result = null; + sections = sections.map(x=> x.sort((a, b) => { + return a.from.getMinutes() - b.from.getMinutes(); + })); - return _template; + for (let i = 0; i < 3; i++) { + let intersections = []; + let section = sections[i]; + findIntersection(section, intersections); + intersections = intersections.filter(x => x.length !== 0); + if (intersections.length === 1) { + result = findWithOneIntersection(intersections, i); + } else if (intersections.length === 0) { + result = findWithoutIntersection(sections[i], i); + } else { + result = findWithSomeIntersections(intersections, i); + } + if (result) { + return result; + } + } + + return result; +} + +function findIntersection(section, intersections) { + for (let j of section) { + let intersection = new Set(); + section.forEach(x => { + if (x !== j && j.isIntersection(x)) { + intersection.add(x); + } + }); + intersections.push(Array.from(intersection.values())); + } } -function findWithOneIntersection(intersections, day, workingHours, duration) { +function findWithOneIntersection(intersections, day) { let result = null; - let whFromTime = parseWorkingHours(workingHours.from); - let whToTime = parseWorkingHours(workingHours.to); - let intersection = Array.from(intersections[0].values()); - let min = intersection[0].from.getMinutes(); - let max = intersection[intersections.length - 1].to.getMinutes(); - if (min - whFromTime.getMinutes() >= duration) { - result = new Time(whFromTime.getMinutes(), day); + let min = intersections[0][0].from.getMinutes(); + let max = intersections[0][intersections.length - 1].to.getMinutes(); + if (min - bankTimeFrom >= _duration) { + return new Time(bankTimeFrom, day); } - if (whToTime.getMinutes() - max >= duration) { - result = new Time(max, day); + if (bankTimeTo - max >= _duration) { + return new Time(max, day); } return result; } -function findWithSomeIntersections(intersections, day, workingHours, duration) { - let result = null; +function findWithSomeIntersections(intersections, day) { let _sections = []; for (let n of intersections) { - n = Array.from(n); let _from = n[0].from.getMinutes(); let _to = n[n.length - 1].to.getMinutes(); _sections.push(new Section(_from, _to)); } - result = findWithoutIntersection(_sections, day, workingHours, duration); - return result; + return findWithoutIntersection(_sections, day); } -function findTime(duration, sections, workingHours) { +function findWithoutIntersection(section, day) { let result = null; - sections = sections.map(x=> x.sort((a, b) => { - return a.from.getMinutes() - b.from.getMinutes(); - })); - - for (let i = 0; i < 3; i++) { - let intersections = []; - let section = sections[i] - .sort((a, b) => { - return a.from.getMinutes() - b.from.getMinutes(); - }); - for (let j of section) { - let intersection = new Set(); - section.forEach(x => { - if (j === x || j.isIntersection(x)) { - intersection.add(x); - } - }); - intersections.push(intersection); - } - if (intersections.length === 1) { - findWithOneIntersection(intersections, i, workingHours, duration); - } else if (intersections.length === 0) { - result = findWithoutIntersection(intersections, i, workingHours, duration); - } else { - result = findWithSomeIntersections(intersections, i, workingHours, duration); - } - } - - return result; -} - -function findWithoutIntersection(section, day, workingHours, duration) { - let result = null; - let whFromTime = parseWorkingHours(workingHours.from); - let whToTime = parseWorkingHours(workingHours.to); - let start = whFromTime.getMinutes(); + let start = bankTimeFrom; for (let m of section) { - if (m.from - start >= duration && m.from < whToTime.getMinutes()) { - console.info(m.from - start); - result = new Time(start, day); - break; + if (m.from.getMinutes() - start >= _duration && + m.from.getMinutes() < bankTimeTo) { + return new Time(start, day); } - start = m.to; + start = m.to.getMinutes(); } - if (whToTime.getMinutes() - section[section.length - 1] >= duration) { - console.info(whToTime.getMinutes() - section[section.length - 1]); - result = new Time(section[section.length - 1], day); + if (bankTimeTo - section[section.length - 1] >= _duration) { + return new Time(section[section.length - 1], day); } return result; } +function hoursToMinutes(hours, minutes) { + return hours * 60 + minutes; +} + function parseWorkingHours(str) { timezone = parseInt(str.substr(6, 2)); let hours = parseInt(str.substr(0, 2)) - timezone; @@ -228,10 +223,6 @@ function parseWorkingHours(str) { return new Time(hoursToMinutes(_hours, minutes), 'all'); } -function hoursToMinutes(hours, minutes) { - return hours * 60 + minutes; -} - function parseTime(str) { let hours = parseInt(str.substr(3, 2)) - parseInt(str.substr(9, 2)); let minutes = parseInt(str.substr(6, 2)); @@ -248,6 +239,16 @@ function parseTime(str) { return new Time(hoursToMinutes(hours, minutes), day); } +function formatTime(template, time) { + let minutes = time.minutes < 10 ? '0' + time.minutes : time.minutes; + let _template = template.replace(/%HH:%MM/, + `${time.hours}:${minutes}`); + _template = _template.replace(/%DD/, + time.day); + + return _template; +} + module.exports = { getAppropriateMoment, From b2e534558cabfdcf1e42ebf36e530fe744de07c6 Mon Sep 17 00:00:00 2001 From: lenastar Date: Sat, 3 Nov 2018 01:00:50 +0300 Subject: [PATCH 7/9] Last commit today --- robbery.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/robbery.js b/robbery.js index 9783ced..b84e813 100755 --- a/robbery.js +++ b/robbery.js @@ -160,7 +160,7 @@ function findIntersection(section, intersections) { for (let j of section) { let intersection = new Set(); section.forEach(x => { - if (x !== j && j.isIntersection(x)) { + if (x === j || j.isIntersection(x)) { intersection.add(x); } }); @@ -197,11 +197,11 @@ function findWithoutIntersection(section, day) { let result = null; let start = bankTimeFrom; for (let m of section) { - if (m.from.getMinutes() - start >= _duration && - m.from.getMinutes() < bankTimeTo) { + if (m.from - start >= _duration && + m.from < bankTimeTo) { return new Time(start, day); } - start = m.to.getMinutes(); + start = m.to; } if (bankTimeTo - section[section.length - 1] >= _duration) { return new Time(section[section.length - 1], day); From 63bcf52fa8e0b6fbce76c3d2e95277cb51cec795 Mon Sep 17 00:00:00 2001 From: lenastar Date: Sun, 4 Nov 2018 00:38:00 +0300 Subject: [PATCH 8/9] Test all --- robbery.js | 177 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 105 insertions(+), 72 deletions(-) diff --git a/robbery.js b/robbery.js index b84e813..2361a21 100755 --- a/robbery.js +++ b/robbery.js @@ -5,10 +5,11 @@ * Реализовано оба метода и tryLater */ const isStar = false; -const dayOfWeek = []; -dayOfWeek['ПН'] = 0; -dayOfWeek['ВТ'] = 1; -dayOfWeek['СР'] = 2; +const dayOfWeek = new Map(); +dayOfWeek.set('ПН', 0); +dayOfWeek.set('ВТ', 1); +dayOfWeek.set('СР', 2); +dayOfWeek.set('ЧТ', 3); const backToDay = ['ПН', 'ВТ', 'СР']; let timezone = 0; let bankTimeFrom; @@ -64,70 +65,37 @@ class Section { } } -/** - * @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} - */ -function getAppropriateMoment(schedule, duration, workingHours) { - _duration = duration; - bankTimeFrom = parseWorkingHours(workingHours.from).getMinutes(); - bankTimeTo = parseWorkingHours(workingHours.to).getMinutes(); - console.info(schedule, duration, workingHours); - - return { - - /** - * Найдено ли время - * @returns {Boolean} - */ - exists: function () { - return this.format('%DD %HH:%MM') !== ''; - }, +function addToInSections(sections, to) { + sections[to.day].push(new Section(new Time(0, to.day), to)); +} - /** - * Возвращает отформатированную строку с часами для ограбления - * Например, "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)" - * @param {String} template - * @returns {String} - */ - format: function (template) { - let _schedule = []; - Object - .keys(schedule) - .map(x => schedule[x]) - .forEach(x => x.forEach(y => _schedule.push(y))); - let sections = []; - for (let i = 0; i < 3; i++) { - sections[i] = []; - } - for (let i of _schedule) { - let from = parseTime(i.from); - let to = parseTime(i.to); - if (from.day !== to.day) { - sections[from.day].push(new Section(from, new Time(1439, from.day))); - sections[to.day].push(new Section(new Time(0, to.day), to)); - } else { - sections[from.day].push(new Section(from, to)); - } - } - let result = findTime(sections); +function addFromInSections(sections, from) { + sections[from.day].push(new Section(from, new Time(1439, from.day))); +} - return result !== null ? formatTime(template, result.getTimeFromMinutes()) : ''; - }, +function addInSections(sections, from, to) { + if (from && !to) { + addFromInSections(sections, from); + } else if (to && !from) { + addToInSections(sections, to); + } +} - /** - * Попробовать найти часы для ограбления позже [*] - * @star - * @returns {Boolean} - */ - tryLater: function () { - return false; +function makeSectionsFromSchedule(_schedule, sections) { + for (let i of _schedule) { + let from = parseTime(i.from); + let to = parseTime(i.to); + if (!from || !to) { + addInSections(sections, from, to); + continue; } - }; + if (from.day !== to.day) { + addFromInSections(sections, from); + addToInSections(sections, to); + } else { + sections[from.day].push(new Section(from, to)); + } + } } function findTime(sections) { @@ -193,19 +161,27 @@ function findWithSomeIntersections(intersections, day) { return findWithoutIntersection(_sections, day); } +function checkLastSection(section, result, day) { + if (bankTimeTo - section[section.length - 1].to >= _duration) { + result = new Time(section[section.length - 1], day); + } + + return result; +} + function findWithoutIntersection(section, day) { let result = null; let start = bankTimeFrom; for (let m of section) { - if (m.from - start >= _duration && - m.from < bankTimeTo) { + if (m.from < start && m.to <= start) { + continue; + } + if (m.from - start >= _duration && m.from < bankTimeTo) { return new Time(start, day); } start = m.to; } - if (bankTimeTo - section[section.length - 1] >= _duration) { - return new Time(section[section.length - 1], day); - } + result = checkLastSection(section, result, day); return result; } @@ -226,9 +202,9 @@ function parseWorkingHours(str) { function parseTime(str) { let hours = parseInt(str.substr(3, 2)) - parseInt(str.substr(9, 2)); let minutes = parseInt(str.substr(6, 2)); - let day = dayOfWeek[str.substr(0, 2)]; + let day = dayOfWeek.has(str.substr(0, 2)) ? dayOfWeek.get(str.substr(0, 2)) : 3; if (hours < 0) { - if (day - 1 >= 0) { + if (day - 1 >= 0 && day - 1 < 3) { day -= 1; hours += 24; } else { @@ -236,7 +212,7 @@ function parseTime(str) { } } - return new Time(hoursToMinutes(hours, minutes), day); + return day !== 3 ? new Time(hoursToMinutes(hours, minutes), day) : null; } function formatTime(template, time) { @@ -249,6 +225,63 @@ function formatTime(template, time) { return _template; } +/** + * @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} + */ +function getAppropriateMoment(schedule, duration, workingHours) { + _duration = duration; + bankTimeFrom = parseWorkingHours(workingHours.from).getMinutes(); + bankTimeTo = parseWorkingHours(workingHours.to).getMinutes(); + console.info(schedule, duration, workingHours); + + return { + + /** + * Найдено ли время + * @returns {Boolean} + */ + exists: function () { + return this.format('%DD %HH:%MM') !== ''; + }, + + /** + * Возвращает отформатированную строку с часами для ограбления + * Например, "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)" + * @param {String} template + * @returns {String} + */ + format: function (template) { + let _schedule = []; + Object + .keys(schedule) + .map(x => schedule[x]) + .forEach(x => x.forEach(y => _schedule.push(y))); + let sections = []; + for (let i = 0; i < 3; i++) { + sections[i] = []; + } + makeSectionsFromSchedule(_schedule, sections); + let result = findTime(sections); + + return result ? formatTime(template, result.getTimeFromMinutes()) : ''; + }, + + /** + * Попробовать найти часы для ограбления позже [*] + * @star + * @returns {Boolean} + */ + tryLater: function () { + return false; + } + }; +} + module.exports = { getAppropriateMoment, From 8168c3bd050e20c62c1d2394f459c5ecd7a9f8c0 Mon Sep 17 00:00:00 2001 From: lenastar Date: Sun, 4 Nov 2018 00:57:20 +0300 Subject: [PATCH 9/9] Fixed findTime --- robbery.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/robbery.js b/robbery.js index 2361a21..89398dd 100755 --- a/robbery.js +++ b/robbery.js @@ -103,8 +103,7 @@ function findTime(sections) { sections = sections.map(x=> x.sort((a, b) => { return a.from.getMinutes() - b.from.getMinutes(); })); - - for (let i = 0; i < 3; i++) { + for (let i = 0; i < sections.length; i++) { let intersections = []; let section = sections[i]; findIntersection(section, intersections); @@ -112,7 +111,7 @@ function findTime(sections) { if (intersections.length === 1) { result = findWithOneIntersection(intersections, i); } else if (intersections.length === 0) { - result = findWithoutIntersection(sections[i], i); + result = findWithoutIntersection(section, i); } else { result = findWithSomeIntersections(intersections, i); } @@ -266,7 +265,7 @@ function getAppropriateMoment(schedule, duration, workingHours) { sections[i] = []; } makeSectionsFromSchedule(_schedule, sections); - let result = findTime(sections); + let result = findTime(sections.filter(x => x.length !== 0)); return result ? formatTime(template, result.getTimeFromMinutes()) : ''; },