hope all of you are doing ok. I'm having a problem with this, because I'm looking for a way to get all the combinations of an array of numbers, but I want to do it without any function, I don't think that's possible, all the answers I already saw on internet have some function or method to do that.
I try this, give this array:
$numbers=[1,2,3,4];
I built 4 for loops to take the position of the array, and create a number, but, it supposes to be 24 different combinations give that array, with my for loops I get 256 combination
for($i = 0; $i <= 3; $i ){
for($j = 0; $j <= 3;$j ){
for($k = 0;$k <= 3;$k ){
for($l = 0; $l <= 3;$l ){
echo "$numbers[$i]$numbers[$j]$numbers[$k]$numbers[$l] <br>";
}
}
}
}
>echo "Combinations: $contador \n";
Could someone please help me! (I want to get the combination on a new array per value, to compare later with a random number)
CodePudding user response:
Getting all combinations works on the principle of next permutation. This basically means it follows the below steps:
The input needs to be sorted as the starting combination. This eases out the calculations and produces a uniform result. Below snippet does use
sort()
inbuilt function but you can roll out for your own sort function(which I leave it to you as an exercise).For a next permutation, we need to find 2 digits where smaller digit occupies an MSB place over the larger digit.
Once found, we swap those 2 digits and reverse the array from MSB 1 position. This reverse operation is to get next smallest lexicographic combination. If not performed, you will miss out on some needed in-between combinations.
The logic stops when the digits get sorted in non-increasing manner yielding the last combination possible.
Snippet:
<?php
function getCombinations($numbers){
sort($numbers); // create your own custom function for sort.
$result = [ $numbers ];
do{
$x = $y = -1;
for($i = count($numbers) - 1; $i >= 0; --$i){
for($j = $i - 1; $j >= 0; --$j){
if($numbers[ $j ] < $numbers[ $i ] && ($y === -1 || $y < $j)){
$x = $i;
$y = $j;
}
}
}
if($x !== -1){
swap($numbers, $x, $y);
reverse($numbers, $y 1, count($numbers) - 1);
$result[] = $numbers;
}
}while($x != -1);
return $result;
}
function reverse(&$numbers, $left, $right){
while($left < $right){
swap($numbers, $left , $right--);
}
}
function swap(&$numbers, $x, $y){
$temp = $numbers[ $x ];
$numbers[ $x ] = $numbers[ $y ];
$numbers[ $y ] = $temp;
}
print_r(getCombinations([1,2,3,4]));
CodePudding user response:
24 is the number of unique combinations - like this
for($i = 0; $i <= 3; $i ){
for($j = 1; $j <= 3;$j ){
for($k = 2;$k <= 3;$k ){
for($l = 3; $l <= 3;$l ){
echo "$numbers[$i]$numbers[$j]$numbers[$k]$numbers[$l] <br>";
}
}
}
}
each digit can only appear once in each string