Task: divide the sum of 70 into 8 terms randomly, the minimum term: 6, maximum: 15. It is necessary that none of the terms should be below the minimum and not above the maximum. We get the following terms: 10, 6, 7, 15, 7, 9, 10, 6. There is a code:

function splitSum($sum, $count, $minPrice, $maxPrice) { $prices = array(); if($sum > $count * $maxPrice || $sum < $count) throw new \Exception('Wrong sum for split'); $j = 0; for($i = $count - 1; $i > 0; $i--) { $diff = $sum - $i * $maxPrice; if($diff > 0) $prices[$j] = rand($minPrice, $maxPrice); else { if($sum - $i * 1 > $maxPrice) $max = $maxPrice; elseif($sum - $i * 1 <= 0) $max = $sum; else $max = $sum - $i * 1; $prices[$j] = rand($minPrice, $max); } if($i > 1) $sum -= $prices[$j]; $j++; } $prices[$j] = $sum - $prices[$j - 1]; return $prices; } 

The function selects the terms, but the minimum limit is not met.

  • if($sum > $count * $maxPrice || $sum < $count) forgot to multiply by $minPrice and inside the loop instead of checking $diff = $sum - $i * $maxPrice; if($diff > 0) $diff = $sum - $i * $maxPrice; if($diff > 0) apparently should do a check if($sum > $i * $maxPrice || $sum < $i * $minPrice) and regenerate the term in the case of true . - Visman
  • @Visman, helped replace the multiplier by $ minPrice and check - chaot1c

1 answer 1

Work code:

 function splitSum($sum, $count, $minPrice, $maxPrice) { $prices = array(); if($sum > ($count * $maxPrice) || $sum < $count || $sum < ($count * $minPrice)) throw new \Exception('Wrong sum for split'); $j = 0; for($i = $count - 1; $i > 0; $i--) { $diff = $sum - $i * $maxPrice; if($diff > 0) $prices[$j] = rand($minPrice, $maxPrice); else { if(($sum - ($i * $minPrice)) > $maxPrice) $max = $maxPrice; elseif(($sum - ($i * $minPrice)) <= 0) $max = $sum; else $max = $sum - ($i * $minPrice); $prices[$j] = rand($minPrice, $max); } if($i > 1) $sum -= $prices[$j]; $j++; } $prices[$j] = $sum - $prices[$j - 1]; return $prices; }