-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Левшин Михаил #18
base: master
Are you sure you want to change the base?
Левшин Михаил #18
Changes from 7 commits
4aab65b
82eda4e
c5e2d5a
d9b1f95
ba94dab
ad30429
73a3ba5
652f8e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,192 @@ | ||
'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 DAYS_INDEXES = { 'ПН': 0, 'ВТ': 1, 'СР': 2, 'ЧТ': 3, 'ПТ': 4, 'СБ': 5, 'ВС': 6 }; | ||
var DAYS_NAMES = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС']; | ||
var MINUTES_IN_HOUR = 60; | ||
var HOURS_IN_DAY = 24; | ||
var MINUTES_IN_DAY = HOURS_IN_DAY * MINUTES_IN_HOUR; | ||
var MINUTES_TO_START_LATER = 30; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Почему удалил доки? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. мешает There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Но они же несут полезную информацию! |
||
var DAYS_TO_HACK = 3; | ||
|
||
|
||
function TimeInterval(start, end) { | ||
this.start = start; | ||
this.end = end; | ||
|
||
this.getLength = function () { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return this.end - this.start; | ||
}; | ||
|
||
this.getNextDay = function () { | ||
return new TimeInterval(this.start + MINUTES_IN_DAY, this.end + MINUTES_IN_DAY); | ||
}; | ||
|
||
this.isTimeInInterval = function (time) { | ||
return this.start <= time && time <= this.end; | ||
}; | ||
} | ||
|
||
function isTimeInIntervals(timeIntervalsArray, time) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Название читаю, а понять что она делает не могу |
||
for (var i = 0; i < timeIntervalsArray.length; i++) { | ||
if (timeIntervalsArray[i].isTimeInInterval(time)) { | ||
return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а зачем тут отступ перед return?) |
||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
function strDateToDateObj(strDate) { | ||
var strDateCopy = strDate.slice(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Зачем это нужно? |
||
if (DAYS_INDEXES[strDateCopy.slice(0, 2)] === undefined) { | ||
strDateCopy = 'ПН ' + strDateCopy; | ||
} | ||
var o = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Что это за название такое?) |
||
day: DAYS_INDEXES[strDateCopy.slice(0, 2)], | ||
timezone: parseInt(strDateCopy.slice(9, strDateCopy.length), 10), | ||
hours: parseInt(strDateCopy.slice(3, 5), 10), | ||
minutes: parseInt(strDateCopy.slice(6, 8), 10) | ||
}; | ||
o.intValue = o.day * MINUTES_IN_DAY + (o.hours - o.timezone) * MINUTES_IN_HOUR + o.minutes; | ||
|
||
return o; | ||
} | ||
|
||
function getGangsterNames(schedule) { | ||
var gangsterNames = []; | ||
for (var gangsterName in schedule) { | ||
if (schedule.hasOwnProperty(gangsterName)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Попробуй написать это как-то по-другому. Попроще :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ну если честно я не знаю как. https://learn.javascript.ru/object-for-in смотрел тут. hasOwnProperty для lint'a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
gangsterNames.push(gangsterName); | ||
} | ||
} | ||
|
||
return gangsterNames; | ||
} | ||
|
||
function createTimeIntervalWithShift(time, shift) { | ||
return new TimeInterval(strDateToDateObj(time.from).intValue + shift, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это нечитаемый однострочник, нужно вынести аргументы TimeIntreval в читаемые переменные |
||
strDateToDateObj(time.to).intValue + shift); | ||
} | ||
|
||
function simplifyTimesIntervals(timeIntervals, duration) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Название функции переводится как «Упростить временные интервалы». Я честно не понимаю что тут подразумевается |
||
var newTimeIntervals = []; | ||
timeIntervals.forEach(function (timeInterval) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Для фильтрации массивов придумали специальную функцию https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/filter |
||
if (timeInterval.getLength() >= duration) { | ||
newTimeIntervals.push(timeInterval); | ||
} | ||
}); | ||
|
||
return newTimeIntervals; | ||
} | ||
|
||
function addOrChangeLastTimeInterval(arrayIntervals, timeToStartNewInterval) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Из названия функции абсолютно не понятно что она делает. И по коду я тоже ничего не понял |
||
if (arrayIntervals.length === 0 || | ||
arrayIntervals[arrayIntervals.length - 1].end !== timeToStartNewInterval - 1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. В этой функции слишком часто используется |
||
arrayIntervals.push(new TimeInterval(timeToStartNewInterval, timeToStartNewInterval)); | ||
} else { | ||
arrayIntervals[arrayIntervals.length - 1].end += 1; | ||
} | ||
} | ||
|
||
function isGangstersNotBusy(schedule, gangsterNames, time) { | ||
var gangstersIsNotBusy = true; | ||
gangsterNames.forEach(function (gangster) { | ||
if (isTimeInIntervals(schedule[gangster], time)) { | ||
gangstersIsNotBusy = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Можно написать здесь There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. К сожалению из forEach нельзя ничего возвращать( |
||
} | ||
}); | ||
|
||
return gangstersIsNotBusy; | ||
} | ||
|
||
function getGoodTimeIntervals(schedule, gangsterNames) { | ||
var goodTimesIntervals = []; | ||
|
||
for (var i = 0; i < DAYS_TO_HACK * MINUTES_IN_DAY; i++) { | ||
if (!isTimeInIntervals(schedule.Bank, i)) { | ||
continue; | ||
} | ||
if (isGangstersNotBusy(schedule, gangsterNames, i)) { | ||
addOrChangeLastTimeInterval(goodTimesIntervals, i); | ||
} | ||
} | ||
|
||
return goodTimesIntervals; | ||
} | ||
|
||
function createGangsterScheduleWithTimeIntervals(schedule, gangsterNames, bankShift) { | ||
var newSchedule = {}; | ||
|
||
gangsterNames.forEach(function (gangsterName) { | ||
newSchedule[gangsterName] = []; | ||
schedule[gangsterName].forEach(function (time) { | ||
var intervalWithShift = createTimeIntervalWithShift(time, bankShift); | ||
intervalWithShift.start++; | ||
intervalWithShift.end--; | ||
newSchedule[gangsterName].push(intervalWithShift); | ||
}); | ||
}); | ||
|
||
return newSchedule; | ||
} | ||
|
||
function addToScheduleBankTimeIntervals(schedule, bankWorkingHours, bankShift) { | ||
schedule.Bank = [createTimeIntervalWithShift(bankWorkingHours, bankShift)]; | ||
for (var dayIndex = 0; dayIndex < DAYS_TO_HACK - 1; dayIndex++) { | ||
schedule.Bank.push(schedule.Bank[schedule.Bank.length - 1].getNextDay()); | ||
} | ||
} | ||
|
||
function createScheduleWithTimeIntervals(bankWorkingHours, schedule, gangsterNames) { | ||
var bankShift = strDateToDateObj(bankWorkingHours.from).timezone * MINUTES_IN_HOUR; | ||
var newSchedule = createGangsterScheduleWithTimeIntervals(schedule, gangsterNames, bankShift); | ||
addToScheduleBankTimeIntervals(newSchedule, bankWorkingHours, bankShift); | ||
|
||
return newSchedule; | ||
} | ||
|
||
function timeToString(time) { | ||
return time < 10 ? '0' + time.toString() : time.toString(); | ||
} | ||
|
||
exports.getAppropriateMoment = function (schedule, duration, workingHours) { | ||
console.info(schedule, duration, workingHours); | ||
var gangsterNames = getGangsterNames(schedule); | ||
var newSchedule = createScheduleWithTimeIntervals(workingHours, schedule, gangsterNames); | ||
var goodTimesIntervals = getGoodTimeIntervals(newSchedule, gangsterNames); | ||
var goodTimesIntervalsWithGoodDuration = simplifyTimesIntervals(goodTimesIntervals, duration); | ||
|
||
return { | ||
|
||
/** | ||
* Найдено ли время | ||
* @returns {Boolean} | ||
*/ | ||
exists: function () { | ||
return false; | ||
return goodTimesIntervalsWithGoodDuration.length !== 0; | ||
}, | ||
|
||
/** | ||
* Возвращает отформатированную строку с часами для ограбления | ||
* Например, | ||
* "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)" | ||
* @param {String} template | ||
* @returns {String} | ||
*/ | ||
format: function (template) { | ||
return template; | ||
if (!this.exists()) { | ||
return ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Кажется, тут лишний перенос строки |
||
} | ||
|
||
var startInterval = goodTimesIntervalsWithGoodDuration[0]; | ||
var day = parseInt(startInterval.start / (MINUTES_IN_DAY), 10); | ||
var hour = parseInt(startInterval.start / MINUTES_IN_HOUR, 10) - day * HOURS_IN_DAY; | ||
var minutes = startInterval.start % MINUTES_IN_HOUR; | ||
|
||
return template.replace('%DD', DAYS_NAMES[day]).replace('%HH', timeToString(hour)) | ||
.replace('%MM', timeToString(minutes)); | ||
}, | ||
|
||
/** | ||
* Попробовать найти часы для ограбления позже [*] | ||
* @star | ||
* @returns {Boolean} | ||
*/ | ||
tryLater: function () { | ||
var startInterval = goodTimesIntervalsWithGoodDuration[0]; | ||
if (this.exists() && (goodTimesIntervalsWithGoodDuration.length > 1 || | ||
startInterval.getLength() >= duration + MINUTES_TO_START_LATER)) { | ||
startInterval.start += MINUTES_TO_START_LATER; | ||
goodTimesIntervalsWithGoodDuration = simplifyTimesIntervals( | ||
goodTimesIntervalsWithGoodDuration, duration); | ||
|
||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Это ключи предыдущего объекта