Skip to content
Open
Show file tree
Hide file tree
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
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// Используйте IntelliSense, чтобы узнать о возможных атрибутах.
// Наведите указатель мыши, чтобы просмотреть описания существующих атрибутов.
// Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [

{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}\\index.js"
}
]
}
198 changes: 195 additions & 3 deletions robbery.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,26 @@
* Сделано задание на звездочку
* Реализовано оба метода и tryLater
*/
exports.isStar = true;
exports.isStar = false;
var codeOfWeekDay = {
'ПН': 0,
'ВТ': 1,
'СР': 2,
'ЧТ': 3,
'ПТ': 4,
'СБ': 5,
'ВС': 6
};

var weekDay = {
0: 'ПН',
1: 'ВТ',
2: 'СР',
3: 'ЧТ',
4: 'ПТ',
5: 'СБ',
6: 'ВС'
};

/**
* @param {Object} schedule – Расписание Банды
Expand All @@ -15,7 +34,19 @@ exports.isStar = true;
* @returns {Object}
*/
exports.getAppropriateMoment = function (schedule, duration, workingHours) {
console.info(schedule, duration, workingHours);
var scheduleOfBankFrom = getTimeObject(workingHours.from);
var scheduleOfBankTo = getTimeObject(workingHours.to);
var timeZone = scheduleOfBankFrom.timeZone;
var entries = getAllEntries(schedule);
var intervalsInMinutes = entries
.map(entry => toIntervalInMinutes(entry, timeZone))
.sort((firstTime, secondTime) => firstTime.intervalStart > secondTime.intervalStart);
var combinedIntervalsInMinutes = combineIntervals(intervalsInMinutes);
var freeIntervals = getFreeIntervals(combinedIntervalsInMinutes);
var workIntervals = getWorkIntervals(scheduleOfBankFrom, scheduleOfBankTo);
var suitableIntervals = getSuitableIntervals(freeIntervals, workIntervals)
.filter(entry => entry.duration >= duration);
var currentSuitableInterval = suitableIntervals[0];

return {

Expand All @@ -24,6 +55,10 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) {
* @returns {Boolean}
*/
exists: function () {
if (suitableIntervals.length !== 0) {
return true;
}

return false;
},

Expand All @@ -35,7 +70,19 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) {
* @returns {String}
*/
format: function (template) {
return template;
if (suitableIntervals.length === 0) {
return '';
}
let startTimeInMinutes = currentSuitableInterval.start;
let minutes = startTimeInMinutes % 60;
let totalHours = Math.floor(startTimeInMinutes / 60);
let day = Math.floor(totalHours / 24);
let hours = totalHours % 24;

return template
.replace('%HH', hours > 9 ? hours : `0${hours}`)
.replace('%MM', minutes > 9 ? minutes : `0${hours}`)
.replace('%DD', weekDay[day]);
},

/**
Expand All @@ -48,3 +95,148 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) {
}
};
};

function getAllEntries(schedule) {
let robberNames = Object.keys(schedule);
var allEntries = [];
for (let robberName of robberNames) {
var entries = schedule[robberName].map(x => {
let [fromDay, fromTimeSting] = x.from.split(' ');
let [toDay, toTimeString] = x.to.split(' ');

let from = getTimeObject(fromTimeSting);
let to = getTimeObject(toTimeString);

return {
fromDay,
toDay,
from,
to
};
});
allEntries = allEntries.concat(entries);
}

return allEntries;
}

function getTimeObject(time) {
let [hours, minutes, timeZone] = time.split(/:|\+/);
let scheduleOfBank = {};
scheduleOfBank.hours = Number(hours);
scheduleOfBank.minutes = Number(minutes);
scheduleOfBank.timeZone = Number(timeZone);

return scheduleOfBank;
}

function toIntervalInMinutes(entry, timeZone) {
let timeZoneDifference = timeZone - entry.from.timeZone;
entry.from.hours += timeZoneDifference;
entry.to.hours += timeZoneDifference;

return {
intervalStart: getEntryToMinutes(entry.from, entry.fromDay),
intervalEnd: getEntryToMinutes(entry.to, entry.toDay)
};

}

function getEntryToMinutes(time, day) {
let codeDay = codeOfWeekDay[day];

return codeDay * 24 * 60 + time.hours * 60 + time.minutes;
}

function combineIntervals(intervalsInMinutes) {
let combinedIntervalsInMinutes = [];
let currentInterval = intervalsInMinutes[0];
let start = currentInterval.intervalStart;
let end = currentInterval.intervalEnd;
for (let i = 1; i < intervalsInMinutes.length; i++) {
currentInterval = intervalsInMinutes[i];
if (end >= currentInterval.intervalEnd) {
continue;
}
if (end >= currentInterval.intervalStart) {
end = currentInterval.intervalEnd;
} else {
combinedIntervalsInMinutes.push({ start, end });

start = currentInterval.intervalStart;
end = currentInterval.intervalEnd;
}
}
combinedIntervalsInMinutes.push({ start, end });

return combinedIntervalsInMinutes;
}

function getFreeIntervals(combinedIntervalsInMinutes) {
let rightTimeLimit = 2 * 24 * 60 + 23 * 60 + 59;
let start = 0;
let end = 0;
let freeIntervals = [];
let rightIntervals = combinedIntervalsInMinutes.filter(x => x.start < rightTimeLimit)
.map(x => {
if (x.end > rightTimeLimit) {
x.end = rightTimeLimit;
}

return x;
});
for (let interval of rightIntervals) {
end = interval.start;
freeIntervals.push({ start, end });
start = interval.end;
}
if (start !== rightTimeLimit) {
freeIntervals.push({ start, end: rightTimeLimit });
}

return freeIntervals;
}

function getWorkIntervals(scheduleOfBankFrom, scheduleOfBankTo) {
let workIntervals = [];
var days = ['ПН', 'ВТ', 'СР'];
for (let day of days) {
var start = getEntryToMinutes(scheduleOfBankFrom, day);
var end = getEntryToMinutes(scheduleOfBankTo, day);
workIntervals.push({ start, end });
}

return workIntervals;
}

function getSuitableIntervals(freeIntervals, workIntervals) {
let result = [];
for (let workInterval of workIntervals) {
let workStart = workInterval.start;
let workEnd = workInterval.end;

let intervals = freeIntervals.filter(x =>
(workStart < x.end && workStart >= x.start) ||
(workEnd > x.start && workEnd <= x.end) ||
(workStart <= x.start && workEnd >= x.end))
.map(x => {
let start = x.start;
let end = x.end;
if (start < workStart) {
start = workStart;
}
if (end > workEnd) {
end = workEnd;
}

return {
start,
end,
duration: end - start
};
});
result = result.concat(intervals);
}

return result;
}