Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function assert(n: number) {
- if (n > 0) {
- return;
- }
- throw new Error("must be positive");
- }
- class PriceRange {
- public readonly range: number;
- constructor(public readonly min: number,
- public readonly max: number,
- public readonly weight: number,) {
- assert(min);
- assert(max);
- assert(weight);
- if (min > max) {
- throw new Error(`"from" must be more than "to"`);
- }
- this.range = this.max - this.min;
- }
- public minAmount() {
- return this.weight * this.min;
- }
- public maxAmount() {
- return this.weight * this.max;
- }
- }
- class Result {
- constructor(public readonly prices: Array<number>,
- public readonly found: boolean,) {
- }
- }
- function min(priceRangeList: Array<PriceRange>): number {
- let result = 0;
- for (let i = 0; i < priceRangeList.length; i++) {
- result += priceRangeList[i].minAmount();
- }
- return result;
- }
- function max(priceRangeList: Array<PriceRange>): number {
- let result = 0;
- for (let i = 0; i < priceRangeList.length; i++) {
- result += priceRangeList[i].maxAmount();
- }
- return result;
- }
- function find(totalAmount, priceRangeList: Array<PriceRange>): Result {
- const maxRemain = totalAmount - min(priceRangeList);
- if (maxRemain < 0) {
- return new Result([], false);
- }
- const minRemain = totalAmount - max(priceRangeList);
- if (minRemain > 0) {
- return new Result([], false);
- }
- let currentRemain = maxRemain;
- const prices = [];
- for (let i = 0; i < priceRangeList.length; i++) {
- prices[i] = priceRangeList[i].min;
- }
- for (let i = 0; i < priceRangeList.length; i++) {
- const priceRange = priceRangeList[i];
- const priceUp = Math.min(Math.floor(currentRemain / priceRange.weight), priceRange.range);
- if (priceUp > 0) {
- currentRemain -= priceUp * priceRange.weight;
- prices[i] += priceUp;
- if (currentRemain === 0) {
- new Result(prices, true);
- }
- }
- }
- return new Result(prices, false);
- }
- function test() {
- try {
- const result = find(
- 51106000,
- [
- new PriceRange(1400, 2070, 11868),
- new PriceRange(1400, 2070, 6924),
- new PriceRange(1400, 2070, 6366),
- new PriceRange(1400, 2070, 2964),
- new PriceRange(1400, 6000, 300),
- ],
- );
- if (result.found) {
- console.log(result.prices);
- } else if (result.prices.length > 0) {
- console.log("only approximate prices", result.prices);
- } else {
- console.log("result not found");
- }
- } catch (e) {
- console.error("invalid data", e);
- }
- }
- test();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement