Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- export type Plate = {
- name: string;
- key: string;
- weight: number;
- count: number;
- selected?: boolean;
- };
- export let myPlates: Plate[] = [
- { key: '0.5', name: '0.5 kg', weight: 500, count: 2, selected: false },
- { key: '1', name: '1 kg', weight: 1000, count: 2, selected: false },
- { key: '1.5', name: '1.5 kg', weight: 1500, count: 2, selected: false },
- { key: '2', name: '2 kg', weight: 2000, count: 2, selected: false },
- { key: '2.5', name: '2.5 kg', weight: 2500, count: 2, selected: false },
- { key: '5', name: '5 kg', weight: 5000, count: 2, selected: false },
- { key: '10', name: '10 kg', weight: 10000, count: 2, selected: false },
- { key: '15', name: '15 kg', weight: 15000, count: 2, selected: false },
- { key: '20', name: '20 kg', weight: 20000, count: 2, selected: false },
- { key: '25', name: '25 kg', weight: 25000, count: 2, selected: false }
- ];
- export class Barbell {
- barWeight: number = 20000;
- availablePlates = new Map<string, Plate>();
- savedWeight: string[][] = [];
- lastSolution: number[] = [];
- constructor(plates: Plate[]) {
- plates.forEach(plate => {
- this.availablePlates.set(plate.key, plate);
- });
- }
- // implement the right solution
- calculate(targetWeight: number): number[] {
- this.savedWeight = [];
- // [] = initial state of the rod, in later calls it will contain weights e.g. ['10', '10']
- //
- // -1/9999999999999999 = latest used weight
- this.getNext(targetWeight - this.barWeight, [], this.availablePlates, -1);
- if (this.savedWeight.length > 0) {
- let result: number[] = [];
- // lets return the first configuration [0]
- for (const weight of this.savedWeight[0]) {
- const p: Plate = this.availablePlates.get(weight) as Plate;
- result.push(p.weight);
- }
- return result;
- }
- // if no solution was found
- return [];
- }
- getNext(
- targetWeight: number,
- current: string[],
- available: Map<string, Plate>,
- latestWeight: number
- ) {
- let currentWeight = 0;
- for (const key of current) {
- // @ts-ignore
- currentWeight += this.availablePlates.get(key).weight;
- }
- // ^- calculate current weight of the rod
- if (targetWeight <= currentWeight) {
- if (targetWeight === currentWeight) {
- // exact weight on the rod
- // DEBUG PRINT console.log("exact:", current, currentWeight);
- // save the configuration
- this.savedWeight.push(current);
- } else {
- // too much weight on the rod, over required amount
- }
- return;
- }
- // available = [ 10, 10, 20, 20, 20 ] => [10, 20] if latestWeight = 15 => [10], if 20 => [10, 20]
- let newKeys = this.getAvailableWeightsBounded(available, latestWeight);
- // there are no new weights available, we used all or there are ones that are heavier than the latest one
- if (newKeys.length == 0) {
- return;
- }
- // backtracking engine
- // trial error for all new possible rods
- for (const newKey of newKeys) {
- let clonedMap: Map<string, Plate> = new Map<string, Plate>(available);
- let newCurrent: string[] = [];
- // ^because typescript
- for (const n of current) {
- newCurrent.push(n);
- }
- newCurrent.push(newKey);
- newCurrent.push(newKey);
- // ^2x weight on left and right
- // @ts-ignore
- let p = clonedMap.get(newKey.toString()) as Plate;
- let pp = {
- key: p.key,
- name: p.name,
- weight: p.weight,
- count: p.count - 2,
- selected: p.selected
- };
- // ^ decrease available weights by 2
- clonedMap.set(newKey.toString(), pp);
- // backtracking recursive call
- this.getNext(targetWeight, newCurrent, clonedMap, p.weight);
- }
- }
- getAvailableWeightsBounded(
- available: Map<string, Plate>,
- maxWeight: number
- ): string[] {
- let keys = Array.from(available.keys());
- let keysDesc = keys.sort((one, two) => (+one > +two ? -1 : 1));
- let result: string[] = [];
- // prettier-ignore
- for (const key of keysDesc) {
- // @ts-ignore
- if (available.get(key).count >= 2 && (available.get(key).weight <= maxWeight || maxWeight == -1)) {
- result.push(key);
- }
- }
- return result;
- }
- }
- // let b = new Barbell(myPlates);
- // console.log('Solution (if not empty array):');
- // console.log(b.calculate(40000));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement