-
Notifications
You must be signed in to change notification settings - Fork 76
Кошара Павел #4
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
Кошара Павел #4
Changes from all commits
5ad0da0
b07ebf2
1ab07b7
798e94d
42cd467
244ed59
cf94374
2cb3a42
0c4bc71
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 |
|---|---|---|
|
|
@@ -6,6 +6,101 @@ | |
| */ | ||
| exports.isStar = true; | ||
|
|
||
| var DAYS = ['ПН', 'ВТ', 'СР']; | ||
|
|
||
| function dateToTimestamp(date) { | ||
| var isoDate = date; | ||
| DAYS.forEach(function (day, i) { | ||
| isoDate = isoDate.replace(day, i + 1); | ||
| }); | ||
|
|
||
| /* Будем считать, что понедельник - 1 января 1970 года. | ||
| соответственно банк меняет сигнализацию 4 января 1970 года. */ | ||
| isoDate = isoDate.replace(/^(\d) (\d{2}:\d{2})(\+\d+)$/, '1 $1 1970 $2 UTC$3'); | ||
|
|
||
| return Date.parse(isoDate); | ||
| } | ||
|
|
||
| function getTimezone(time) { | ||
| var match = /^\d{2}:\d{2}\+(\d+)$/.exec(time); | ||
|
|
||
| return match && Number(match[1]); | ||
| } | ||
|
|
||
| function toTimestampInterval(interval) { | ||
| return { | ||
| from: dateToTimestamp(interval.from), | ||
| to: dateToTimestamp(interval.to) | ||
| }; | ||
| } | ||
|
|
||
| function getBusyIntervals(schedule) { | ||
| return Object.keys(schedule).reduce(function (busyIntervals, thugName) { | ||
| return busyIntervals.concat( | ||
| schedule[thugName].map(toTimestampInterval) | ||
| ); | ||
| }, []); | ||
| } | ||
|
|
||
| function getWorkingDays(workingHours) { | ||
| return DAYS.map(function (day) { | ||
| var from = day + ' ' + workingHours.from; | ||
| var to = day + ' ' + workingHours.to; | ||
|
|
||
| return { | ||
| from: dateToTimestamp(from), | ||
| to: dateToTimestamp(to) | ||
| }; | ||
| }); | ||
| } | ||
|
|
||
| function invertBusyIntervals(busyIntervals, weekStart, deadline) { | ||
| var sortedBusyIntervals = busyIntervals.slice().sort(function (one, another) { | ||
| return one.from - another.from; | ||
| }); | ||
| var spareIntervals = []; | ||
| var current = weekStart; | ||
| sortedBusyIntervals.forEach(function (interval) { | ||
| if (current < interval.from) { | ||
| spareIntervals.push({ | ||
| from: current, | ||
| to: interval.from | ||
| }); | ||
| } | ||
| current = Math.max(interval.to, current); | ||
| }); | ||
| if (current < deadline) { | ||
| spareIntervals.push({ | ||
| from: current, | ||
| to: deadline | ||
| }); | ||
| } | ||
|
|
||
| return spareIntervals; | ||
| } | ||
|
|
||
| function getRobberyIntervals(spareIntervals, workingDays, durationInMilliseconds) { | ||
| var robberyIntervals = []; | ||
| spareIntervals.forEach(function (interval) { | ||
| workingDays.forEach(function (day) { | ||
| var attemptTo = Math.min(day.to, interval.to); | ||
| var attemptFrom = Math.max(day.from, interval.from); | ||
| if (attemptTo - attemptFrom >= durationInMilliseconds) { | ||
| robberyIntervals.push({ | ||
| from: attemptFrom, | ||
| to: attemptTo | ||
| }); | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| return robberyIntervals; | ||
| } | ||
|
|
||
| function twoDigitsFormat(number) { | ||
| return number.toLocaleString(undefined, { 'minimumIntegerDigits': 2 }); | ||
| } | ||
|
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. но ты его кроме как с двойкой не используешь, поэтому можно переименовать в |
||
|
|
||
| /** | ||
| * @param {Object} schedule – Расписание Банды | ||
| * @param {Number} duration - Время на ограбление в минутах | ||
|
|
@@ -15,7 +110,21 @@ exports.isStar = true; | |
| * @returns {Object} | ||
| */ | ||
| exports.getAppropriateMoment = function (schedule, duration, workingHours) { | ||
| console.info(schedule, duration, workingHours); | ||
| var bankTimezone = getTimezone(workingHours.from); | ||
| var weekStart = dateToTimestamp('ПН 00:00+' + bankTimezone); | ||
| var deadline = dateToTimestamp('СР 23:59+' + bankTimezone); | ||
|
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. пока просто мысли вслух: у тебя есть хеплер
Author
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. Это и padNumberLeft: да, в кодстайле сказано не писать лишние вещи. Но курс ООП научил нас такой штуке как "переиспользование кода".
Author
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 busyIntervals = getBusyIntervals(schedule); | ||
| var spareIntervals = invertBusyIntervals(busyIntervals, weekStart, deadline); | ||
|
|
||
| var durationInMilliseconds = duration * 60 * 1000; | ||
| var workingDays = getWorkingDays(workingHours); | ||
| var robberyIntervals = getRobberyIntervals( | ||
| spareIntervals, | ||
| workingDays, | ||
| durationInMilliseconds | ||
| ); | ||
| var currentRobberyIndex = 0; | ||
|
|
||
| return { | ||
|
|
||
|
|
@@ -24,7 +133,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { | |
| * @returns {Boolean} | ||
| */ | ||
| exists: function () { | ||
| return false; | ||
| return robberyIntervals.length > 0; | ||
| }, | ||
|
|
||
| /** | ||
|
|
@@ -35,7 +144,23 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { | |
| * @returns {String} | ||
| */ | ||
| format: function (template) { | ||
| return template; | ||
| if (!this.exists()) { | ||
|
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 robbery = robberyIntervals[0];
if (!robbery) {
return '';
}
// ... |
||
| return ''; | ||
| } | ||
|
|
||
| var hourInMilliseconds = 60 * 60 * 1000; | ||
| var date = new Date( | ||
| robberyIntervals[currentRobberyIndex].from + | ||
| bankTimezone * hourInMilliseconds | ||
| ); | ||
| var minutes = twoDigitsFormat(date.getUTCMinutes()); | ||
| var hours = twoDigitsFormat(date.getUTCHours()); | ||
| var day = DAYS[date.getUTCDate() - 1]; | ||
|
|
||
| return template | ||
| .replace('%HH', hours) | ||
| .replace('%MM', minutes) | ||
| .replace('%DD', day); | ||
| }, | ||
|
|
||
| /** | ||
|
|
@@ -44,6 +169,29 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) { | |
| * @returns {Boolean} | ||
| */ | ||
| tryLater: function () { | ||
| if (!this.exists()) { | ||
| return false; | ||
| } | ||
|
|
||
| var halfHourInMilliseconds = 30 * 60 * 1000; | ||
| var i = currentRobberyIndex; | ||
| var delayedRobberyStart = robberyIntervals[i].from + halfHourInMilliseconds; | ||
| while (i < robberyIntervals.length && robberyIntervals[i].from < delayedRobberyStart) { | ||
| if (robberyIntervals[i].to - delayedRobberyStart >= durationInMilliseconds) { | ||
| robberyIntervals[i].from = delayedRobberyStart; | ||
| currentRobberyIndex = i; | ||
|
|
||
| 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. нет, не согласен. По первой части: ты пробуешь попробовать ограбить в тот же интервал с задержкой, но оставляешь сайдэффект, о котором никто в задаче не просит - правишь По второй части: ты снова изменяешь
Author
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. 2- Это не ответ - 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. уточню -
Author
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. да, видимо тесты не покрывают |
||
| i++; | ||
| } | ||
|
|
||
| if (i < robberyIntervals.length) { | ||
| currentRobberyIndex = i; | ||
|
|
||
| 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. Как-то сложно получилось, и, главное, кажется с логикой проблемы. Чего мы хотим? Нам нужно:
Мне кажется, не надо два кейса мешать в один. Лучше написать так: var i = 0;
// 1ый кейс
while (i < robberyIntervals.length && robberyIntervals[i].from < delayedRobberyStart) {
if (robberyIntervals[i].to - delayedRobberyStart >= durationInMilliseconds) {
robberyIntervals[i].from = delayedRobberyStart;
robberyIntervals = robberyIntervals.slice(i);
return true;
}
i++;
}
// 2ой кейс
if (i < robberyIntervals.length) {
robberyIntervals = robberyIntervals.slice(i);
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. так, а чего мы slice не сделали? типа:
Author
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. мм, понял тебя. Только не понятно, как это согласуется с работой метода но это уже придирки, с задачей ты разобрался
Author
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. Тогда можно закрыть, наверное?)
Author
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. И ничего не сломается, т.к. currentRobberyIndex в exists не используется
Author
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. Точнее, robberyIndex не превысит длину robberyIntervals(если robberyIntervals не пуст) 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 (!this.exists()) { // не посмотрели на currentRobberyIndex, а он, может быть, уже больше длины
return '';
}
var hourInMilliseconds = 60 * 60 * 1000;
var date = new Date(
robberyIntervals[currentRobberyIndex].from + // бдыжь, бах, бум! все взорволось, undefined is not an object
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.
это другой разговор:)
Author
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. Что-то я запутался. Если currentRobberyIndex равен 0 и exists вернет true, то нулевой элемент в robberyIntervals есть. Если currentRobberyIndex больше 0, то смотрим где он меняется: В обоих случаях присвоение произойдет только тогда, когда присваимое значение(i) меньше длины robberyIntervals, то есть если exists вернет true, то robberyInterval[currentRobberyInterval] != undefined. 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 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.
можно еще так:
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.
Мне кажется, что Ваш вариант медленнее
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.
Ваш - твой, пожалуйста) Согласен, насколько медленнее? Из явных плюсов - в моем варианте семантика кода ближе к задаче - код написан ровно так как от него требуется
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.
из минусов - при добавлении нового дня придется и регулярку менять вместе с массивом дат
про скорость я пожалуй возьму свои слова назад, уже не так уверен
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.
да, регвыр придется синхронизировать - убедил, тут больше не пристаю