2

I am trying to create a function, that will always total the mx variable, in the code:

(function () {
    var i = 0;
    var j;
    var mn = 1;
    var mx = 579;

    while (i < mx) {
        j = Math.floor(Math.random() * (mx - mn + 1)) + mn;
        mx = mx - i;
        i += j;

        if (i < (mx - j)) {
            console.log(i);
        } else {
            console.log(mx);
        }
    }
})();

So if mx = 999 then the console may log 900, 90 and 9 or if mx = 50 the console could log 4, 1, 10, 33 and 2.

This happens most of the time, but every now-and-again I get numbers that equal greater than mx and I can't for the life of me figure out why!

I'd be very grateful for any help, pointers or direction! As I'd like to lean where I went wrong, an explanation would be really awesome too!

Thank you!

Jonathon Oates
  • 2,912
  • 3
  • 37
  • 60
  • 1
    Related: http://stackoverflow.com/questions/7289136/how-to-make-5-random-numbers-with-sum-of-100, http://stackoverflow.com/questions/2640053/getting-n-random-numbers-that-the-sum-is-m, http://stackoverflow.com/questions/8064629/random-numbers-that-add-to-100-matlab, http://stackoverflow.com/questions/3959021/non-biased-return-a-list-of-n-random-positive-numbers-0-so-that-their-sum – finnw Dec 03 '11 at 02:14

2 Answers2

1

Although i < mx at the start of the loop, that's no longer necessarily true once you've added j to it. That's why you're sometimes writing a value of i that's bigger than your original mx.

Matthew Strawbridge
  • 19,940
  • 10
  • 72
  • 93
0

I'm not sure I'm interpreting your problem correctly, but you seem to want to "break up" a number into random numbers which add up to the initial value (579).

If so, I think you're doing it a little bit incorrectly: you;re both substracting i from max and adding j to i. Thus, i becomes larger each time.

It looks like your algorithm can be simplified.

Edit: I gave it another shot so that the numbers are (as far as I'm concerned) more uniformly distributed. I also renamed the variables for clarity:

(function () {
    var total = 0,
        current,
        min = 1,
        max = 579;

    while (total < max) { // while the total has not reached max yet
        current = Math.floor(Math.random() * (max - min + 1)) + min;

        if(total + current > max) { // if total would become too high
            current = max - total;  // set current such that total becomes max
        }

        total += current;

        console.log(current);
    }
})();
pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • I'll try this tomorrow morning, but does this solution do: if we had a max of 50, and the first random number was 12, we'd be left with 38. If the second random number was 32, we'd be left with 6. If the third random number was 12, we discard it and go with the 6 that we had left, which would total the max of 50 we started with. I don't want the random number to get smaller each time, as in, if we're breaking up the number, I dont want each break to get smaller on each loop. – Jonathon Oates Dec 02 '11 at 23:25
  • @Jonathon David Oates: Yes, that's what this does. You indeed get relatively many small numbers at the end. I'll change it when I have time. – pimvdb Dec 02 '11 at 23:29
  • If you could that would be great! Thanks' – Jonathon Oates Dec 02 '11 at 23:33