skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER

    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.


  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search