Home > Enterprise >  PHP : Find list of X possible values which sum gives Y number
PHP : Find list of X possible values which sum gives Y number

Time:01-12

I want to solve a problem but I don't know how to proceed.

In fact, I want to create the following function:

<?php

function xSumY(int $x, int $y)
{
  $set = [];
   
  //find $set {$a   $b   $c   ... ($x times)} which sum equal $y
}

//Examples 
$set1 = xSumY(55, 1);
$set2 = xSumY(1, 20);
$set3 = xSumY(3, 10); //returns for example {1, 3, 6}

NOTE: If possible avoid repetition of given value

Thanks in advance for your help.

CodePudding user response:

I don't understand the need for all that code you used in your answer. I made this in five minutes:

function xSumY(int $x, int $y)
{
    if ($y < $x) die("xSumY(): Invalid input, y < x.");
    $r = array_fill(1, $x, 1);
    for ($i = 1; $i <= $y - $x; $i  ) {
        $r[random_int(1, $x)]  ; 
    }
    return $r;
}

and it seems to do the job.

CodePudding user response:

After several hours I got something like this:

static function xSumY(int $x, int $y)
    {
        $setOf = []; //Will contain sum subset
        $roundTo = strlen($x); //Will help to round values

        if($x < 1 || $y < 1): //return empty array if null or negative values
            return $setOf;
        elseif($x == $y): //fill with same value if $x = $y
            $setOf = array_fill(0, $x, ($x/$y));
            return $setOf;
        endif;

        $maxRand = round($y/$x, $roundTo); //we are going to find a value between 0 and this
        $multiplicator = pow((1 * 10), $roundTo 1);
        $max = $maxRand * $multiplicator;
        
        for($i=1; $i <= $x; $i  ): //this loop help to create our set
            if(count($setOf)   1 == $x):
                $currentElement = round(($y - array_sum($setOf)), $roundTo); //the last value of the set
            else:
                $currentElement = round(mt_rand(1, $max) / $multiplicator);
            endif;

            array_push($setOf, $currentElement); //add values to our set

        endfor;
        shuffle($setOf); //Make our set look more real

        while(round((min($setOf) / max($setOf)) * 100) < 20): //Reduce the difference & avoid zero
            $maxSet = max($setOf);
            $maxIndex = array_search(max($setOf), $setOf);

            $minSet = min($setOf);
            $minIndex = array_search(min($setOf), $setOf);
    
            $falsAverage = $maxSet   $minSet;
            $newMin = round((mt_rand(2, 4) / 10) * $falsAverage);
            $newMax = $falsAverage - $newMin;
            
            $setOf[$maxIndex] = $newMax;
            $setOf[$minIndex] = $newMin;
        endwhile;

        return $setOf; //Our set ready for use
    }

I want to know if it's good or I'm missing something or if there is a way I can dot it better. Also, I wanted to know if this operation will not excessively consume the memory.

  • Related