Split a random value into four that sum up to it

后端 未结 6 877
被撕碎了的回忆
被撕碎了的回忆 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:13

    As a recursive function the algorithm is very nice:

    func getRandomValues(amount: Int, total: Int) -> [Int] {
        if amount == 1 { return [total] }
        if amount == total { return Array(count: amount, repeatedValue: 1) }
        let number = Int(arc4random()) % (total - amount + 1) + 1
        return [number] + getRandomValues(amount - 1, total - number)
    }
    

    And with safety check:

    func getRandomValues(amount: Int, total: Int) -> [Int]? {
        if !(1...total ~= amount) { return nil }
        if amount == 1 { return [total] }
        if amount == total { return Array(count: amount, repeatedValue: 1) }
        let number = Int(arc4random()) % (total - amount + 1) + 1
        return [number] + getRandomValues(amount - 1, total - number)!
    }
    

    As @MartinR pointed out the code above is extremely biased. So in order to have a uniform distribution of the output values you should use this piece of code:

    func getRandomValues(amount: Int, total: Int) -> [Int] {
        var numberSet = Set()
    
        // add splitting points to numberSet
        for _ in 1...amount - 1 {
            var number = Int(arc4random()) % (total - 1) + 1
            while numberSet.contains(number) {
                number = Int(arc4random()) % (total - 1) + 1
            }
            numberSet.insert(number)
        }
    
        // sort numberSet and return the differences between the splitting points
        let sortedArray = (Array(numberSet) + [0, total]).sort()
        return sortedArray.enumerate().flatMap{
            indexElement in
            if indexElement.index == amount { return nil }
            return sortedArray[indexElement.index + 1] - indexElement.element
        }
    }
    

提交回复
热议问题