-4

i have some problem like this. user(A) enter 500000 to my application and then i want to generate 50 random 5 digit number and when summary 50 random number need to equal 500000, How to do like i tried already but it's not working this is my code

            int balane = 500000;
            int nums = 50;
            int max = balane / nums;
            Random rand = new Random();
            int newNum = 0;
            int[] ar = new int[nums];
            for (int i = 0; i < nums - 1; i++)
            {
                newNum = rand.Next(max);
                ar[i] = newNum;
                balane -= newNum;
                max = balane / (nums - i - 1);

                ar[nums - 1] = balane;
            }

            int check = 0;
            foreach (int x in ar)
            {
                check += x;
            }

the result that i tell you not working because in my array list i have value more than 5 digit but the result equal 500000.

enter image description here

How to solve this issue ? Thank you very much.

user3001046
  • 235
  • 1
  • 10
  • 28
  • 1
    The screenshot you've shown isn't the same as the code you've posted. The screenshot uses `rand.Next(0, 99999)` whereas the code you've posted as text uses `rand.Next(0, max)`. The code that uses `rand.Next(0, max)` works. (Admittedly I'd only allocate `ar[num -1]` after the loop, but that's a different matter. – Jon Skeet Jun 16 '18 at 08:06
  • @DaisyShipton Please check again, i edited already. – user3001046 Jun 16 '18 at 08:22
  • @user3001046 - Do you mean you want 50 random numbers that sum to 500,000? – Enigmativity Jun 16 '18 at 08:25
  • 1
    what is the desired output? – Jonathan Applebaum Jun 16 '18 at 08:26
  • debug debug debug step by step and fix it.... – Aristos Jun 16 '18 at 08:35
  • 2
    Right, so at this point it's a matter of your algorithm being broken. Consider that `rand.Next(max)` could always return 0... at that point, your final element would have to be the original target. You need to think about applying a minimum as well as a maximum. Note that your question would be better (IMO) if you'd remove the screenshot, add a `Console.WriteLine(ar[nums - 1])` after the loop, and just include the output of that. There's no need for an image here. – Jon Skeet Jun 16 '18 at 08:36
  • @Enigmativity Yes – user3001046 Jun 16 '18 at 08:47
  • 1
    https://stackoverflow.com/questions/50876175/how-to-generate-random-5-digit-number-depend-on-user-summary why are you posting same question again ? – Amit Jun 16 '18 at 08:48
  • sorry, but please help – user3001046 Jun 16 '18 at 08:57
  • 50*10000=500000. Hence, no need to random – Ray Krungkaew Jun 16 '18 at 09:10
  • @paparazzo is duplicate but this question can make you understand me – user3001046 Jun 16 '18 at 09:24
  • 1
    @user3001046 update the original question if you need to, but posting a duplicate question is against the rules. – cwharris Jun 16 '18 at 13:38

2 Answers2

0

This works for me

    public static void test(int balance = 500000, int nums = 50, int max_digits = 5)
    {
        int rest = balance;
        var max_value = (int)Math.Pow(10, max_digits) - 1;

        var rand = new Random();

        int[] ar = new int[nums];
        for (int i = 0; i < nums - 1; i++)
        {
            var max = rest / (nums - i);
            if (max > max_value) max = max_value;
            var newNum = rand.Next(max);
            ar[i] = newNum;
            rest -= newNum;
        }
        while (rest > max_value)
        {
            var all_values_are_max = true;
            for (int i = 0; i < nums - 1; i++)
            {
                if (ar[i] < max_value)
                {
                    var d = (int)((max_value - ar[i]) / 10.0); // 10% increase
                    ar[i] += d;
                    rest -= d;
                    all_values_are_max = false;
                }
            }
            if (all_values_are_max)
                throw new Exception("This is not possible at all!");
        }
        while (rest < 0)
        {
            for (int i = 0; i < nums - 1; i++)
            {
                if (ar[i] > 0)
                {
                    var d = (int)(ar[i] / 20.0); // %5 decrease
                    ar[i] -= d;
                    rest += d;
                }
            }
        }
        ar[nums - 1] = rest;

        int check_sum = 0;
        foreach (int x in ar)
        {
            check_sum += x;
            if (x > max_value || x < 0)
                MessageBox.Show("wrong value");
        }
        if (check_sum != balance)
            MessageBox.Show("Error: sum is " + check_sum);

        MessageBox.Show("ok");
    }

For example, test(500000,50) works fine all times, but test(500000, 5) throw an exception, because is not possible

mrbm
  • 1,136
  • 1
  • 12
  • 36
  • This question is an exact duplicate from the same user. Please move this answer to that question to discourage duplicate posting. – cwharris Jun 16 '18 at 13:40
0

Perhaps try this:

var rnd = new Random();

var numbers = Enumerable.Range(0, 50).Select(x => rnd.Next(500_000)).OrderBy(x => x).ToArray();

numbers = numbers.Skip(1).Zip(numbers, (x1, x0) => x1 - x0).ToArray();

numbers = numbers.Append(500_000 - numbers.Sum()).ToArray();

Console.WriteLine(numbers.Count());
Console.WriteLine(numbers.Sum());

This outputs:

50
500000

This works by generating 50 random numbers between 0 and 499,999 inclusively. It then sorts them ascendingly and then gets the difference between each successive pair. This by definition produces a set of 49 values that almost adds up to 500,000. It's then just a matter of adding the one missing number by doing 500_000 - numbers.Sum().

Enigmativity
  • 113,464
  • 11
  • 89
  • 172