jeudi 13 février 2020

JavaScript : Random numbers (float) between 2 values that sums up to N

I want to generate random numbers between 2 values that sums up to N.

What I've done so far :

function randomNumbers() {

    let i, nb, min, max, totAtteindre, tot, ajout;

    let resultat = new (Array);
    let alea        = [];

    nb              = document.getElementById("nbjours").value;
    totAtteindre    = document.getElementById("total").value;
    min             = Math.ceil(document.getElementById("minimum").value);
    max             = Math.floor(document.getElementById("maximum").value);


    tot = 0;

    for (i = 0; i < nb ; i++)
    {
        alea[i] = Math.random() * (max - min) + min;
        alea[i] = alea[i].toFixed(2);
        alea[i] = parseFloat(alea[i]);
        tot += alea[i];

    }

    tot = parseFloat(tot);

    if (totAtteindre > tot)
    {
        ajout = (totAtteindre - tot) / nb;
        ajout = ajout.toFixed(2);
        ajout = parseFloat(ajout);

        for (i = 0; i < nb ; i++)
        {
            alea[i] += ajout;
            tot += ajout;
        }

    }
    else
    {
        ajout = (tot - totAtteindre) / nb ;
        ajout = ajout.toFixed(2);
        ajout = parseFloat(ajout);

        for (i = 0; i < nb ; i++)
        {
            alea[i] -= ajout;
            tot -= ajout;
        }

    }

    let tmp = totAtteindre - tot;
    tot += tmp;

    alea[0] += tmp;

    // Affichage en vert ou rouge pour les valeurs positives ou négatives
    for (i = 0; i < nb ; i++)
    {
        if ((alea[i] > min) && (alea[i] < max))
        {
            resultat += alea[i].toFixed(2).replace('.', ',').fontcolor("green");
            if (i < nb-1)
            {
                resultat += "<br>";
            }
        }
        else
        {
            resultat += alea[i].toFixed(2).replace('.', ',').fontcolor("red");
            if (i < nb-1)
            {
                resultat += "<br>";
            }
        }
    }

    document.getElementById("valeurs").innerHTML = resultat;
    document.getElementById("totalAp").innerHTML = tot.toFixed(2);
}
<body>
<main>

    <header>
        <h1 style="font-size: 40px; text-align: center; margin: 20px; border: solid 2px black; font-family: 'Big Caslon'"><strong>Générateur de valeurs aléatoires</strong></h1>
    </header>

    <section>
    <form style="display: block; margin: 20px; text-align: center;">
        <h1 style="margin-bottom: 50px; font-family: 'Big Caslon';" ><u>Veuillez saisir le nombre de valeurs, les bornes inférieures/supérieures approximatives et le montant à atteindre</u><br></h1>

        <fieldset>
            <legend><strong>Nombre de valeurs</strong></legend>
            <input id="nbjours" type="number" name ="nbj">
        </fieldset>

        <br>

        <fieldset>
            <legend><strong>Bornes journalières approximatives</strong></legend>
            <input id="minimum" type="number" name="mont1">
            <input id="maximum" type="number" name="mont2">
            <div class="help-tip">
                <p style="text-align: justify; font-size: smaller">Il est possible d'avoir un résultat dont les valeurs dépassent les bornes. <br>Dans ce cas-là, diminuez les bornes ou augmentez les.</p>
            </div>
        </fieldset>

        <br>

        <fieldset>
            <legend><strong>Montant à atteindre</strong></legend>
            <input id="total" type="number" name="to">
        </fieldset>
    </form>

        <div style="display: flex; justify-content: center; margin: 20px;">
            <button onclick="randomNumbers()" class="myButton">Générer</button>
        </div>
    </section>

    <section style="display: block; text-align: center; margin-top: 10px; width: 50%; margin-left: auto; margin-right: auto">

        <fieldset>

            <legend style="background-color: unset;">
                <button onclick="copyText('valeurs')">
                    Copier les valeurs
                </button>
                <br>
            </legend>
            <div id="valeurs" ></div>

        </fieldset>

    </section>

    <section style="text-align: center; margin: 10px; width: 30%; display: block; margin-left: auto; margin-right: auto">
        <fieldset>
            <legend style="background-color: firebrick"><strong>Total</strong></legend>
            <div id="totalAp"></div>
        </fieldset>
    </section>

</main>
</body>
</html>

As you can see, sometimes you get values under the min or max. Because I add the total remaining divided by the number of values and add them to each of the values.

I don't know if there exists a way to only get values between the two ranges (minimum and maximum) strictly with like a method or else. I could maybe do if statements to not add the added value to those that would surpass the min/max values and divide more. But I tried and I would still get one or two not being strictly in the range.

I'm pretty new to JavaScript (and web in general).

Thanks for your time !




Aucun commentaire:

Enregistrer un commentaire