You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求修复Kotlin四数拆分函数以通过指定单元测试

修复Kotlin拆分4个不同正整数的函数问题

问题背景

需要实现函数divideIntoFourDistinctNumbersThatAddUptoTotal,将给定的total(范围10~50)拆分为4个互不相同的正整数,满足以下单元测试要求:

@Test
fun dividingIntoFour() {
    repeat(times = 100) {
        val randomNumber = Random.nextInt(from = 50, until = 90)
        val total = 100 - randomNumber
        val numberList = divideIntoFourDistinctNumbersThatAddUptoTotal(total = total)
        assert(numberList.sum() == total)
        assert(!numberList.contains(0))
        assert(numberList.all { it > 0 })
        assert(numberList.distinct().size == 4)
    }
}

原实现存在偶尔挂起的问题,根源在于最后一个while循环的调整逻辑可能陷入死循环,同时初始选数范围未考虑边界情况(可能生成无效数值范围)。

原代码问题分析

  1. 无效范围风险:当total较小时(比如10),计算aTotal后可能生成start > end的Range(如3..2),调用random()会直接抛出异常。
  2. 死循环隐患:最后一个while循环的调整逻辑(如fourth -=1、first +=1)可能导致数值重复问题反复出现,或者将数值调整为0/负数,无法跳出循环。
  3. 边界条件缺失:未确保剩余数值能满足正整数要求,可能生成非正整数。

解决方案

采用循环重试+边界约束的方式,确保每次生成的数值都符合要求,且不会陷入死循环:

import kotlin.random.Random

fun divideIntoFourDistinctNumbersThatAddUptoTotal(total: Int): List<Int> {
    // 题目中total范围是10~50,满足最小拆分1+2+3+4=10的要求
    require(total >= 10) { "Total must be at least 10 to split into 4 distinct positive integers" }
    val random = Random.Default
    
    while (true) {
        // 第一个数:范围1到total-6(剩余三个数至少需要1+2+3=6)
        val first = random.nextInt(1, total - 5)
        // 第二个数:范围1到total-first-3(剩余两个数至少需要1+2=3),且不等于first
        val second = generateSequence { random.nextInt(1, total - first - 2) }
            .first { it != first }
        // 第三个数:范围1到total-first-second-1(第四个数至少需要1),且不等于first、second
        val third = generateSequence { random.nextInt(1, total - first - second) }
            .first { it != first && it != second }
        // 计算第四个数
        val fourth = total - first - second - third
        
        // 验证第四个数是否符合要求:正整数且与前三个都不同
        if (fourth > 0 && fourth != first && fourth != second && fourth != third) {
            return listOf(first, second, third, fourth)
        }
    }
}

方案优势

  1. 无死循环风险:由于题目中total范围是10~50,必然存在有效拆分(如1,2,3,total-6),因此循环一定会找到符合条件的组合后退出。
  2. 边界安全:每个数的生成范围都确保剩余数值能满足正整数要求,避免出现0或负数。
  3. 严格去重:通过generateSequence确保前三个数互不相同,最后验证第四个数的唯一性,保证最终列表的4个元素完全不同。
  4. 满足测试要求:生成的列表天然满足sum == total、全正整数、无重复的条件。

内容的提问来源于stack exchange,提问作者Christopher Hall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:45:31