Advertisement
Guest User

Untitled

a guest
Nov 13th, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.40 KB | None | 0 0
  1. export type Plate = {
  2. name: string;
  3. key: string;
  4. weight: number;
  5. count: number;
  6. selected?: boolean;
  7. };
  8.  
  9. export let myPlates: Plate[] = [
  10. { key: '0.5', name: '0.5 kg', weight: 500, count: 2, selected: false },
  11. { key: '1', name: '1 kg', weight: 1000, count: 2, selected: false },
  12. { key: '1.5', name: '1.5 kg', weight: 1500, count: 2, selected: false },
  13. { key: '2', name: '2 kg', weight: 2000, count: 2, selected: false },
  14. { key: '2.5', name: '2.5 kg', weight: 2500, count: 2, selected: false },
  15. { key: '5', name: '5 kg', weight: 5000, count: 2, selected: false },
  16. { key: '10', name: '10 kg', weight: 10000, count: 2, selected: false },
  17. { key: '15', name: '15 kg', weight: 15000, count: 2, selected: false },
  18. { key: '20', name: '20 kg', weight: 20000, count: 2, selected: false },
  19. { key: '25', name: '25 kg', weight: 25000, count: 2, selected: false }
  20. ];
  21.  
  22. export class Barbell {
  23. barWeight: number = 20000;
  24. availablePlates = new Map<string, Plate>();
  25. savedWeight: string[][] = [];
  26. lastSolution: number[] = [];
  27. constructor(plates: Plate[]) {
  28. plates.forEach(plate => {
  29. this.availablePlates.set(plate.key, plate);
  30. });
  31. }
  32.  
  33. // implement the right solution
  34. calculate(targetWeight: number): number[] {
  35. this.savedWeight = [];
  36.  
  37. // [] = initial state of the rod, in later calls it will contain weights e.g. ['10', '10']
  38. //
  39. // -1/9999999999999999 = latest used weight
  40. this.getNext(targetWeight - this.barWeight, [], this.availablePlates, -1);
  41.  
  42. if (this.savedWeight.length > 0) {
  43. let result: number[] = [];
  44.  
  45. // lets return the first configuration [0]
  46. for (const weight of this.savedWeight[0]) {
  47. const p: Plate = this.availablePlates.get(weight) as Plate;
  48. result.push(p.weight);
  49. }
  50.  
  51. return result;
  52. }
  53.  
  54. // if no solution was found
  55. return [];
  56. }
  57.  
  58. getNext(
  59. targetWeight: number,
  60. current: string[],
  61. available: Map<string, Plate>,
  62. latestWeight: number
  63. ) {
  64. let currentWeight = 0;
  65.  
  66. for (const key of current) {
  67. // @ts-ignore
  68. currentWeight += this.availablePlates.get(key).weight;
  69. }
  70. // ^- calculate current weight of the rod
  71.  
  72. if (targetWeight <= currentWeight) {
  73. if (targetWeight === currentWeight) {
  74. // exact weight on the rod
  75. // DEBUG PRINT console.log("exact:", current, currentWeight);
  76. // save the configuration
  77. this.savedWeight.push(current);
  78. } else {
  79. // too much weight on the rod, over required amount
  80. }
  81. return;
  82. }
  83.  
  84. // available = [ 10, 10, 20, 20, 20 ] => [10, 20] if latestWeight = 15 => [10], if 20 => [10, 20]
  85. let newKeys = this.getAvailableWeightsBounded(available, latestWeight);
  86.  
  87. // there are no new weights available, we used all or there are ones that are heavier than the latest one
  88.  
  89. if (newKeys.length == 0) {
  90. return;
  91. }
  92.  
  93. // backtracking engine
  94. // trial error for all new possible rods
  95. for (const newKey of newKeys) {
  96. let clonedMap: Map<string, Plate> = new Map<string, Plate>(available);
  97. let newCurrent: string[] = [];
  98. // ^because typescript
  99. for (const n of current) {
  100. newCurrent.push(n);
  101. }
  102. newCurrent.push(newKey);
  103. newCurrent.push(newKey);
  104. // ^2x weight on left and right
  105. // @ts-ignore
  106. let p = clonedMap.get(newKey.toString()) as Plate;
  107. let pp = {
  108. key: p.key,
  109. name: p.name,
  110. weight: p.weight,
  111. count: p.count - 2,
  112. selected: p.selected
  113. };
  114. // ^ decrease available weights by 2
  115. clonedMap.set(newKey.toString(), pp);
  116. // backtracking recursive call
  117. this.getNext(targetWeight, newCurrent, clonedMap, p.weight);
  118. }
  119. }
  120.  
  121. getAvailableWeightsBounded(
  122. available: Map<string, Plate>,
  123. maxWeight: number
  124. ): string[] {
  125. let keys = Array.from(available.keys());
  126. let keysDesc = keys.sort((one, two) => (+one > +two ? -1 : 1));
  127. let result: string[] = [];
  128.  
  129. // prettier-ignore
  130. for (const key of keysDesc) {
  131. // @ts-ignore
  132. if (available.get(key).count >= 2 && (available.get(key).weight <= maxWeight || maxWeight == -1)) {
  133. result.push(key);
  134. }
  135. }
  136.  
  137. return result;
  138. }
  139. }
  140.  
  141. // let b = new Barbell(myPlates);
  142. // console.log('Solution (if not empty array):');
  143. // console.log(b.calculate(40000));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement