Skip to content
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
239 changes: 236 additions & 3 deletions robbery.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,225 @@
* Сделано задание на звездочку
* Реализовано оба метода и tryLater
*/
const isStar = true;
const isStar = false;
const dayOfWeek = new Map();
dayOfWeek.set('ПН', 0);
dayOfWeek.set('ВТ', 1);
dayOfWeek.set('СР', 2);
dayOfWeek.set('ЧТ', 3);
const backToDay = ['ПН', 'ВТ', 'СР'];
let timezone = 0;
let bankTimeFrom;
let bankTimeTo;
let _duration;


class Time {
constructor(minutes, day) {
this.minutes = minutes;
this.day = day;
}

getMinutes() {
return this.minutes;
}

getTimeFromMinutes() {
let hours = Math.floor(this.minutes / 60) + timezone;
let minutes = this.minutes - 60 * Math.floor(this.minutes / 60);
if (hours < 0) {
return {
day: backToDay[this.day - 1],
hours: 24 + hours,
minutes
};
} else if (hours >= 24) {
return {
day: backToDay[this.day + 1],
hours: 24 - hours,
minutes
};
}

return {
day: backToDay[this.day],
hours,
minutes
};

}
}

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

isIntersection(section) {
return section.to.getMinutes() >= this.from.getMinutes() &&
section.from.getMinutes() <= this.to.getMinutes();
}
}

function addToInSections(sections, to) {
sections[to.day].push(new Section(new Time(0, to.day), to));
}

function addFromInSections(sections, from) {
sections[from.day].push(new Section(from, new Time(1439, from.day)));
}

function addInSections(sections, from, to) {
if (from && !to) {
addFromInSections(sections, from);
} else if (to && !from) {
addToInSections(sections, to);
}
}

function makeSectionsFromSchedule(_schedule, sections) {
for (let i of _schedule) {
let from = parseTime(i.from);
let to = parseTime(i.to);
if (!from || !to) {
addInSections(sections, from, to);
continue;
}
if (from.day !== to.day) {
addFromInSections(sections, from);
addToInSections(sections, to);
} else {
sections[from.day].push(new Section(from, to));
}
}
}

function findTime(sections) {
let result = null;
sections = sections.map(x=> x.sort((a, b) => {
return a.from.getMinutes() - b.from.getMinutes();
}));
for (let i = 0; i < sections.length; i++) {
let intersections = [];
let section = sections[i];
findIntersection(section, intersections);
intersections = intersections.filter(x => x.length !== 0);
if (intersections.length === 1) {
result = findWithOneIntersection(intersections, i);
} else if (intersections.length === 0) {
result = findWithoutIntersection(section, i);
} else {
result = findWithSomeIntersections(intersections, i);
}
if (result) {
return result;
}
}

return result;
}

function findIntersection(section, intersections) {
for (let j of section) {
let intersection = new Set();
section.forEach(x => {
if (x === j || j.isIntersection(x)) {
intersection.add(x);
}
});
intersections.push(Array.from(intersection.values()));
}
}

function findWithOneIntersection(intersections, day) {
let result = null;
let min = intersections[0][0].from.getMinutes();
let max = intersections[0][intersections.length - 1].to.getMinutes();
if (min - bankTimeFrom >= _duration) {
return new Time(bankTimeFrom, day);
}
if (bankTimeTo - max >= _duration) {
return new Time(max, day);
}

return result;
}

function findWithSomeIntersections(intersections, day) {
let _sections = [];
for (let n of intersections) {
let _from = n[0].from.getMinutes();
let _to = n[n.length - 1].to.getMinutes();
_sections.push(new Section(_from, _to));
}

return findWithoutIntersection(_sections, day);
}

function checkLastSection(section, result, day) {
if (bankTimeTo - section[section.length - 1].to >= _duration) {
result = new Time(section[section.length - 1], day);
}

return result;
}

function findWithoutIntersection(section, day) {
let result = null;
let start = bankTimeFrom;
for (let m of section) {
if (m.from < start && m.to <= start) {
continue;
}
if (m.from - start >= _duration && m.from < bankTimeTo) {
return new Time(start, day);
}
start = m.to;
}
result = checkLastSection(section, result, day);

return result;
}

function hoursToMinutes(hours, minutes) {
return hours * 60 + minutes;
}

function parseWorkingHours(str) {
timezone = parseInt(str.substr(6, 2));
let hours = parseInt(str.substr(0, 2)) - timezone;
let _hours = hours < 0 ? hours + 24 : hours;
let minutes = parseInt(str.substr(3, 2));

return new Time(hoursToMinutes(_hours, minutes), 'all');
}

function parseTime(str) {
let hours = parseInt(str.substr(3, 2)) - parseInt(str.substr(9, 2));
let minutes = parseInt(str.substr(6, 2));
let day = dayOfWeek.has(str.substr(0, 2)) ? dayOfWeek.get(str.substr(0, 2)) : 3;
if (hours < 0) {
if (day - 1 >= 0 && day - 1 < 3) {
day -= 1;
hours += 24;
} else {
hours = 0;
}
}

return day !== 3 ? new Time(hoursToMinutes(hours, minutes), day) : null;
}

function formatTime(template, time) {
let minutes = time.minutes < 10 ? '0' + time.minutes : time.minutes;
let _template = template.replace(/%HH:%MM/,
`${time.hours}:${minutes}`);
_template = _template.replace(/%DD/,
time.day);

return _template;
}

/**
* @param {Object} schedule – Расписание Банды
Expand All @@ -15,6 +233,9 @@ const isStar = true;
* @returns {Object}
*/
function getAppropriateMoment(schedule, duration, workingHours) {
_duration = duration;
bankTimeFrom = parseWorkingHours(workingHours.from).getMinutes();
bankTimeTo = parseWorkingHours(workingHours.to).getMinutes();
console.info(schedule, duration, workingHours);

return {
Expand All @@ -24,7 +245,7 @@ function getAppropriateMoment(schedule, duration, workingHours) {
* @returns {Boolean}
*/
exists: function () {
return false;
return this.format('%DD %HH:%MM') !== '';
},

/**
Expand All @@ -34,7 +255,19 @@ function getAppropriateMoment(schedule, duration, workingHours) {
* @returns {String}
*/
format: function (template) {
return template;
let _schedule = [];
Object
.keys(schedule)
.map(x => schedule[x])
.forEach(x => x.forEach(y => _schedule.push(y)));
let sections = [];
for (let i = 0; i < 3; i++) {
sections[i] = [];
}
makeSectionsFromSchedule(_schedule, sections);
let result = findTime(sections.filter(x => x.length !== 0));

return result ? formatTime(template, result.getTimeFromMinutes()) : '';
},

/**
Expand Down