Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function repairCars(ranks: number[], cars: number): number {
- if (cars === 0) return 0;
- // https://stackoverflow.com/a/42919752
- const top: number = 0;
- const parent = (i: number) => ((i + 1) >>> 1) - 1;
- const left = (i: number) => (i << 1) + 1;
- const right = (i: number) => (i + 1) << 1;
- class PriorityQueue {
- private _heap: number[];
- private _comparator: (a: number, b: number) => boolean;
- constructor(comparator = (a: number, b: number) => a > b) {
- this._heap = [];
- this._comparator = comparator;
- }
- size() {
- return this._heap.length;
- }
- isEmpty() {
- return this.size() == 0;
- }
- peek() {
- return this._heap[top];
- }
- push(...values) {
- values.forEach(value => {
- this._heap.push(value);
- this._siftUp();
- });
- return this.size();
- }
- pop() {
- const poppedValue = this.peek();
- const bottom = this.size() - 1;
- if (bottom > top) {
- this._swap(top, bottom);
- }
- this._heap.pop();
- this._siftDown();
- return poppedValue;
- }
- replace(value) {
- const replacedValue = this.peek();
- this._heap[top] = value;
- this._siftDown();
- return replacedValue;
- }
- _greater(i, j) {
- return this._comparator(this._heap[i], this._heap[j]);
- }
- _swap(i, j) {
- [this._heap[i], this._heap[j]] = [this._heap[j], this._heap[i]];
- }
- _siftUp() {
- let node = this.size() - 1;
- while (node > top && this._greater(node, parent(node))) {
- this._swap(node, parent(node));
- node = parent(node);
- }
- }
- _siftDown() {
- let node = top;
- while (
- (left(node) < this.size() && this._greater(left(node), node)) ||
- (right(node) < this.size() && this._greater(right(node), node))
- ) {
- let maxChild = (right(node) < this.size() && this._greater(right(node), left(node))) ? right(node) : left(node);
- this._swap(node, maxChild);
- node = maxChild;
- }
- }
- }
- // collapse duplicate ranks together
- const counts = new Map<number, number>();
- for(const r of ranks) {
- if (!counts.has(r)) {
- counts.set(r, 0);
- }
- counts.set(r, counts.get(r) + 1);
- }
- const distinctRanks = Array.from(counts.keys()).map(i => i);
- const count = distinctRanks.map(i => 0);
- const nextCost = distinctRanks.map(i => i);
- const queue = new PriorityQueue((a,b) => nextCost[a] < nextCost[b]);
- for(let i=0; i<nextCost.length; i++) {
- queue.push(i);
- }
- let lastCost = 0;
- while(cars > 0) {
- const ix = queue.pop();
- lastCost = nextCost[ix];
- count[ix]++;
- nextCost[ix] = distinctRanks[ix] * (count[ix]+1) * (count[ix]+1);
- let ixCount = counts.get(distinctRanks[ix]);
- //console.log(`${ix}: ${ixCount} * ${distinctRanks[ix]} given car ${count[ix]} at total cost ${lastCost}`);
- while(cars > 0 && ixCount > 0) {
- cars--;
- ixCount--;
- }
- queue.push(ix);
- }
- return lastCost;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement