Split a random value into four that sum up to it

后端 未结 6 873
被撕碎了的回忆
被撕碎了的回忆 2020-12-20 05:50

I have one value like 24, and I have four textboxes. How can I dynamically generate four values that add up to 24?

All the values must be integers and can\'t be nega

6条回答
  •  攒了一身酷
    2020-12-20 06:31

    Here's a solution which should have significantly* less bias than some of the other methods. It works by generating the requested number of random floating point numbers, multiplying or dividing all of them until they add up to the target total, and then rounding them into integers. The rounding process changes the total, so we need to correct for that by adding or subtracting from random terms until they add up to the right amount.

    func getRandomDoubles(#count: Int, #total: Double) -> [Double] {
        var nonNormalized = [Double]()
        nonNormalized.reserveCapacity(count)
        for i in 0.. [Int] {
        let doubles = getRandomDoubles(count: count, total: Double(total))
        var ints = [Int]()
        ints.reserveCapacity(count)
        for double in doubles {
            if double < 1 || double % 1 >= 0.5 {
                // round up
                ints.append(Int(ceil(double)))
            } else {
                // round down
                ints.append(Int(floor(double)))
            }
        }
        let roundingErrors = total - (reduce(ints, 0) { $0 + $1 })
        let directionToAdjust: Int = roundingErrors > 0 ? 1 : -1
        var corrections = abs(roundingErrors)
        while corrections > 0 {
            let index = Int(arc4random_uniform(UInt32(count)))
            if directionToAdjust == -1 && ints[index] <= 1 { continue }
            ints[index] += directionToAdjust
            corrections--
        }
        return ints
    }
    

    *EDIT: Martin R has correctly pointed out that this is not nearly as uniform as one might expect, and is in fact highly biased towards numbers in the middle of the 1-24 range. I would not recommend using this solution, but I'm leaving it up so that others can know not to make the same mistake.

提交回复
热议问题