Divide value with random numbers

Asked

Viewed 118 times

2

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

ex: if I receive the number 100, it could generate 20,30,10,20, 5, 15 = 100

the problem is that my code is wrong, the program hangs, 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";
}
  • could generate 20,30,10,20, 5,15, but is not in parts not equal? the 20 is repeated. And in how many parts would be?

  • it doesn’t have to be exactly different, I think I expressed myself badly, because if it’s all the same I could divide by a number, but it has to have a little randomness, about the amount of 1-12 at most. and the numbers need to be integer.

3 answers

2


Simple alternative to suit your comment

it doesn’t have to be exactly different, I think I expressed myself badly, because if it’s all the same I could divide by a number, but it has to have a little randomness, about the amount of 1-12 at most. and the numbers need to be integer.

ex: if I receive 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

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.

Your code problem boils down to:

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

Let’s assume that $val = 100. So $tmp can be from 1 to 100, say 50. In the next run it can be again from 1 to 100, say 80. Then your $tmp + $total comparison will fail, because after all we have 80+50 > 100. When it fails it will make an infinite loop.

To fix this you have to force the run 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";
}

Anyway I see no point in using this function, you can just make use of the random_int, which is even safer.

1

I 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;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.