function City(powerStations, powerPanels, powerLines, houses) {
this._powerStations = powerStations;
this._powerPanels = powerPanels;
this._powerLines = powerLines;
this._houses = houses;
}
//Метод получения прибыли (убытка)
City.prototype.getFinanceResult = function(overflowPower) {
var order = (overflowPower > 0) ? "desc" : "asc";
//Если продаем подороже, то сортируем линии электропередач по убыванию
//Если покупаем подешевле, то по возрастанию
var powerLinesSortedByCost = this._powerLines.sort(function(a, b) {
return (order == "asc") ? a.cost - b.cost : b.cost - a.cost;
});
//console.log(powerLinesSortedByCost);
var powerSum = 0;
var costSum = 0;
for (var i = 0; i < powerLinesSortedByCost.length; i++) {
var power = Util.convertPowerToKwNumber(powerLinesSortedByCost[i].power);
var cost = powerLinesSortedByCost[i].cost;
if (powerSum + power >= Math.abs(overflowPower)) {
power = Math.abs(overflowPower) - powerSum;
}
powerSum += power;
//Так как учет цены идет в виде стоимости за мегаватт
costSum += Util.convertKwToMw(power) * cost;
}
/*
console.log("overflow " + overflowPower);
console.log("powerSum " + powerSum);
console.log("costSum " + costSum);
*/
if (powerSum < Math.abs(overflowPower)) {
throw new CityException("Power lines are not enough in the city");
}
//Если это был экспорт из других городов, надо показать это отрицательным значением
if (order == "asc") {
costSum = -costSum;
}
return +costSum.toFixed(2);
};
//Метод получения переизбытка (недоотдачи) городской энергии
City.prototype.getOverflowPower = function(timesOfDay) {
var cityPower = this._getCityPower(timesOfDay);
var needPower = this._getNeedPower(timesOfDay);
/*
console.log("cityPower " + cityPower);
console.log("needPower " + needPower);
console.log("np & cp " + timesOfDay);
console.log("---------------------------");
*/
return cityPower - needPower;
};
City.prototype._getCityPower = function(timesOfDay) {
var powerSum = 0;
for (var i = 0; i < this._powerStations.length; i++) {
var powerStation = this._powerStations[i];
powerSum += Util.convertPowerToKwNumber(powerStation.power);
}
if (timesOfDay == "day") {
for (var j = 0; j < this._powerPanels.length; j++) {
var powerPanel = this._powerPanels[j];
powerSum += Util.convertPowerToKwNumber(powerPanel.power);
}
} else {
for (j = 0; j < this._powerPanels; j++) {
powerSum += PowerPanel.NIGHT_POWER;
}
}
return powerSum;
};
City.prototype._getNeedPower = function(timesOfDay) {
var counter = 0;
for (var key in this._houses) {
counter++;
}
if (timesOfDay == "day") {
return counter * Util.convertPowerToKwNumber(House.FLAT_TAKE_DAY_POWER);
} else {
return counter * Util.convertPowerToKwNumber(House.FLAT_TAKE_NIGHT_POWER);
}
};
function CityException(message) {
this.name = "CityException";
this.message = message;
}
/***************PowerStation***************/
PowerStation.MIN_POWER = "1MW";
PowerStation.MAX_POWER = "100MW";
function PowerStation(power) {
this._setPower(power);
}
PowerStation.prototype._setPower = function(power) {
if (power < Util.convertPowerToKwNumber(PowerStation.MIN_POWER) ||
power > Util.convertPowerToKwNumber(PowerStation.MAX_POWER)) {
throw new PowerStationException("Incorrectly set power. " +
"Min: " + PowerStation.MIN_POWER + ". " +
"Max: " + PowerStation.MAX_POWER + ".");
}
this.power = power;
};
function PowerStationException(message) {
this.name = "PowerStationException";
this.message = message;
}
/***************House***************/
House.MIN_FLATS = 100;
House.MAX_FLATS = 400;
House.FLAT_TAKE_DAY_POWER = "4KW";
House.FLAT_TAKE_NIGHT_POWER = "1KW";
function House(flats) {
this._setFlats(flats);
}
House.prototype._setFlats = function(flats) {
flats = +flats.slice(0, -5);
if (isNaN(flats)) {
throw new HouseException("Not a number");
} else if (flats < House.MIN_FLATS || flats > House.MAX_FLATS) {
throw new HouseException("Incorrect number of flats. " +
"Min: " + House.MIN_FLATS + ". " +
"Max: " + House.MAX_FLATS + ".");
}
this.flats = flats;
};
function HouseException(message) {
this.name = "HouseException";
this.message = message;
}
/***************PowerPanel***************/
PowerPanel.TYPE_ONE = "typeOne";
PowerPanel.TYPE_TWO = "typeTwo";
PowerPanel.TYPE_THREE = "typeThree";
PowerPanel.TYPE_FOUR = "typeFour";
PowerPanel.TYPE_FIVE = "typeFive";
PowerPanel.NIGHT_POWER = 0;
PowerPanel.typeList = {
"typeOne": "1MW",
"typeTwo": "2MW",
"typeThree": "3MW",
"typeFour": "4MW",
"typeFive": "5MW"
};
function PowerPanel(type) {
this._setType(type);
this._setPower(PowerPanel.typeList[this.type]);
}
PowerPanel.prototype._setType = function(type) {
if (!(type in PowerPanel.typeList)) {
throw new PowerPanelException("Wrong type of panel. Allowed panels: " +
Object.keys(PowerPanel.typeList) + ".");
}
this.type = type;
};
PowerPanel.prototype._setPower = function(power) {
this.power = power;
};
function PowerPanelException(message) {
this.name = "PowerPanelException";
this.message = message;
}
/***************PowerLine***************/
PowerLine.typeList = {
"typeOne": {power: "50MW", cost: 5},
"typeTwo": {power: "75MW", cost: 4.9},
"typeThree": {power: "110MW", cost: 5.2},
"T-800": {power: "100MW", cost: 5.6}
};
function PowerLine(type) {
this._setType(type);
}
PowerLine.prototype._setType = function(type) {
if (!(type in PowerLine.typeList)) {
throw new PowerLineException("Wrong type of power line. Allowed panels: " +
Object.keys(PowerLine.typeList) + ".");
}
this.type = type;
this.power = PowerLine.typeList[type].power;
this.cost = PowerLine.typeList[type].cost;
};
function PowerLineException(message) {
this.name = "PowerLineException";
this.message = message;
}
/***************Util***************/
function Util() {}
//Статический метод конвертации строки вида 15MW в число 15000
Util.convertPowerToKwNumber = function(power) {
var unit = power.slice(-2);
var value = +power.slice(0, -2);
switch(unit) {
case "KW": return value;
case "MW": return value * 1000;
default: throw new UtilException("Wrong unit of power");
}
};
//Противоположный эффект методу Util.convertPowerToKwNumber
Util.convertKwNumberToPower = function(kw) {
if (Math.abs(kw) < 1000) {
return kw + "KW";
} else {
return Util.convertKwToMw(kw) + "MW";
}
};
//Метод для расчета цены (тарифы в мегаваттах) который используется один раз :(
Util.convertKwToMw = function(kw) {
return kw / 1000;
};
//Создание массива объектов
Util.generator = function(constructor, conditions) {
var objects = [];
for (var key in conditions) {
for (var i = 0; i < conditions[key]; i++) {
objects.push(new constructor(key));
}
}
return objects;
};
Util.showResults = function(timesOfDay, power, financeResult) {
console.log("Times of day: " + timesOfDay + ".");
if (financeResult >= 0) {
console.log("Profit is equal to: " + financeResult + ". " +
"Overflow of power: " + Util.convertKwNumberToPower(power) + ".");
} else {
console.log("Loss is equal to: " + financeResult + ". " +
"Deficit of power: " + Util.convertKwNumberToPower(power) + ".");
}
console.log("---------------------------");
};
function UtilException(message) {
this.name = "UtilException";
this.message = message;
}
/***************Test***************/
//Далее - количество определенных элементов электросети (значение) и их хар-ка (ключ)
//(15000 * 1) + (30000 * 2) + (45000 * 1) + (60000 * 2) = 240000KW (сила на сутки)
var conditionsForPowerStations = {
"15MW": 1,
"30MW": 2,
"45MW": 1,
"60MW": 2
};
//(8 * 1000) + (6 * 2000) + (9 * 3000) + (9 * 4000) + (8000 * 5) = 123000KW (сила на день)
var conditionsForPowerPanels = {
"typeOne": 8,
"typeTwo": 6,
"typeThree": 9,
"typeFour": 9,
"typeFive": 8
};
//800000KW требуется днем и 200000KW ночью
var conditionsForHouses = {
"100Flats": 200000,
"200Flats": 0,
"300Flats": 0,
"400Flats": 0
};
//(50 * 5) + (75 * 8) + (110 * 6) + (100 * 1) = 1610MW пропускная способность
var conditionsForPowerLines = {
"typeOne": 5,
"typeTwo": 8,
"typeThree": 6,
"T-800": 1
};
/**
Перенесем сюда тарифы чтобы легче было сверить результаты
работы програмы
*/
//"typeOne": {power: "50MW", cost: 5},
//"typeTwo": {power: "75MW", cost: 4.9},
//"typeThree": {power: "110MW", cost: 5.2},
//"T-800": {power: "100MW", cost: 5.6}
/**
Днем энергия города будет 363 мегаватта.
Днем городу нужно 80 мегаватт.
Днем дефицит будет 437 мегаватт.
Придется их купить со второй дешевой линии (4.9).
Шести линий хватит (75 * 6 > 437). Цена: 437 * 4.9 = 2141.3
Ночью энергия города будет 240 мегаватта.
Ночью городу нужно 200 мегаватт.
Ночью переизбыток будет 40 мегаватт.
Продаем их с последней дорогой линии (5.6).
Одной линии хватит (100 > 40). Цена: 40 * 5.6 = 224
*/
try {
var powerStations = Util.generator(PowerStation, conditionsForPowerStations);
var panels = Util.generator(PowerPanel, conditionsForPowerPanels);
var houses = Util.generator(House, conditionsForHouses);
var powerLines = Util.generator(PowerLine, conditionsForPowerLines);
//console.log(powerStations);
//console.log(panels);
//console.log(houses);
var city = new City(powerStations, panels, powerLines, houses);
var overflowForDay = city.getOverflowPower("day");
var overflowForNight = city.getOverflowPower("night");
var resultForDay = city.getFinanceResult(overflowForDay);
var resultForNight = city.getFinanceResult(overflowForNight);
Util.showResults("day", overflowForDay, resultForDay);
Util.showResults("night", overflowForNight, resultForNight);
} catch(error) {
console.log(error.name + ": " + "Message: " + error.message);
}