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

Маркевич Роман #86

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
184 changes: 180 additions & 4 deletions robbery.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,175 @@
* Сделано задание на звездочку
* Реализовано оба метода и tryLater
*/
const isStar = true;
const isStar = false;
const DAYS_KEYS = { 'ПН': 0, 'ВТ': 1, 'СР': 2, 'ЧТ': 3, 'ПТ': 4, 'СБ': 5, 'ВС': 6 };
const NUMBER_KEYS = { 0: 'ПН', 1: 'ВТ', 2: 'СР', 3: 'ЧТ', 4: 'ПТ', 5: 'СБ', 6: 'ВС' };
const HOURS_IN_DAYS = 24;
const MINUTES_IN_HOUR = 60;
const MINUTES_IN_DAY = HOURS_IN_DAYS * MINUTES_IN_HOUR;

class Time {
constructor(currentString) {
this.currentString = currentString;
this.day = getDayFromStr(currentString);
this.dayIndex = DAYS_KEYS[this.day];
this.hours = getHoursFromStr(currentString);
this.minutes = getMinutesFromStr(currentString);
this.delta = getTimeZone(currentString);
}

convertStringToMinutes(bankTimeZone) {
return this.dayIndex * MINUTES_IN_DAY +
this.hours * MINUTES_IN_HOUR +
this.minutes +
(bankTimeZone - this.delta) * MINUTES_IN_HOUR;
}
}

class Interval {
constructor(from, to) {
this.from = from;
this.to = to;
}

isIntersecPoint(point) {
return point >= this.from && point <= this.to;
}

isInInterval(interval) {
return this.from >= interval.from && this.to <= interval.to;
}
}

function getTimeZone(str) {
return parseInt(str.match(/[+]\d+/).toString()
.substr(1));
}

function getHoursFromStr(str) {
let hour = str.match(/\d+:/).toString();

return parseInt(hour.substring(0, hour.length - 1));
}

function getDayFromStr(str) {
let day = str.match(/[А-Я]{2}/);
if (day === null) {
return NUMBER_KEYS[0];
}

return day.toString();
}

function getMinutesFromStr(str) {
let minute = str.match(/:\d+/).toString();

return parseInt(minute.substr(1));
}

function getArrayOfIntervals(freeInterval, interval) {
let intersectLeft = freeInterval.isIntersecPoint(interval.from);
let intersectRight = freeInterval.isIntersecPoint(interval.to);

if (intersectLeft) {
if (intersectRight) {
return [new Interval(freeInterval.from, interval.from),
new Interval(interval.to, freeInterval.to)];
}

return [new Interval(freeInterval.from, interval.from)];
}
if (!intersectLeft && intersectRight) {
return [new Interval(interval.to, freeInterval.to)];
}
if (freeInterval.isInInterval(interval)) {
return [];
}

return [freeInterval];
}

function calculateInterval(freeIntervals, intervals) {
for (let interval of intervals) {
calculateInversia(freeIntervals, interval);
}
}

function calculateInversia(freeIntervals, interval) {
for (let i = 0; i < freeIntervals.length;) {
let temp = getArrayOfIntervals(freeIntervals[i], interval);
freeIntervals.splice(i, 1);
for (let j = 0; j < temp.length; j++) {
freeIntervals.splice(i + j, 0, temp[j]);
}
i += temp.length;
}
}

function convertStrToDeltaTime(param, bankTimeZone) {
let timeFrom = (new Time(param.from)).convertStringToMinutes(bankTimeZone);
let timeTo = (new Time(param.to)).convertStringToMinutes(bankTimeZone);

return new Interval(timeFrom, timeTo);
}

function niceRofl(obj, intervals, bankTimeZone) {
for (let param of obj) {
let deltaTime = convertStrToDeltaTime(param, bankTimeZone);
intervals.push(deltaTime);
}
}

function getIntervalsFromSchedlue(schedule, bankTimeZone) {
let intervals = [];
for (let human in schedule) {
if (schedule.hasOwnProperty(human)) {
niceRofl(schedule[human], intervals, bankTimeZone);
}
}

return intervals;
}

function checkFreeIntervals(freeIntervals, duration) {
for (let freeInterval of freeIntervals) {
let delta = freeInterval.to - freeInterval.from;
if (delta >= duration) {
return freeInterval;
}
}

return false;
}

function findRoberyTime(schedule, duration, workingHours) {
const bankTimeZone = getTimeZone(workingHours.from);
let intervals = getIntervalsFromSchedlue(schedule, bankTimeZone);
let bankInterval = convertStrToDeltaTime(workingHours, bankTimeZone);
let freeIntervals = [];
for (let i = 0; i < 3; i++) {
freeIntervals.push(new Interval(bankInterval.from +
i * MINUTES_IN_DAY, bankInterval.to + i * MINUTES_IN_DAY));
intervals.push(new Interval(i * MINUTES_IN_DAY, i * MINUTES_IN_DAY));
}
calculateInterval(freeIntervals, intervals);

return checkFreeIntervals(freeIntervals, duration);
}

function convertToResultAnswer(time, template) {
let dayIndex = Math.floor(time / MINUTES_IN_DAY);
let day = NUMBER_KEYS[dayIndex];
let hour = Math.floor((time - MINUTES_IN_DAY * dayIndex) / MINUTES_IN_HOUR);
let minutes = time - MINUTES_IN_DAY * dayIndex - hour * MINUTES_IN_HOUR;
minutes = minutes > 10 ? minutes : '0' + minutes.toString();
template = template
.replace('%DD', day)
.replace('%HH', hour)
.replace('%MM', minutes);

return template;
}

/**
* @param {Object} schedule – Расписание Банды
Expand All @@ -15,7 +183,7 @@ const isStar = true;
* @returns {Object}
*/
function getAppropriateMoment(schedule, duration, workingHours) {
console.info(schedule, duration, workingHours);
let resultOfFunction = findRoberyTime(schedule, duration, workingHours);

return {

Expand All @@ -24,7 +192,11 @@ function getAppropriateMoment(schedule, duration, workingHours) {
* @returns {Boolean}
*/
exists: function () {
return false;
if (resultOfFunction === false) {
return false;
}

return true;
},

/**
Expand All @@ -34,7 +206,11 @@ function getAppropriateMoment(schedule, duration, workingHours) {
* @returns {String}
*/
format: function (template) {
return template;
if (!resultOfFunction) {
return '';
}

return convertToResultAnswer(resultOfFunction.from, template);
},

/**
Expand Down