Using operations to produce desired results in JavaScript

We are required to write a JavaScript function that takes in an array of exactly 4 numbers, arr, as the first argument and a target as the second argument.

Our function needs to determine whether the numbers in the array arr can be operated through *, /, +, -, (, ) to get a value equal to the target.

Problem Example

For example, if the input to the function is:

Input

const arr = [5, 3, 2, 1];
const target = 4;

Output

true

Output Explanation

Because we can achieve 4 like this:

(5 - 1) * (3 - 2) = 4

Algorithm Approach

The solution uses a recursive approach that tries all possible combinations of operations between pairs of numbers. For each pair, it applies all six operations (+, -, *, /, and division in reverse order) and continues recursively with the remaining numbers plus the result.

Implementation

const arr = [5, 3, 2, 1];
const target = 4;

const canOperate = (arr = [], target = 1) => {
    const isValid = x => Math.abs(x - target)  {
        if (arr.length === 1) {
            return isValid(arr[0])
        }
        let valid = false
        for (let i = 0; i  index !== i && index !== j)
                valid = valid || helper([...nextArr, arr[i] + arr[j]])
                || helper([...nextArr, arr[i] - arr[j]])
                || helper([...nextArr, arr[j] - arr[i]])
                || helper([...nextArr, arr[i] * arr[j]])
                || helper([...nextArr, arr[i] / arr[j]])
                || helper([...nextArr, arr[j] / arr[i]])
            }
        }
        return valid
    }
    return helper(arr)
}

console.log(canOperate(arr, target));
true

How It Works

The algorithm works by:

  1. Base Case: When only one number remains, check if it equals the target (within floating-point precision)
  2. Recursive Case: For each pair of numbers, try all six operations and recursively check the resulting smaller array
  3. Floating-Point Precision: Uses a small epsilon (0.0000001) to handle floating-point arithmetic precision issues
  4. Early Exit: Returns true as soon as any valid combination is found

Testing with Different Examples

// Test case 1: Simple addition
console.log(canOperate([1, 1, 1, 1], 4)); // true: 1+1+1+1=4

// Test case 2: Complex operations needed
console.log(canOperate([1, 2, 3, 4], 24)); // true: (1+2+3)*4=24 or other combinations

// Test case 3: Impossible target
console.log(canOperate([1, 1, 1, 1], 10)); // false: cannot reach 10
true
true
false

Key Points

  • The algorithm explores all possible ways to combine four numbers using basic arithmetic operations
  • It handles division carefully by trying both directions (a/b and b/a)
  • Uses floating-point comparison with epsilon to avoid precision errors
  • Time complexity is exponential, but acceptable for exactly 4 numbers

Conclusion

This recursive solution efficiently determines if four numbers can be combined using basic arithmetic operations to reach a target value. The algorithm systematically explores all possible combinations and handles floating-point precision issues appropriately.

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

153 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements