64 lines
1.5 KiB
TypeScript
64 lines
1.5 KiB
TypeScript
// idea: do not ever sort
|
|
// simply keep looping from left to right and back to left
|
|
// whenever a smaller number is found,
|
|
// subtract as many multiples of that number from the rest of the array
|
|
|
|
const subtractMultiples = (a: number, b: number): number => {
|
|
// subtract a from b as many times as possible
|
|
const mod = b % a;
|
|
if (mod === 0) {
|
|
// figure out how many times a can be subtracted from b
|
|
const div = b / a - 1;
|
|
return b - a * div;
|
|
} else {
|
|
return mod;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Does a single operation on the given array.
|
|
* Keeps the array sorted.
|
|
* @returns True if the array is all the same, false otherwise.
|
|
*/
|
|
const operate = (arr: number[]): boolean => {
|
|
|
|
let step = 1;
|
|
let i = 0;
|
|
let done = false;
|
|
let hasChangedDuringLoop = false;
|
|
while (!done) {
|
|
if (i + step >= arr.length || i + step < 0) {
|
|
// reverse direction
|
|
step = -step;
|
|
if (!hasChangedDuringLoop) {
|
|
done = true;
|
|
}
|
|
hasChangedDuringLoop = false;
|
|
}
|
|
|
|
const first = arr[i];
|
|
const next = arr[i + step];
|
|
|
|
if (first > next) {
|
|
arr[i] = subtractMultiples(next, first);
|
|
hasChangedDuringLoop = true;
|
|
} else if (first < next) {
|
|
arr[i + step] = subtractMultiples(first, next);
|
|
hasChangedDuringLoop = true;
|
|
}
|
|
|
|
i += step;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
export function solution(numbers: number[]): number {
|
|
let done = false;
|
|
while (!done) {
|
|
done = operate(numbers);
|
|
}
|
|
|
|
// sum the numbers
|
|
return numbers.reduce((acc, num) => acc + num, 0);
|
|
} |