生成 4 个不同的数字,这些数字加起来就是一个随机生成的数字

问题描述 投票:0回答:1

我需要通过这个单元测试:

 @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)
        }
    }

通过案例:

该函数正确地将总和(即 100 减去 50 到 90 之间的随机数)分成四个不同的正整数,总和为总和,这适用于该函数的 100 次迭代。

失败案例:

  • 函数返回一个包含0的列表。
  • 函数返回一个不正好包含四个的列表 不同的正整数。
  • 函数返回一个非正整数列表。
  • 函数返回一个整数列表,这些整数加起来不等于 给出总数。

这和我得到的一样接近——它要么通过,要么挂在最后一个 while 循环中:

fun divideIntoFourDistinctNumbersThatAddUptoTotal(total: Int): List<Int> {
        var aTotal = total
        var first = (aTotal / 4..aTotal / 2).random()
        aTotal -= first
        var second = (3..aTotal - 3).random()
        while (second == first) {
            second = (3..aTotal - 3).random()
        }
        aTotal -= second
        var third = (3..aTotal).random()
        while (third == first || third == second) {
            third = (3..aTotal).random()
        }
        aTotal -= third
        var fourth = aTotal
        while (listOf(first, second, third, fourth).distinct().size != 4) {
            if (fourth == first) {
                fourth -= 1
                first += 1
            } else if (fourth == third) {
                fourth -= 1
                third += 1
            } else if (fourth == second) {
                fourth -= 1
                second += 1
            }
        }
        return listOf(first, second, third, fourth)
    }

ChatGpt 在其 openai 网站和 github copilot 上都失败了。

kotlin distinct
1个回答
0
投票

使用基于随机获取一个数字,然后随机获取第二个数字,依此类推的算法来解决这个问题似乎是一项艰巨的任务,因为您将获得比例过高的包含递减数字的结果。但是如果四个数的排序没有关系,那就没问题了

如果不经常连续调用函数,那么在随机列表中简单搜索第一个解决方案可能就是解决方案。这可能会比你的算法慢一点(因为三个“洗牌”)。

repeat(times = 100) {
  val total = (10..50).random()
  val ints = divideIntoFourDistinctNumbersThatAddUptoTotal(total = total)
  if (ints.sum() != total) println("Invalid total: $ints => $total")
  if (ints.contains(0)) println("Contains zero: $ints => $total")
  if (ints.distinct().size != 4) println("Not distinct: $ints => $total")
  println("$total -> $ints")
}

fun divideIntoFourDistinctNumbersThatAddUptoTotal(total: Int): List<Int> {

  val largestInt = total - (1 + 2 + 3)

  val ints1 = IntArray(largestInt) { it + 1 }.apply { shuffle() }
  val ints2 = IntArray(largestInt) { it + 1 }.apply { shuffle() }
  val ints3 = IntArray(largestInt) { it + 1 }.apply { shuffle() }

  for (i1 in ints1) {
    for (i2 in ints2) {
      if (i1 == i2) continue
      val sum12 = i1 + i2
      if (sum12 > total) continue
      for (i3 in ints3) {
        if (i1 == i3 || i2 == i3) continue
        val sum123 = sum12 + i3
        if (sum123 > total) continue
        val i4 = total - sum123
        if (i4 > 0 && i1 != i4 && i2 != i4 && i3 != i4) {
          return listOf(i1, i2, i3, i4).sorted()
        }
      }
    }
  }

  return emptyList()   // Only for when 'total' is smaller than 10 (1 + 2 + 3 + 4)

}

科特林游乐场

© www.soinside.com 2019 - 2024. All rights reserved.