2

This code gives me every possible combination of n values with a length of x, to have a sum of n.

function GETall_distri_pres($n_valeurs, $x_entrees, $combi_presences = array()) {
    if ($n_valeurs == 1) { 
        $combi_presences[] = $x_entrees;
        return array($combi_presences);
    }

    $combinaisons = array();

    // $tiroir est le nombre de chaussettes dans le tiroir suivant
    for ($tiroir = 0; $tiroir <= $x_entrees; $tiroir++) {
        $combinaisons = array_merge($combinaisons, GETall_distri_pres(
            $n_valeurs - 1,
            $x_entrees - $tiroir,
            array_merge($combi_presences, array($tiroir))));
    }
    return $combinaisons;
}

I need to generate only unique distributions for example not having [2,1,1,0] and [1,2,1,0], only [2,1,1,0].

var_dump(GETall_distri_pres(3,3)) will give :

array (size=10)
  0 => 
    array (size=3)
      0 => int 0
      1 => int 0
      2 => int 3
  1 => 
    array (size=3)
      0 => int 0
      1 => int 1
      2 => int 2
  2 => 
    array (size=3)
      0 => int 0
      1 => int 2
      2 => int 1
  3 => 
    array (size=3)
      0 => int 0
      1 => int 3
      2 => int 0
  4 => 
    array (size=3)
      0 => int 1
      1 => int 0
      2 => int 2
  5 => 
    array (size=3)
      0 => int 1
      1 => int 1
      2 => int 1
  6 => 
    array (size=3)
      0 => int 1
      1 => int 2
      2 => int 0
  7 => 
    array (size=3)
      0 => int 2
      1 => int 0
      2 => int 1
  8 => 
    array (size=3)
      0 => int 2
      1 => int 1
      2 => int 0
  9 => 
    array (size=3)
      0 => int 3
      1 => int 0
      2 => int 0

Do you have any ideas?

2
  • Can you give an example of the inputs? Commented Dec 23, 2020 at 10:26
  • I just added an example, thank you. Commented Dec 23, 2020 at 10:35

1 Answer 1

2

This would be an approach: before returning the computed set you filter them by creating a fresh associative array, using the normalized permutations as keys. That will result in permutations overwriting themselves, so that only one will get preserved:

<?php

function GETall_distri_pres($n_valeurs, $x_entrees, $combi_presences = array()) {
    if ($n_valeurs == 1) { 
        $combi_presences[] = $x_entrees;
        return array($combi_presences);
    }

    $combinaisons = array();

    // $tiroir est le nombre de chaussettes dans le tiroir suivant
    for ($tiroir = 0; $tiroir <= $x_entrees; $tiroir++) {
        $combinaisons = array_merge($combinaisons, GETall_distri_pres(
            $n_valeurs - 1,
            $x_entrees - $tiroir,
            array_merge($combi_presences, array($tiroir))));
    }
    
    // filter out permutations
    $filteredCombinations = [];
    array_walk($combinaisons, function($entry) use(&$filteredCombinations) {
        arsort($entry);
        $filteredCombinations[join('', $entry)] = $entry;
    });
    return array_values($filteredCombinations);
}

$result = GETall_distri_pres(3, 3);

print_r($result);

The output obviously is:

Array
(
    [0] => Array
        (
            [0] => 3
            [1] => 0
            [2] => 0
        )

    [1] => Array
        (
            [0] => 2
            [1] => 1
            [2] => 0
        )

    [2] => Array
        (
            [0] => 1
            [1] => 1
            [2] => 1
        )

)
Sign up to request clarification or add additional context in comments.

2 Comments

You're the boss it works thank you!That being done, don't you think there would be a function which could generate without having to filter ?
Certainly possible, you'd just have to take care not to just merge the functions numerical result arrays, but return an associative array along the same strategy as I implemented in the filter passage. And another details you might want to think about: recursive algorithms as you implemented one here are not exactly efficient. Maybe you want to think about implementing a solution with scales in a linear manner instead?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.