Skip to content
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

Грехов Кирилл #56

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 132 additions & 33 deletions robbery.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,147 @@
'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}
*/
exports.isStar = false;

var DAYS = ['ПН', 'ВТ', 'СР'];
var BANK_TIME_ZONE;

function getBankSchedule(workingHours) {
var bankSchedule = [];
for (var i = 0; i < DAYS.length; i++) {
var from = convertToDate(DAYS[i] + ' ' + workingHours.from);
var to = convertToDate(DAYS[i] + ' ' + workingHours.to);
bankSchedule.push({ from: from, to: to });
}

return bankSchedule;
}

function convertToDate(stringDate) {
var days = { 'ПН': 1, 'ВТ': 2, 'СР': 3, 'ЧТ': 4, 'ПТ': 5, 'СБ': 6, 'ВС': 7 };
var re = /^([А-Я]{2}) (\d{2}):(\d{2})(\+\d+)$/;
var parseDate = stringDate.match(re);
var date = new Date(Date.UTC(0, 0, days[parseDate[1]],
parseInt(parseDate[2]) - parseInt(parseDate[4]),
parseInt(parseDate[3])));

return date;
}

function getCompanionsSchedule(schedule) {
var companionsSchedule = {};
var names = Object.keys(schedule);
for (var i = 0; i < names.length; i++) {
var name = names[i];
companionsSchedule[name] = [];
for (var j = 0; j < schedule[name].length; j++) {
var from = convertToDate(schedule[name][j].from);
var to = convertToDate(schedule[name][j].to);
companionsSchedule[name].push({ from: from, to: to });
}
}

return companionsSchedule;
}

function findFreeTimeSchedule(bankSchedule, companionsSchedule) {
var freeTimeSchedule = bankSchedule.slice();
var names = Object.keys(companionsSchedule);
for (var i = 0; i < names.length; i++) {
var newFreeTimes = [];
for (var j = 0; j < freeTimeSchedule.length; j++) {
newFreeTimes = newFreeTimes.concat(
getNotIntersectedTime(freeTimeSchedule[j], companionsSchedule[names[i]])
);
}
freeTimeSchedule = newFreeTimes;
}

return freeTimeSchedule;
}

function getNotIntersectedTime(freeTime, busyTimes) {
var notIntersectedTime = [];
var freeTimeIsNotIntersected = true;
for (var j = 0; j < busyTimes.length; j++) {
if (isTimeInInterval(busyTimes[j].from, freeTime)) {
notIntersectedTime.push({ from: freeTime.from, to: busyTimes[j].from });
freeTimeIsNotIntersected = false;
}
if (isTimeInInterval(busyTimes[j].to, freeTime)) {
notIntersectedTime.push({ from: busyTimes[j].to, to: freeTime.to });
freeTimeIsNotIntersected = false;
}
if (isIntervalInInterval(freeTime, busyTimes[j])) {
freeTimeIsNotIntersected = false;
}
}
if (freeTimeIsNotIntersected) {
notIntersectedTime.push(freeTime);
}

return notIntersectedTime;
}

function isTimeInInterval(time, interval) {
return interval.from.getTime() <= time.getTime() && time.getTime() <= interval.to.getTime();
}

function isIntervalInInterval(verifiableInterval, interval) {
return (interval.from.getTime() <= verifiableInterval.from.getTime() &&
verifiableInterval.to.getTime() <= interval.to.getTime());
}

function findTimeForRobbery(freeTimeSchedule, duration) {
var timeForRobbery = null;
for (var i = 0; i < freeTimeSchedule.length; i++) {
var minutes = (freeTimeSchedule[i].to.getTime() - freeTimeSchedule[i].from.getTime()) /
60000;
if (minutes >= duration) {
timeForRobbery = freeTimeSchedule[i];
break;
}
}

return timeForRobbery;
}

exports.getAppropriateMoment = function (schedule, duration, workingHours) {
console.info(schedule, duration, workingHours);
BANK_TIME_ZONE = parseInt(workingHours.from.split('+')[1]);
var bankSchedule = getBankSchedule(workingHours);
var companionsSchedule = getCompanionsSchedule(schedule);
var freeTimeSchedule = findFreeTimeSchedule(bankSchedule, companionsSchedule);
var timeForRobbery = findTimeForRobbery(freeTimeSchedule, duration);

return {

/**
* Найдено ли время
* @returns {Boolean}
*/
exists: function () {
return false;
return timeForRobbery !== null;
},

/**
* Возвращает отформатированную строку с часами для ограбления
* Например,
* "Начинаем в %HH:%MM (%DD)" -> "Начинаем в 14:59 (СР)"
* @param {String} template
* @returns {String}
*/
format: function (template) {
return template;
if (timeForRobbery) {
timeForRobbery.from.setUTCHours(
timeForRobbery.from.getUTCHours() + BANK_TIME_ZONE
);
var day = DAYS[timeForRobbery.from.getUTCDay() - 1];
var hours = timeForRobbery.from.getUTCHours().toString();
if (hours.length === 1) {
hours = '0' + hours;
}
var minutes = timeForRobbery.from.getUTCMinutes().toString();
if (minutes.length === 1) {
minutes = '0' + minutes;
}

return template
.replace('%DD', day)
.replace('%HH', hours)
.replace('%MM', minutes);
}

return '';
},

/**
* Попробовать найти часы для ограбления позже [*]
* @star
* @returns {Boolean}
*/
tryLater: function () {
return false;
}
Expand Down