锡兰,370 * 0.9 = 333364 * 0.9 = 327.4
这些功能大多数已经在Ceylon的语言包中提供(尽管有时签名有所不同),但是我们按照问题的要求在此处定义它们。
alias I=>Integer;R[]m<A,R>(R(A)g,A[]l)=>f((R[]x,A y)=>x.append([g(y)]),[],l);A n<A>(A(A)g,A a,I t)=>f((A x,I y)=>g(x),a,r(t));R y<A,R>(Callable<R,A>g,A v)given A satisfies Anything[]=>g(*v);I[]r(I i)=>t((j)=>j,[1,i]);A f<A,O>(A(A,O)g,A a,O[]o)=>if(nonempty o)then f(g,g(a,o[0]),o.rest)else a;R[]t<R>(R(I)g,[I,I]i)=>i[1]<i[0]then[]else[g(i[0]),*t(g,[i[0]+1,i[1]])];
实际上,只有两个函数(t
和f
)实际上在使用递归(分别在列表和整数上),其他函数则基于这些。(应用有点离群值,它与其他元素并没有真正的联系。)
我将“列表”解释为锡兰的顺序类型,它是元素的不可变有序(可能为空)序列。[R*]
代表Sequential<R>
–由于某种原因,我们也可以编写它R[]
,它短了一个字节。
函数类型是Callable<R, A>
,其中A
是参数的元组类型,例如[X, Y, Z]
(即的某些子类型Anything[]
)。作为快捷方式,我们可以编写R(X,Y,Z)
而不是Callable<R,[X,Y,Z]>
。
我别名Integer
为I
节省一些字节。
这是一个格式化(并稍加注释)的版本:
// implement functional paradigms
//
// Question: http://codegolf.stackexchange.com/q/58588/2338
// My Answer: http://codegolf.stackexchange.com/a/64515/2338
alias I => Integer;
// map – based on fold.
R[] m<A, R>(R(A) g, A[] l) =>
f((R[]x,A y) => x.append([g(y)]), [], l);
// nest – based on fold + range, throwing away the second
// argument in a proxy function.
A n<A>(A(A) g, A a, I t) =>
f((A x, I y) => g(x), a, r(t));
// apply – this looks quite heavy due to type safety.
// This uses the "spread operator" *.
R y<A, R>(Callable<R,A> g, A v)
given A satisfies Anything[] =>
g(*v);
// range – based on table (using the identity function)
I[] r(I i) =>
t((j) => j, [1, i]);
// fold – a plain list recursion.
A f<A, O>(A(A, O) g, A a, O[] o) =>
if (nonempty o) then f(g, g(a, o[0]), o.rest) else a;
// table – an integer recursion.
// (Not sure why the min/max parameters need
// to be passed in one argument.)
R[] t<R>(R(I) g, [I, I] i) =>
i[1] < i[0] then [] else [g(i[0]), *t(g, [i[0] + 1, i[1]])];
使用“循环”
可以使用循环(实际上是序列理解)来更短地实现Table和Map:
// map – using a sequence comprehension:
R[] m<A, R>(R(A) g, A[] l) =>
[for(a in l) g(a)];
// table – map with an integer range.
// (Not sure why the min/max parameters need
// to be passed in one argument.)
R[] t<R>(R(I) g, [I, I] i) =>
m(g, i[0]..i[1]);
尽管我不确定整数范围内使用..
运算符是否算作内置函数。如果允许,则结果代码为长度312:
alias I=>Integer;R[]m<A,R>(R(A)g,A[]l)=>[for(a in l)g(a)];A n<A>(A(A)g,A a,I t)=>f((A x,I y)=>g(x),a,r(t));R y<A,R>(Callable<R,A>g,A v)given A satisfies Anything[]=>g(*v);I[]r(I i)=>t((j)=>j,[1,i]);A f<A,O>(A(A,O)g,A a,O[]o)=>if(nonempty o)then f(g,g(a,o[0]),o.rest)else a;R[]t<R>(R(I)g,[I,I]i)=>m(g,i[0]..i[1]);
(通过定义可以使它更短r(I i) => 1..i
,得到301分。尽管看起来更像是在作弊。)
如果..
不允许,我们将不得不再次实现它。我们可以将这些实现用于r
和t
(与m
以上所述):
// range – based two-limit range
I[] r(I i) =>
q(1, i);
// two-limit range implemented recursively
I[] q(I i, I j) =>
j < i then [] else [i, *q(i + 1, j)];
// table – map with an integer range.
// (Not sure why the min/max parameters need
// to be passed in one argument.)
R[] t<R>(R(I) g, [I, I] i) =>
m(g, q(i[0], i[1]));
这将产生348个字节,比完全递归的版本要好,但是在应用了红利之后却没有。
Table
这里的工作方式。你的榜样应该是Table(f, {x, 0, 5})
吗?我也完全没有目的x
,因为它只是将函数应用于范围。