Finding smallest sum after making transformations in JavaScript

We need to write a JavaScript function that takes an array of positive integers and applies transformations until no more are possible. The transformation rule is: if arr[i] > arr[j], then arr[i] = arr[i] - arr[j]. After all transformations, we return the sum of the array.

Problem

The key insight is that this transformation process eventually reduces all numbers to their Greatest Common Divisor (GCD). When we repeatedly subtract smaller numbers from larger ones, we're essentially performing the Euclidean algorithm.

if arr[i] > arr[j] then arr[i] = arr[i] - arr[j]

How It Works

The algorithm works by:

  • Sorting the array to find the largest and smallest elements
  • Subtracting the smallest from the largest
  • Repeating until all elements are equal (which will be their GCD)
  • Returning the sum of the final array

Example

const arr = [6, 9, 21];

const smallestSum = (arr = []) => {
    const equalNums = arr => arr.reduce((a, b) => {
        return (a === b) ? a : NaN;
    });
    
    if(equalNums(arr)){
        return arr.reduce((a, b) => {
            return a + b;
        });
    } else {
        const sorted = arr.sort((a, b) => {
            return a - b;
        });
        const last = sorted[arr.length-1] - sorted[0];
        sorted.pop();
        sorted.push(last);
        return smallestSum(sorted);
    }
};

console.log(smallestSum(arr));
9

Step-by-Step Transformation

Let's trace through the example [6, 9, 21]:

const traceTransformations = (arr) => {
    console.log("Initial array:", arr);
    let step = 1;
    
    const transform = (currentArr) => {
        const equalNums = currentArr => currentArr.reduce((a, b) => {
            return (a === b) ? a : NaN;
        });
        
        if(equalNums(currentArr)){
            console.log(`Final array: [${currentArr.join(', ')}]`);
            return currentArr.reduce((a, b) => a + b);
        } else {
            const sorted = [...currentArr].sort((a, b) => a - b);
            const last = sorted[sorted.length-1] - sorted[0];
            sorted.pop();
            sorted.push(last);
            console.log(`Step ${step++}: [${sorted.join(', ')}]`);
            return transform(sorted);
        }
    };
    
    return transform(arr);
};

const result = traceTransformations([6, 9, 21]);
console.log("Sum:", result);
Initial array: [ 6, 9, 21 ]
Step 1: [ 6, 9, 15 ]
Step 2: [ 6, 9, 9 ]
Step 3: [ 6, 3, 9 ]
Step 4: [ 3, 3, 9 ]
Step 5: [ 3, 3, 6 ]
Step 6: [ 3, 3, 3 ]
Final array: [3, 3, 3]
Sum: 9

Optimized Approach Using GCD

Since the final result is always the GCD of all numbers multiplied by array length, we can optimize:

const gcd = (a, b) => {
    return b === 0 ? a : gcd(b, a % b);
};

const findGCDOfArray = (arr) => {
    return arr.reduce((result, current) => gcd(result, current));
};

const optimizedSmallestSum = (arr) => {
    const arrayGCD = findGCDOfArray(arr);
    return arrayGCD * arr.length;
};

// Test with the same example
console.log(optimizedSmallestSum([6, 9, 21])); // 9
console.log(optimizedSmallestSum([4, 6, 8]));  // 6
console.log(optimizedSmallestSum([12, 18]));   // 12
9
6
12

Comparison

Approach Time Complexity Space Complexity Readability
Recursive Transformation O(n² × log(max)) O(n) Shows the process
GCD Calculation O(n × log(max)) O(1) More efficient

Conclusion

The transformation process essentially finds the GCD of all array elements. The optimized GCD approach is more efficient than simulating the actual transformations, especially for large arrays or numbers.

Updated on: 2026-03-15T23:19:00+05:30

210 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements