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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"main": "robbery.js",
"private": true,
"scripts": {
"lint": "eslint .",
"test": "npm run lint && mocha *.spec.js --exit"
Expand Down
138 changes: 136 additions & 2 deletions robbery.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,88 @@
*/
const isStar = true;

const MINUTES_IN_HOUR = 60;
const MINUTES_IN_DAY = 24 * MINUTES_IN_HOUR;
const DAYS = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС'];

let bankTimeZone = 0;
let startWorkBank = 0;
let endWorkBank = 0;
let freeTimeIntervalsFrom = [];
let freeTimeIntervalsTo = [];
let rightTimeStart = [];
let rightTimeEnd = [];
let timeNumber = 0;

function splitTime(time) {
const parsingTime = time.split(/ |:|\+/);
const day = DAYS.indexOf(parsingTime[0]);
const timeInMinutes = parsingTime[1] * MINUTES_IN_HOUR +
Number(parsingTime[2]) + Number(day * MINUTES_IN_DAY) +
Number(MINUTES_IN_HOUR * (bankTimeZone - parsingTime[3]));

return timeInMinutes;
}

function bankTimeInMinutes(workingHours) {
const workingHoursFrom = workingHours.from.split(/:|\+/);
const workingHoursTo = workingHours.to.split(/:|\+/);

bankTimeZone = workingHoursFrom[2];
startWorkBank = workingHoursFrom[0] * MINUTES_IN_HOUR + Number(workingHoursFrom[1]);
endWorkBank = workingHoursTo[0] * MINUTES_IN_HOUR + Number(workingHoursTo[1]);
}

function sortTime(firstTime, secondTime) {
return firstTime - secondTime;
}

function checkInterval(duration) {
for (let i = 0; i < freeTimeIntervalsFrom.length; i++) {
if (freeTimeIntervalsTo[i] - freeTimeIntervalsFrom[i] >= duration) {
rightTimeStart.push(freeTimeIntervalsFrom[i]);
rightTimeEnd.push(freeTimeIntervalsTo[i]);
}
}

rightTimeStart.sort(sortTime);
rightTimeEnd.sort(sortTime);
}

function confluence(robberyTimeFrom, robberyTimeTo, i) {
if (robberyTimeTo >= freeTimeIntervalsTo[i] || robberyTimeTo <= freeTimeIntervalsFrom[i]) {
freeTimeIntervalsFrom[i] = freeTimeIntervalsFrom[i];
} else if (robberyTimeTo >= freeTimeIntervalsTo[i] &&
robberyTimeFrom > freeTimeIntervalsFrom[i]) {
freeTimeIntervalsTo[i] = robberyTimeFrom;
} else if (robberyTimeTo < freeTimeIntervalsTo[i] && robberyTimeFrom <= freeTimeIntervalsFrom[i]) {
freeTimeIntervalsFrom[i] = robberyTimeTo;
} else if (robberyTimeTo < freeTimeIntervalsTo[i] && robberyTimeFrom > freeTimeIntervalsFrom[i]) {
freeTimeIntervalsTo.push(freeTimeIntervalsTo[i]);
freeTimeIntervalsFrom.push(robberyTimeTo);
freeTimeIntervalsTo[i] = robberyTimeFrom;
} else {
freeTimeIntervalsFrom[i] = 0;
freeTimeIntervalsTo[i] = 0;
}
}

function interval(robberyTimeFrom, robberyTimeTo) {
for (let i = 0; i < freeTimeIntervalsFrom.length; i++) {
confluence(robberyTimeFrom, robberyTimeTo, i);
}
}

function exclude(schedule) {
for (let robbery of Object.keys(schedule)) {
schedule[robbery].forEach(item => {
const robberyTimeFrom = splitTime(item.from);
const robberyTimeTo = splitTime(item.to);
interval(robberyTimeFrom, robberyTimeTo);
});
}
}

/**
* @param {Object} schedule – Расписание Банды
* @param {Number} duration - Время на ограбление в минутах
Expand All @@ -17,13 +99,33 @@ const isStar = true;
function getAppropriateMoment(schedule, duration, workingHours) {
console.info(schedule, duration, workingHours);

freeTimeIntervalsFrom = [];
freeTimeIntervalsTo = [];
rightTimeStart = [];
rightTimeEnd = [];
timeNumber = 0;

bankTimeInMinutes(workingHours);

for (let i = 0; i < 3; i++) {
freeTimeIntervalsFrom.push(startWorkBank + MINUTES_IN_DAY * i);
freeTimeIntervalsTo.push(endWorkBank + MINUTES_IN_DAY * i);
}

exclude(schedule);
checkInterval(duration);

return {

/**
* Найдено ли время
* @returns {Boolean}
*/
exists: function () {
if (rightTimeStart.length) {
return true;
}

return false;
},

Expand All @@ -34,7 +136,28 @@ function getAppropriateMoment(schedule, duration, workingHours) {
* @returns {String}
*/
format: function (template) {
return template;
if (!this.exists()) {
return '';
}

const time = rightTimeStart[timeNumber];
const day = 0;

while (time >= MINUTES_IN_DAY) {
time -= MINUTES_IN_DAY;
day++;
}

let minutes = time % MINUTES_IN_DAY;
let hours = (time - minutes) / MINUTES_IN_HOUR;

minutes = (minutes < 10 ? '0' : '') + minutes;
hours = (hours < 10 ? '0' : '') + hours;

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

/**
Expand All @@ -43,13 +166,24 @@ function getAppropriateMoment(schedule, duration, workingHours) {
* @returns {Boolean}
*/
tryLater: function () {
const time = rightTimeEnd[timeNumber] - rightTimeStart[timeNumber];

if (time - 30 >= duration) {
rightTimeStart[timeNumber] += 30;

return true;
} else if (rightTimeStart[timeNumber + 1]) {
timeNumber++

return true;
}

return false;
}
};
}

module.exports = {
getAppropriateMoment,

isStar
};