0

I'm having a problem in PHP, I want to get all possible combinations or distributions to add to some values, for example:

$unities = 3;
$array = [ 1, 2, 3 , 4]

What I want to do is get every possibility to add that unities to the numbers in the array, like a loop that makes:

3 0 0 0
0 3 0 0
0 0 3 0
0 0 0 3
2 1 0 0
2 0 1 0
2 0 0 1
.......
.......
Continue
.......
.......

And add that to the array, so the result must be:

4 2 3 4
1 5 3 4
1 2 6 4
1 2 3 7
3 3 3 4
3 2 4 4
3 2 3 5
.......
.......
Continue
.......

I hope is well explained and you can help me.

Thanks a lot.

pjs
  • 18,696
  • 4
  • 27
  • 56
Viturbiko
  • 15
  • 3

2 Answers2

1

If it's a fixed number then you can simply use nested for loops and an if statement to check that the sum is correct?

$array = [1,2,3,4];
$unities = 3;

for ($a = 0; $a <= $unities; $a++)
    for ($b = 0; $b <= $unities; $b++)
        for ($c = 0; $c <= $unities; $c++)
            for ($d = 0; $d <= $unities; $d++)
                if ($a + $b + $c + $d === $unities)
                    $output[] = [$a + $array[0], $b + $array[1], $c + $array[2], $d + $array[3]];

print_r($output);

Recursive Version

$array = [1,2,3,4];
$unities = 3;


function getPossibilities($target, $array, &$output, $arr = [])
{
    for ($i = 0; $i <= $target; $i++) {
        $currentArr = array_merge($arr, [$i]);
        if (count($array) === count($currentArr)) {
            if (array_sum($currentArr) === $target) {
                $tempOutput = [];
                for ($x = 0; $x < count($array); $x++) {
                    $tempOutput[] = $array[$x] + $currentArr[$x];
                }
                $output[] = $tempOutput;
            }
        } else {
            getPossibilities($target, $array, $output, $currentArr);
        }
    }
}

getPossibilities($unities, $array, $output);

print_r($output);
Steven
  • 6,053
  • 2
  • 16
  • 28
0

I got this function that returns the permutation of the array passed into it from this answer https://stackoverflow.com/a/13194803/15350139. From O'Reilly's "PHP Cookbook".

function pc_permute($items, $perms = [])
{
    if (empty($items)) {
        $return = [$perms];
    } else {
        $return = [];

        for ($i = count($items) - 1; $i >= 0; --$i) {
            $new_items = $items;
            $new_perms = $perms;

            list($foo) = array_splice($new_items, $i, 1);
            array_unshift($new_perms, $foo);

            $return = array_merge($return, pc_permute($new_items, $new_perms));
        }
    }

    return $return;
}

Then from the permutations of the required array, I use this add the $unities to each element

function decreasingDist($unities, $array)
{
    foreach ($array as $i => $num) $array[$i] += $num;
    return $array;
}

Then this will return the desired result

$unities = 3;
$array = [ 1, 2, 3 , 4];

decreasingDist($untities, pc_permute($array));
a.mola
  • 3,883
  • 7
  • 23