我目前正在处理这个(代码高尔夫)挑战,我很难结合给定整数数量n
和十进制总和的四个要求s
(考虑到我们应该支持的范围:1 <= n <= 10
和0 <= s <= n
):
- 项目
n
都应该是随机的,并且是均匀划分的 - 所有项目的总和必须等于
s
- 所有项目均不得高于 1.0
- 代码必须在每 1 秒内运行
n <= 10
,无论s
基于这个 Stackoverflow 答案,我知道如何在给定范围内统一划分项目。例如,使用,我可以在 range 中n=5, s=4.5
创建一个项目列表,并带有一个额外的前导和尾随。然后我可以计算所有差异(因此所有差异的总和将等于)。这是一个可能的实现:n-1 = 4
[0, 1.5]
0
1.5
s=4.5
int n=5; double s=4.5;
double[] randomValues = new double[n+1];
randomValues[n] = s;
for(int i=1; i<n; i++)
randomValues[i] = Math.random()*s;
java.util.Arrays.sort(randomValues);
System.out.println("Random values:\n"+java.util.Arrays.toString(randomValues)+"\n");
double[] result = new double[n];
for(int i=0; i<n; i++)
result[i] = Math.abs(randomValues[i]-randomValues[i+1]);
System.out.println("Result values:\n"+java.util.Arrays.toString(result)+"\n");
double resultSum = java.util.Arrays.stream(result).sum();
System.out.println("Sum: "+resultSum);
System.out.println("Is the result sum correct? "+(s==resultSum?"yes":"no"));
示例输出:
Random values:
[0.0, 1.3019797415889383, 1.9575834386978177, 2.0417721898726313, 4.109698885802333, 4.5]
Result values:
[1.3019797415889383, 0.6556036971088794, 0.08418875117481361, 2.0679266959297014, 0.39030111419766733]
Sum: 4.5
Is the result sum correct? yes
以上符合上述四个要求中的三个(1、2 和 4)。但是,不是3。
我可以在它周围环绕一个循环,只要result
-array 中的一项仍然大于 1,它就会继续:
for(boolean flag=true; flag; ){
... // Same code as above
flag=false;
for(double d:result)
if(d>1)
flag=true;
}
这对大多数人来说仍然相对较快,n
并且s
:
在线尝试(打印被删除/移动以不溢出控制台)
但是,最后四个//
禁用的测试用例,预期随机值的平均值接近1
,耗时太长(甚至在 TIO 上 60 秒后超时)。
所以这就是我的问题主要涉及的地方。如何像我一样统一划分值,并记住[0, 1]
每个值的范围,并有良好的表现?在顶部的链接代码高尔夫挑战中,我看到了其他编程语言(如 Python 或 JavaScript)的一些工作示例,但是将更长的代码高尔夫挑战从一种编程语言移植到另一种编程语言通常不是很简单。