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

Смеловская Татьяна #40

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b41fabf
Друзьяшки Оушена
TatianaSmelovsckaya Oct 25, 2016
a1b9194
Граничные значения
TatianaSmelovsckaya Oct 25, 2016
0b6d431
Количество бандитов
TatianaSmelovsckaya Oct 26, 2016
cf7ab2d
Добавлена ситуация, когда банк вообще не работает
TatianaSmelovsckaya Oct 26, 2016
019d6b1
Добавлена ситуация, когда бандиты свободны
TatianaSmelovsckaya Oct 26, 2016
1f7108d
Без звёздочки
TatianaSmelovsckaya Oct 26, 2016
c224a48
Вернула звёздочку, исправила граничные значения
TatianaSmelovsckaya Oct 26, 2016
da9f5cb
Исправлен поиск интервалов для ограбления
TatianaSmelovsckaya Oct 26, 2016
1daf182
Исправлены границы
TatianaSmelovsckaya Oct 26, 2016
102e8d5
Исправлены границы 2
TatianaSmelovsckaya Oct 26, 2016
d033813
Откат
TatianaSmelovsckaya Oct 26, 2016
5a497ac
Исправлено формирование интервалов
TatianaSmelovsckaya Oct 26, 2016
c29ceb1
Исправлены границы 3
TatianaSmelovsckaya Oct 26, 2016
d63e3e0
Исправлено формирование интервалов 2
TatianaSmelovsckaya Oct 26, 2016
8b5739f
Исправлено формирование интервалов 4
TatianaSmelovsckaya Oct 26, 2016
6024a98
Исправлены границы 5
TatianaSmelovsckaya Oct 26, 2016
595dff2
Исправлено формирование интервалов 6
TatianaSmelovsckaya Oct 26, 2016
fd21c5a
Откат
TatianaSmelovsckaya Oct 26, 2016
34a7f27
Убрала лишную корректировку
TatianaSmelovsckaya Oct 26, 2016
5068dbd
Немного рефакторинга
TatianaSmelovsckaya Oct 31, 2016
138ebc3
Ещё рефакторинг
TatianaSmelovsckaya Oct 31, 2016
e6de2b2
Корректировка условий вхождения в интервал
TatianaSmelovsckaya Oct 31, 2016
94ef452
Исправлен поиск начала интервала для анализа
TatianaSmelovsckaya Oct 31, 2016
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
328 changes: 324 additions & 4 deletions robbery.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
*/
exports.isStar = true;

var MINUTES_IN_HOUR = 60;
var HOURS_IN_DAY = 24;
var MINUTES_IN_DAY = MINUTES_IN_HOUR * HOURS_IN_DAY;

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

if (!isWorkingHours(workingHours) || (!duration)) {
return {
exists: function () {
return false;
},
format: function () {
return '';
},
tryLater: function () {
return false;
}
};
}

var bankUTC = getBankUTC(workingHours.from);
var bankIntervals = getBankIntervals(workingHours);
var gangIntervals = getGangIntervals(schedule, bankUTC);

var robberyIntervals = findRobberyIntervals(bankIntervals, gangIntervals);
var goodTimes = getGoodTimesForRobbery(robberyIntervals, duration);

var isExistsTime = goodTimes.length !== 0;
var robberyTime = goodTimes.shift();

return {

Expand All @@ -24,7 +51,7 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) {
* @returns {Boolean}
*/
exists: function () {
return false;
return isExistsTime;
},

/**
Expand All @@ -35,7 +62,21 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) {
* @returns {String}
*/
format: function (template) {
return template;
if (!isExistsTime || !template) {
return '';
}

var day = ['ПН', 'ВТ', 'СР'][Math.floor(robberyTime / MINUTES_IN_DAY)];

var hour = Math.floor((robberyTime % MINUTES_IN_DAY) / MINUTES_IN_HOUR);
hour = (hour < 10 ? '0' : '') + hour;

var minute = (robberyTime % MINUTES_IN_DAY) % MINUTES_IN_HOUR;
minute = (minute < 10 ? '0' : '') + minute;

return template.replace('%DD', day)
.replace('%HH', hour)
.replace('%MM', minute);
},

/**
Expand All @@ -44,7 +85,286 @@ exports.getAppropriateMoment = function (schedule, duration, workingHours) {
* @returns {Boolean}
*/
tryLater: function () {
return false;
var oldTime = robberyTime;
robberyTime = goodTimes.shift() || robberyTime;

return robberyTime !== oldTime;
}
};
};

function isWorkingHours(hours) {
return (hours) && (Object.keys(hours).length !== 0);
}

function getBankUTC(dateAsString) {
return parseInt(dateAsString.split('+')[1]);
}

function getBankIntervals(workingHours) {
var bankIntervals = [];

var bankStart = transformStringToDate(workingHours.from);
var bankEnd = transformStringToDate(workingHours.to);

bankIntervals.push(
{
from: convertDateToMinutes(bankStart, 'ПН'),
to: convertDateToMinutes(bankEnd, 'ПН')
},
{
from: convertDateToMinutes(bankStart, 'ВТ'),
to: convertDateToMinutes(bankEnd, 'ВТ')
},
{
from: convertDateToMinutes(bankStart, 'СР'),
to: convertDateToMinutes(bankEnd, 'СР')
}
);

return bankIntervals;
}

function transformStringToDate(dateAsString) {
var dateComponents = dateAsString.split(/\s|:|\+/);

if (dateComponents.length === 3) {
return {
day: '',
hour: parseInt(dateComponents[0]),
minute: parseInt(dateComponents[1]),
utc: parseInt(dateComponents[2])
};
}

return {
day: dateComponents[0],
hour: parseInt(dateComponents[1]),
minute: parseInt(dateComponents[2]),
utc: parseInt(dateComponents[3])
};
}

function convertDateToMinutes(date, day) {
if (day) {
date.day = day;
}

return getMinutes(date);
}

function getMinutes(date) {
var minutes = date.minute + date.hour * MINUTES_IN_HOUR;

if (date.day === 'ПН') {
minutes += 0;
} else if (date.day === 'ВТ') {
minutes += MINUTES_IN_DAY;
} else if (date.day === 'СР') {
minutes += 2 * MINUTES_IN_DAY;
} else {
minutes += 3 * MINUTES_IN_DAY;
}

return minutes;
}

function getGangIntervals(shedule, bankUTC) {
var gangIntervals = [];

if (!shedule || Object.keys(shedule).length === 0) {
return gangIntervals;
}

var bandits = Object.keys(shedule);

for (var i = 0; i < bandits.length; i++) {
var bandit = bandits[i];
gangIntervals = gangIntervals.concat(getBanditShedule(shedule[bandit], bankUTC));
}

gangIntervals.sort(function (interval1, interval2) {
return interval1.from > interval2.from;
});

return gangIntervals;
}

function getBanditShedule(banditShedule, bankUTC) {
var banditIntervals = [];
for (var i = 0; i < banditShedule.length; i++) {
banditIntervals.push(getBanditInterval(banditShedule[i], bankUTC));
}

return banditIntervals;
}

function getBanditInterval(elementOfShedule, bankUTC) {
var dateStart = transformStringToDate(elementOfShedule.from);
var dateEnd = transformStringToDate(elementOfShedule.to);

var minutesStart = convertDateToMinutes(dateStart);
var minutesEnd = convertDateToMinutes(dateEnd);

var minutesStartWithUTC = addUTCToMinutes(minutesStart, dateStart.utc, bankUTC);
var minutesEndWithUTC = addUTCToMinutes(minutesEnd, dateEnd.utc, bankUTC);

return {
from: minutesStartWithUTC,
to: minutesEndWithUTC
};
}

function addUTCToMinutes(minutes, banditUTC, bankUTC) {
return minutes - (banditUTC - bankUTC) * MINUTES_IN_HOUR;
}
// function findNewStart(gangIntervals, start) {
// return gangIntervals.filter(function (interval) {
// return interval.from <= start && start <= interval.to;
// });
// }

function findBadStart(gangIntervals, start, end) {
return gangIntervals.filter(function (interval) {
return start < interval.from && interval.to < end;
});
}

function exploreInterval(gangIntervals, robberyIntervals, robberyStart, robberyEnd) {
while (robberyStart <= robberyEnd) {
var badStart = findBadStart(gangIntervals, robberyStart, robberyEnd)[0];

var from = badStart !== undefined ? badStart.from : robberyEnd;

robberyIntervals.push({
from: robberyStart,
to: from
});

if (from === robberyEnd) {
break;
}

robberyStart = badStart !== undefined ? badStart.to : robberyEnd;

// robberyStart = findNewStart(gangIntervals, robberyStart)
// .map(function (elem) {
// return elem.to;
// })
// .sort(function (a, b) {
// return b > a;
// })[0];
robberyStart = findRobberyStart(gangIntervals, { from: robberyStart, to: robberyEnd });
}
}

function findRobberyIntervals(bankIntervals, gangIntervals) {
if (gangIntervals.length === 0) {
return bankIntervals;
}

var robberyIntervals = [];

for (var i = 0; i < bankIntervals.length; i++) {
var bankInterval = bankIntervals[i];
// var robberyInterval = findPossibleRobberyInterval(gangIntervals, bankInterval);
var robberyStart = findRobberyStart(gangIntervals, bankInterval);
var robberyEnd = findRobberyEnd(gangIntervals, bankInterval);
if (robberyStart >= bankInterval.to || robberyEnd <= robberyStart) {
continue;
}

exploreInterval(gangIntervals, robberyIntervals, robberyStart, robberyEnd);
}

return robberyIntervals;
}

function findRobberyStart(gangIntervals, bankInterval) {
var robberyStart = bankInterval.from;

var newRobberyStart = gangIntervals.filter(function (interval) {
return interval.from <= bankInterval.from && bankInterval.from < interval.to;
})
.map(function (intervals) {
return intervals.to;
})
.sort(function (a, b) {
return a < b;
})[0];

if (newRobberyStart !== undefined && newRobberyStart !== robberyStart) {
var newInterval = {
from: newRobberyStart,
to: bankInterval.to
};
robberyStart = findRobberyStart(gangIntervals, newInterval);
}

return robberyStart;
}

function findRobberyEnd(gangIntervals, bankInterval) {
var robberyEnd = bankInterval.to;

var newRobberyEnd = gangIntervals.filter(function (interval) {
return interval.from < bankInterval.to && bankInterval.to <= interval.to;
})
.map(function (intervals) {
return intervals.from;
})
.sort(function (a, b) {
return a > b;
})[0];

if (newRobberyEnd !== undefined && newRobberyEnd !== robberyEnd) {
var newInterval = {
from: bankInterval.from,
to: newRobberyEnd
};
robberyEnd = findRobberyEnd(gangIntervals, newInterval);
}

return robberyEnd;
}

// function findPossibleRobberyInterval(gangIntervals, bankInterval) {
// var robberyStart = gangIntervals.filter(function (interval) {
// return interval.from <= bankInterval.from && bankInterval.from < interval.to;
// })
// .map(function (intervals) {
// return intervals.to;
// })
// .sort(function (a, b) {
// return a < b;
// })[0];

// var robberyEnd = gangIntervals.filter(function (interval) {
// return interval.from < bankInterval.to && bankInterval.to <= interval.to;
// })
// .map(function (intervals) {
// return intervals.from;
// })
// .sort(function (a, b) {
// return a > b;
// })[0];

// robberyStart = robberyStart ? robberyStart : bankInterval.from;
// robberyEnd = robberyEnd ? robberyEnd : bankInterval.to;

// return [robberyStart, robberyEnd];
// }

function getGoodTimesForRobbery(robberyIntervals, duration) {
var goodTimes = [];
var stepTime = 30;

robberyIntervals.forEach(function (time) {
while (time.from + duration <= time.to) {
goodTimes.push(time.from);
time.from += stepTime;
}
});

return goodTimes;
}