【发布时间】:2009-06-08 20:39:42
【问题描述】:
我尝试打代码。
finding the minimum value of ∑W_i*|X-X_i| 的问题简化为找到权重为w[i] 的x[i] 列表的加权中位数(定义见下文)。你将如何用一个最短、最简单、最漂亮的程序来做到这一点?
这是我的代码最初的样子(解释在the answer to the question 中,简短版本作为以下答案之一发布)。
#define zero(x) ( abs(x) < 1e-10 ) /* because == doesn't work for floats */
float sum = 0;
int i;
for (i = 0; i < n; i++)
sum += w[i];
while (sum > 0)
sum -= 2*w[--i];
right = x[i] // the rightmost minimum point
left = ( zero(sum) && zero(w[i]-w[i-1]) ) ? x[i-1] : right;
answer = (left + right) / 2;
(实际上,它已经被大量优化,因为您看到变量 i 和 sum 被重用)
规则
浮点数和整数:不同的语言有不同的浮点算术标准,所以我将问题重新表述为将x[i] 和w[i] 设为整数,你可以如果您愿意,返回两倍的答案值(始终为整数)。您可以返回、打印或将答案分配给变量。
加权中位数的定义和说明:
- 长度为
n的排序数组x[i]的中位数是x[n/2]或(x[n/2-1/2]+x[n/2+1/2])/2,具体取决于n是奇数还是偶数 -
未排序数组的中位数是排序后数组的中位数(正确,但我们的数组已排序) -
x[i]和整数正权重w[i]的加权中值被定义为较大数组的中值,其中x[i]的每次出现都已更改为w[i]x[i]的出现。
我希望看到什么
询问的原因之一是我假设最合适的语言将使用 lambda 进行简单的数组求和和迭代。我认为函数式语言可能是合理的,但我不确定——所以这是问题的一部分。我希望看到类似的东西
// standard function add := (a,b) :-> a + b
myreduce := w.reduce
with: add
until: (value) :-> 2*value >= (w.reduce with:add)
answer = x [myreduce from:Begin] + x [myreduce from:End]
不知道是否有任何语言可以实现并且实际上更短。
测试数据
static int n = 10;
for (int j = 0; j < n; j++) {
w[j] = j + 1;
x[j] = j;
}
答案:6 或 12。
static int n = 9;
int w[n], x[n] ;
for (int j = 0; j < n; j++) {
w[j] = j + ((j<6) ? 1 : 0);
x[j] = j + 1;
}
答案:6.5 或 13。
【问题讨论】:
-
[function-programming] Inigo Montoya 说“你一直在使用这个词。我不认为它意味着你认为它的意思。”
-
...你能让你的代码更具可读性吗?
-
代码高尔夫问题应该是CW。
-
澄清 x[i] 已排序。顺便说一句,CW 是什么?
-
您仍然可以将其更改为社区 wiki(我认为)。
标签: language-agnostic code-golf