Code Challenge - More array methods

Code Challenge - More array methods

We have another array based challenge, which we will solve in PHP, so lets get started.

The Problem

Given an array of integers, return a new array such that each element at index i of the new array is the product of all the numbers in the original array except the one at i. For example, if our input was [1, 2, 3, 4, 5], the expected output would be [120, 60, 40, 30, 24]. If our input was [3, 2, 1], the expected output would be [2, 3, 6].
- dailycodingproblem.com

Testing

My first step is always to write tests using the provided examples, so this is where we will begin. We will write a simple test script without using any frameworks.

function test() {
    $testData = [
        ['input'=>[1, 2, 3, 4, 5], 'expected'=>[120, 60, 40, 30, 24]],
        ['input'=>[3, 2, 1], 'expected' => [2, 3, 6]],
    ];

    foreach($testData as $test) {
        echo product($test['input']) == $test['expected'] ? 'PASS'.PHP_EOL : 'FAIL'.PHP_EOL;
    }
}

My Solution

There are many ways to solve this issue, but I am a big fan of using standard inbuilt PHP methods/functions where possible.

Here is my solution, I will explain it after the code.

function product(array $array) {
    return array_map(fn($v) => array_product($array) / $v, $array);
}

That's it, a short and simple method.

We iterate through the given array using the array_map() function. What this does is pass each value in the given array through a closure and return a new array as a result. Within the closure we simply use array_product() to find the product of the array, and then divide it by the current array value. This has the effect of getting the product of all array values excluding the current value.

Complete Code

<?php

// The solution
function product(array $array) {
    return array_map(fn($v) => array_product($array) / $v, $array);
}

// The test method
function test() {
    $testData = [
        ['input'=>[1, 2, 3, 4, 5], 'expected'=>[120, 60, 40, 30, 24]],
        ['input'=>[3, 2, 1], 'expected' => [2, 3, 6]],
    ];

    foreach($testData as $test) {
        echo product($test['input']) == $test['expected'] ? 'PASS'.PHP_EOL : 'FAIL'.PHP_EOL;
    }
}

// Run the tests
test();

Conclusion

We have manged to solve the issue with a clean single line method. If we are really looking at effeciency, we could calculate the array product once, then iterate through the array and do the division for each value.