Skip to content

Commit

Permalink
chore: move sorting into List class
Browse files Browse the repository at this point in the history
increases readability of the safe round fn
  • Loading branch information
boredland committed Feb 24, 2023
1 parent 7c08d0c commit 0f52b73
Showing 1 changed file with 40 additions and 10 deletions.
50 changes: 40 additions & 10 deletions src/safeRound.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,32 +51,62 @@ class ListNumber {
}
}

class List {
private _items: ListNumber[];

constructor(values: number[], private places: number) {
this._items = values.map((value, index) => new ListNumber(index, value, this.places))
}

public update(items: ListNumber[]) {
this._items = items;
}

get items() {
return this._items.sort((a,b) => a.order - b.order);
}

private get original() {
return this.items.map(item => item.original);
}

public get values() {
return this.items.map(item => item.value);
}

get sum() {
return sumUp(this.values, this.places)
}

get originalSum() {
return sumUp(this.original, this.places);
}
}

/**
* Safely round a list of values so, that their resulting sum equals the input values sum
* @param values - values to round
* @param places - places to round to
* @returns list of rounded values
*/
export const safeRound = (values: number[], places = 0) => {
let local: ListNumber[] = values.map((value, index) => new ListNumber(index, value, places));
const originalSum = sumUp(local.map(value => value.original), places);
let localSum = sumUp(local.map(item => item.value), places);
let list = new List(values, places);
let increment = -1;

while (localSum !== originalSum) {
const diff = roundToPlaces(originalSum - localSum, places);
while (list.sum !== list.originalSum) {
const diff = roundToPlaces(list.originalSum - list.sum, places);
if (diff < 0) {
increment = -1 * _mininc(places);
} else {
increment = _mininc(places);
}
const tweaks = Math.floor(Math.abs(diff) / _mininc(places));
local = local.sort((a,b) => a.diff - b.diff);
const items = list.items.sort((a,b) => a.diff - b.diff);

[...local.slice(0, tweaks)].forEach((v, i) => {
local[i].add(increment);
[...items.slice(0, tweaks)].forEach((v, i) => {
items[i].add(increment);
});
localSum = sumUp(local.map(item => item.value), places);
list.update(items)
}
return local.sort((a, b) => a.order - b.order).map(item => item.value);
return list.values;
};

0 comments on commit 0f52b73

Please sign in to comment.