0

As an example. I want to randomly hand out 100 chocolates to 25 kids. I cannot give any kid more than 10 chocolates.

So here m = 100, n = 25, x = 1 and y = 12.

I have checked these questions.

Dividing a number into m parts uniformly randomly

Dividing a number into random unequal parts

They do give some idea but in these questions x and y are not specified.

So basically,

1) Total No. of Chocolates = 100

2) I can only give minimum 1 and maximum 12 chocolates to each kid

3) Chocolates should be distributed between 25 kids

4) I do not want any distribution (uniform or normal) - it should be purely random. (I am willing to exclude this condition if all else fails.)

Private Function divideUniformlyRandomly(n As Integer, m As Integer) As Integer()
    Dim rRandom As New Random
    Dim fences As Integer() = New Integer(m - 2) {}
    For i As Integer = 0 To m - 3
        fences(i) = rRandom.Next(0, n - 1)
    Next
    [Array].Sort(fences)

    Dim result As Integer() = New Integer(m - 1) {}
    result(0) = fences(0)
    For i As Integer = 1 To m - 3
        result(i) = fences(i + 1) - fences(i)
    Next
    result(m - 1) = n - 1 - fences(m - 2)

    Return result
End Function

This does work but I get 0 and 13 as well. I cannot ensure x and y here.

Community
  • 1
  • 1
VRM
  • 151
  • 2
  • 11

1 Answers1

1

Give each child x chocolate. This will leave you with m - (n * x) to distribute randomly. Keep distributing to children that have less than y chocolates, until there are no more chocolates.

Private Function divideUniformlyRandomly(n As Integer, m As Integer, x As Integer, y As Integer) As Integer()
    Dim rRandom As New Random
    Dim aResult As Integer() = New Integer(n - 1) {}

    Dim i As Integer = 0
    Dim remaining As Integer = m


    ' Every n must have a min of x.
    For i = 0 To n - 1
        aResult(i) = x
        remaining -= x
    Next

    ' distribute the remaining m over the children randomly
    While remaining > 0

        ' pick a child randomly
        i = rRandom.Next(0, n)

        ' if the child has less than y, give them one
        If aResult(i) < y Then
            aResult(i) += 1
            remaining -= 1
        End If

    End While

    ' Debug
    Dim sum As Integer = 0
    For i = 0 To n - 1
        Console.WriteLine("{0}: {1}", i, aResult(i))
        sum += aResult(i)
    Next

    Console.WriteLine("Sum: {0}", sum)

    divideUniformlyRandomly = aResult
End Function
Mike Hixson
  • 5,071
  • 1
  • 19
  • 24