Divide value with random numbers

2

I have a value that I need to divide it into non-equal parts with several numbers.

eg, if I get the number 100, it could generate 20,30,10,20, 5, 15 = 100

The problem is that my code is wrong, the program hangs, it does not leave the number 2.

function separate($val) {
    if ($val == 1) {
        return "1";
    }
    $list = [];
    $total = 0;
    while (true) {
        $tmp = rand(1, $val);
        if ($tmp + $total == $val) {
            $list[] = $tmp;
            $total += $tmp;
            break;
        } else {
            $list[] = $tmp;
            $total += $tmp;
        }
    }
    return json_encode($list);
}

foreach (range(1, 500) as $m) { // gera ate 500 de prêmio
    print "{$m}\n";
    var_dump(separate($m));
    print "=======\n";
}
    
asked by anonymous 17.11.2018 / 17:27

3 answers

2

Simple alternative to answer your review

  

It does not have to be exactly different, I think I expressed it badly, because if it's all the same I could divide by a number, but it has to have a bit of randomness, on the amount of 1-12 at the most. and the numbers must be integers.

     

eg, if I get the number 100, it could generate 20,30,10,20, 5, 15 = 100

$numGrupos   = rand(1,12);
$soma               = 100;
$grupos             = array();
$grupo              = 0;

//array_sum() retorna a soma dos valores de um array.
while(array_sum($grupos) != $soma)
{
    $grupos[$grupo] = mt_rand(0, $soma/mt_rand(1,5));

    if(++$grupo == $numGrupos)
    {
        $grupo  = 0;
    }
}

$string = implode(',', $grupos);

Online Test

    
17.11.2018 / 18:30
1

The reason is because the loop is infinite, what you can do is simply subtract the value, until it reaches zero.

<?php

function separate($val) {
    if ($val == 1) {
        return "1";
    }

    $list = [];

    while ($val > 0) {
        $val -= ($rand = rand(1, $val));
        $list[] = $rand;    
    }

    return json_encode($list);
}

foreach (range(1, 500) as $m) { // gera ate 500 de prêmio
    print $m . "->" . separate($m);
    print "=======<br>";
}

Test here.

The problem with your code is:

while (true) {
      $tmp = rand(1, $val);
      if ($tmp + $total == $val) {

Let's suppose that $val = 100 . So the $ tmp could be from 1 to 100, say 50. On the next run it could be again from 1 to 100, for example 80. So your comparison of $ tmp + $ total will fail because then we have 80 + 50 > 100. When it fails it will loop an infinite loop.

To fix this you have to force the execute execution to be limited to 50 in the case of the previous example. Then you can use $tmp = rand(1, ($val - $total)); :

function separate($val) {
    if ($val == 1) {
        return "1";
    }
    $list = [];
    $total = 0;
    while (true) {
        $tmp = rand(1, ($val - $total); // Agora não tem como gerar um número  maior
        if ($tmp + $total == $val) {
            $list[] = $tmp;
            $total += $tmp;
            break;
        } else {
            $list[] = $tmp;
            $total += $tmp;
        }
    }
    return json_encode($list);
}

foreach (range(1, 500) as $m) { // gera ate 500 de prêmio
    print "{$m}\n";
    var_dump(separate($m));
    print "=======\n";
}

I do not see any sense in using this function, you can simply make use of random_int , which is even safer.

    
17.11.2018 / 17:58
1

Implemented in a simple way that can solve your problem:

<?php

$numeros = [];
$numeroAnalisado = 100;

$randomicoAuxiliar = $numeroAnalisado;

if($numeroAnalisado == 1) $numeros[] = 1;
else 
{
    for($randomicoAuxiliar = $numeroAnalisado; $randomicoAuxiliar >= 1;)
    {
        $valorRandomico = rand(1, $randomicoAuxiliar);
        $randomicoAuxiliar = $randomicoAuxiliar - $valorRandomico;
        $numeros[] = $valorRandomico;
    }

    foreach($numeros as $numero) 
    {
        echo $numero . "<br >";
    }
}

$soma = array_sum($numeros);
echo "<br />Soma: " . $soma;
    
17.11.2018 / 18:09