实施函数式编程范例


21

您的公司才刚刚开始一个项目,并且您第一次决定使用功能性编程代码风格。但是,您的老板确实很不满意,不想使用内置功能,需要您自己实现主要功能。特别是你需要写功能:MapNestApplyRangeFoldTable在您选择的语言。老板是一个非常忙碌的人,他想让程序尽可能短,这样他就不会浪费时间阅读。他也不想让您使用循环,因此,如果不使用循环,您的字节数将减少10%。

功能的详细要求如下:

地图

Map函数有两个参数:flist其中where f是一个函数,list是一个值列表。它应返回f应用于的每个元素list。因此它将按以下方式工作:

Map(f,{a,b,c})

退货

{ f(a), f(b), f(c) }

Map(f, {{a,b},{b,c}})

退货

{ f({a,b}), f({b,c})}

Nest函数有三个参数,以及:fargtimes这里f是一个功能,arg就是它的启动参数,times是功能多少次应用。它应返回一个对f施加times时间的表达式arg。因此它将按以下方式工作:

Nest(f, x, 3)

退货

f(f(f(x)))

Nest(f, {a,b}, 3)

退货

f(f(f({a,b})))

应用

Apply函数有两个参数:fargs这里f是一个函数和args一个列表。它应该适用fargs。因此:

Apply(f, {a,b,c})

退货

f(a,b,c)

范围

Range函数采用一个整数,r并输出直至该数字的整数。因此:

Range(5)

退货

{ 1, 2, 3, 4, 5}

Fold函数有三个参数fargothers这里f是一个功能,arg就是简单的参数,并others列表。它将这样工作:

Fold(f, x, {a, b, c, d})

退货

f(f(f(f(x,a),b),c),d)

表函数应采用函数f以及iterator以以下形式调用的参数:{iMin, iMax}其中iMiniMax是整数。您应f在指定范围内使用。因此:

Table(f, {0, 5})

退货

{f(0), f(1), f(2), f(3), f(4), f(5)}

我已经从Mathematica函数式编程页面中使用了这些函数的定义,因此,如果您需要更多指导,请直接访问那里。请注意,您不需要实现该页面中显示的所有功能版本,而只需实现本文中编写的功能。

正常情况下不允许使用标准漏洞

如果您的语言不允许将函数作为参数传递,则需要实现此功能,并将其添加到您的答案中。但是,此操作的字节数不会添加到总数中。

这是代码高尔夫球,所以最短的代码获胜。祝好运!!!


这太棒了!+1但是,我不太了解Table这里的工作方式。你的榜样应该是Table(f, {x, 0, 5})吗?我也完全没有目的x,因为它只是将函数应用于范围。
kirbyfan64sos

@ kirbyfan64sos谢谢!是的,那是一个错字,我留下了x作为对mathematica的引用,它使用它作为符号特征,但是我想我可以把它弄出来
WizardOfMenlo

还有一个问题:我们如何命名功能?我们必须给他们完全相同的名字吗?单字母?
kirbyfan64sos

@ kirbyfan64sos因为它是代码高尔夫球,所以我允许使用单个字母名称,但是在您的答案中将标题放在每个函数的标题上,以便我们知道它是哪个。也不要使用碰撞字母。
WizardOfMenlo

您能否具体说明什么算作循环?
xnor

Answers:


9

Haskell,许多以前的字节数为 127 * 0.9 = 114.3字节

f#(a:b)=f a:f#b;f#x=x
(f&x)0=x;(f&x)i=f$f&x$i-1
i=id
r x=i%(1,x)
(g?x)(a:b)=g(g?x$b)a;(g?x)y=x
f%(a,b)|a>b=[]|1<2=f a:f%(a+1,b)

没有循环,只有递归。

#是地图:(*2) # [1,2,3]->[2,4,6]

&是巢:((*2) & 3) 4->48

i适用:i (*2) 7->14

r是范围:r 4->[1,2,3,4]

?折:((+) ? 0) [1,2,3,4]->10

%是表:(*2) % (2,4)->[4,6,8]

根据要求提供注释的非公开版本。请注意,&并且?是三进制中缀运算符,在被调用或模式匹配时需要附加括号。

f # (a:b) = f a : f#b        -- map on a list (a->head, b->tail) is f a in front of mapping f to b
f # x     = x                -- map on the empty list is the empty list
                             -- (non empty lists are caught in the line before) 

(f & x) 0 = x                -- nesting zero times is x
(f & x) i = f $ f&x $ i-1    -- nesting i times is f (nesting one time less)

i=id                         -- apply in Haskell is just the identity function 

r x = i % (1,x)              -- defined via the "table" of the identity function from 1 to x

(g ? x) (a:b) = g (g?x$b) a  -- folding g into a list (a->head, b->tail) is g applied to (folding g into b) and a
(g ? x) y     = x             -- folding the empty list is x
                             --  again, y must be the empty list, else it would have been handled by the previous line

f % (a,b)                    
  |a>b       = []                -- if iMin is greater than iMax, the table is empty
  |otherwise = f a : f%(a+1,b)   --  otherwise f a in front of the table with iMin increased by one

感谢@dfeuer和@Zgarb提供了一些有用的提示


我是Haskell的新手,它看起来不错,但是,请您为正在执行的操作添加一个解释?
WizardOfMenlo

1
@WizardOfMenlo:增加了一些意见
NIMI

刚意识到Haskell有多优雅,真是太好了!
WizardOfMenlo

1
忽略无限列表和效率m#q=reverse$f((:).m)[]q。该长度与您的长度相同,但难于阅读。
dfeuer

您可以!通过将其命名而不是运算符来缩短:i f=f
dfeuer

5

Python 2,305.1字节(-10%376 369 366 349 339字节)

exec'e=eval;q=len;m=@,l:e("["+"f(l.pop()),"*q(l)+"][::-1]");n=@,x,l:e("f("*l+"*x"+")"*l);r=@:e("r(f-1)+"*(f>1)+"[f]");a=@,a:e("f(a["+`r(q(a))`[1:-1]$",","-1],a[")+"-1])");f=@,x,l:e("f("*q(l)+"x,["+`r(q(l))`[1:-1]$",","-1]),l[")+"-1])");t=@,n,x:e("[f("+`r(x)[n-1:]`$",","),f(")[1:-1]+")]")'.replace("@","lambda f").replace("$",".replace(")

展开后,等效于:

e=eval;q=len
m=lambda f,l:e("["+"f(l.pop()),"*q(l)+"][::-1]")
n=lambda f,x,l:e("f("*l+"*x"+")"*l)
r=lambda i:e("r(i-1)+"*(i>1)+"[i]")
a=lambda f,a:e("f(a["+`r(q(a))`[1:-1].replace(",","-1],a[")+"-1])")
f=lambda f,x,l:e("f("*q(l)+"x,["+`r(q(l))`[1:-1].replace(",","-1]),l[")+"-1])")
t=lambda f,n,x:e("[f("+`r(x)[n-1:]`.replace(",","),f(")[1:-1]+")]")

没有循环!

好吧,它确实很有效,eval如果您的老板不能忍受循环,那么他们会讨厌评估。但是,他们将不得不忍受它

range感谢在lambda中执行操作的方法,因此我不必执行任何功能(Shudder)。

说明:

  • m=lambda f,l:eval("["+"f(l.pop()),"*len(l)+"][::-1]")
    • 创建一个从列表中弹出元素的字符串,将其包装到列表中,将其反转,最后进行评估!
  • n=lambda f,x,l:eval("f("*l+"*x"+")"*l)
    • 手动创建带有嵌套的字符串,然后进行评估!
  • r=lambda i:e("r(i-1)+"*(i>1)+"[i]")
    • 创建一个字符串,当 eval ed返回[0]或使用递归获得先前结果并将当前索引添加到列表。评估它。
  • a=lambda f,a:eval("f(a["+r(len(a))[1:-1].replace(",","-1],a[")+"-1])")
    • 使用range函数获取索引1-len(list)。用获取正确列表索引的方式替换字符串列表中的逗号a。评估吧!
  • f=lambda f,x,l:eval("f("*len(l)+"x,["+r(len(l))[1:-1].replace(",","-1]),l[")+"-1])")
    • 与apply相同,不同之处在于用逗号括起来,用逗号括起来并用逗号开头。
  • t=lambda f,n,x:eval("[f("+r(x)[n-1:].replace(",","),f(")[1:-1]+")]")
    • 与apply和fold相同,除了用结束函数并调用新函数代替。评估吧!

地图,嵌套,范围,应用,折叠,表格。

感谢@Zgarb提供的lambda范围!


我的老板会把我的头放在他的桌子上:)您能不能再加上一个简短的解释?
WizardOfMenlo

怎么r=lambda i:[]if i<1 else r(i-1)+[i]样 没有循环,只有递归。
Zgarb

1
当然,我现在就考虑一下,但是老板需要更多eval向他们展示如何for循环还不错:)
Blue

哈!使用的另一个版本e=evalr=lambda i:e("r(i-1)+"*(i>1)+"[i]")
Zgarb

您可以将奖金从60%更改为10%吗?我修改了问题说明,以使其更公平
WizardOfMenlo

5

Javascript ES6,197 * 0.9 = 177.3字节

M=(f,l)=>F((a,b)=>[...a,f(b)],[],l)
N=(f,x,n)=>f(--n?N(f,x,n):x)
A=(f,l)=>f(...l)
R=n=>n--?[...R(n),n+1]:[]
F=(f,x,l,n=l.length)=>n--?f(F(f,x,l,n),l[n]):x
T=(f,i)=>([n,x]=i,M(q=>f(q+n-1),R(x-n+1)))

地图M=(f,l)=>F((a,b)=>[...a,f(b)],[],l)):

使用Fold合并f应用于的每个成员的结果l到一个空列表。使用内置函数可将其减少为M=(f,l)=>l.map(f)(由于价格便宜而没有使用它...?)。

巢状N=(f,x,n)=>f(--n?N(f,x,n):x)):

f递归应用,直到n递减为0。

申请A=(f,l)=>f(...l)):

利用扩频(...)营办商申请lf

范围R=n=>n--?[...R(n),n+1]:[]):

Concat nRange的递归调用直到n递减为0。

F=(f,x,l,n=l.length)=>n--?f(F(f,x,l,n),l[n]):x):

应用Fold的递归调用和to n的第th个元素,直到lfn减为0。使用内置功能减少这F=(f,x,l)=>l.reduce(f,x)(再次,似乎便宜... ...)。

T=(f,i)=>([n,x]=i,M(q=>f(q+n-1),R(x-n+1)))):

首先初始化nxIMIN和IMAX使用解构(到[n,x]=i),然后使用范围来构建值的表从IMIN到IMAX。f然后使用Map将其应用于表格并返回结果。


想知道我的哲学吗?“如果便宜,那就买。” 在规范中并没有说您不能使用内置函数,所以请使用它们!
Mama Fun Roll

4

Python 3,218个字节

不可读的版本:

exec("P!:[f(_)for _ in x];Y!,z:Y(f,f(x),z-1)if z else x;T!:f(*x);H!=0:(H(f-1)if~-f else[])+[f];O!,z:O(f,f(x,z[0]),z[1:])if z else x;N!:(N(f,[x[0],x[1]-1])if x[1]-x[0]else[])+[f(x[1])]".replace("!","=lambda f,x"))

(更多)可读版本:

P=lambda f,x:[f(_)for _ in x]
Y=lambda f,x,z:Y(f,f(x),z-1)if z else x
T=lambda f,x:f(*x)
H=lambda f,x=0:(H(f-1)if~-f else[])+[f]
O=lambda f,x,z:O(f,f(x,z[0]),z[1:])if z else x
N=lambda f,x:(N(f,[x[0],x[1]-1])if x[1]-x[0]else[])+[f(x[1])]

一次通过一个lambda:

地图功能 P

P=lambda f,x:[f(_)for _ in x]
只是一个简单的迭代器。这里没有太多要说的。

嵌套功能 Y

Y=lambda f,x,z:Y(f,f(x),z-1)if z else x
递归直到z达到零,应用f每次都。最后的if子句感觉很笨拙;也许有更好的方法来结束递归。

套用功能 T

T=lambda f,x:f(*x)
Python有一个不错的扩展运算符,可以为我完成所有繁重的工作。

范围功能 H

H=lambda f,x=0:(H(f-1)if~-f else[])+[f]
这比我预期的要难。最终采取了递归方法。同样,if-else构造占用大量字节,我觉得可以改进。x=0你问为什么有一个假人?因此,当我用压缩时exec,可以替换=lambda f,x而不是=lambda f

折叠功能 O

O=lambda f,x,z:O(f,f(x,z[0]),z[1:])if z else x
对此非常满意。每次递归时,只要断开数组的第一个元素,直到没有任何剩余。

表功能 N

N=lambda f,x:(N(f,[x[0],x[1]-1])if x[1]-x[0]else[])+[f(x[1])]
这太可怕了,我敢肯定还有改进的余地。试图使用先前为map(f,range(x,y))某种构造而定义的范围和地图功能,但没有成功。最终做了一个可怕的递归方法,它与范围函数有一些相似之处。

所有的lambda表达式都包裹在exec一个replace以显著缩短字节数。


我本来打算[f(_)for _ in x]将其缩短为map(f,x),但后来我想起了挑战所在
Cyoce

4

朱莉娅,181个字节

我没有奖金;我自由地使用了循环。对不起老板,但朱莉娅的循环很有效!

M(f,x)=[f(i...)for i=x]
N(f,x,n)=(for i=1:n x=f(x...)end;x)
A(f,x)=f(x...)
R(n)=(i=0;x={};while i<n push!(x,i+=1)end;x)
F(f,x,a)=(for b=a x=f(x,b)end;x)
T(f,i)=[f(j)for j=i[1]:i[2]]

在函数的参数后面添加省略号会破坏数组,元组或常规函数参数中包含的内容。否则,该函数会认为您正在尝试传递数组(或元组等)。它对单个参数无效。

函数名称:

  • 地图: M
  • 巢: N
  • 应用: A
  • 范围: R
  • 折: F
  • 表: T

4

Tinylisp,325 * 0.9 = 292.5

语言比问题新,但无论如何它不会取胜。

(d @(q(a a)))(d Q(q((l)(i l(c(@(q q)(h l))(Q(t l)))l))))(d A(q((f a)(v(c(q f)(Q a))))))(d M(q((f l)(i l(c(A f(@(h l)))(M f(t l)))l))))(d N(q((f a x)(i x(A f(@(N f a(s x 1))))a))))(d ,(q((m a b)(i(l b a)m(,(c b m)a(s b 1))))))(d R(q((a)(,()1 a))))(d T(q((f r)(M f(A ,(c()r))))))(d F(q((f a l)(i l(F f(A f(@ a(h l)))(t l))a))))

定义函数A(应用),M(地图),N(嵌套),R(范围),T(表)和F(折叠)以及一些辅助函数。T期望其第二个参数为两个整数的列表。

Tinylisp甚至没有任何循环构造。一切都通过递归来完成。其中一些函数不是尾递归的,因此,如果在大列表上调用它们,则可能会破坏调用堆栈。它们都可以用尾递归来实现...但是会占用更多字节,这就是代码高尔夫。

这是一个扩展的版本,带有空格和名称的真实单词,如果您熟悉Lisp,应该很容易阅读。(除了其他的tinylisp内建函数,我都使用了别名q(quote)和i(if)。)

(d define d)
(define cons c)
(define car h)
(define cdr t)
(define subtract s)
(define less l)
(define eval v)

(define lambda
  (q (()
      (arglist expr)
      (list arglist expr))))

(define list (lambda args args))

(define quote-all
  (lambda (lyst)
    (i lyst
       (cons
         (list (q q) (car lyst))
         (quote-all (cdr lyst)))
       lyst)))

(define Apply
  (lambda (func arglist)
    (eval (cons (q func) (quote-all arglist)))))

(define Map
  (lambda (func lyst)
    (i lyst
       (cons
         (Apply func (list (car lyst)))
         (Map func (cdr lyst)))
       lyst)))

(define Nest
  (lambda (func arg times)
    (i times
       (Apply func
              (list (Nest func arg (subtract times 1))))
       arg)))

(define range*
  (lambda (accumulator a b)
    (i (less b a)
       accumulator
       (range* (cons b accumulator) a (subtract b 1)))))

(define Range
  (lambda (x)
    (range* 1 x)))

(define Table
  (lambda (func iterator)
    (Map func
         (Apply range* (cons () iterator)))))

(define Fold
  (lambda (func arg lyst)
    (i lyst
       (Fold func
             (Apply func (list arg (car lyst)))
             (cdr lyst))
       arg)))

可根据要求提供进一步的解释。

样品输出

使用我的参考实现中的REPL环境。对于这些示例,我将q(quote)用作一元函数,将s(减法)用作二进制函数,以及@将返回其参数列表的函数(在此代码中定义)。

tl> [line of definitions goes here]
@
Q
A
M
N
,
R
T
F
tl> (A s (@ 10 7))
3
tl> (M q (@ 1 2 3 4))
((q 1) (q 2) (q 3) (q 4))
tl> (N q 123 4)
(q (q (q (q 123))))
tl> (R 5)
(1 2 3 4 5)
tl> (T q (@ 3 7))
((q 3) (q 4) (q 5) (q 6) (q 7))
tl> (F s 10 (@ 4 3 2))
1

2

Python 2.x:450.6字节(折扣10%之前为493字节)

打高尔夫球的答案:

y=len
z=lambda a,b:a.append(b)
_=lambda a:a if a is not None else[]
def M(a,b,c=None):
 c=_(c);d=y(b)
 if d:z(c,A(a,b[0]))
 return M(a,b[1:],c)if d else c
def N(a,b,c):d=A(a,b);return N(a,d,c-1)if c>1 else d
A=lambda a,b:a(*b)if type(b)is list else a(b)
def R(a,b=None):b=_(b);b.insert(0,a);return b if a<=1 else R(a-1,b)
def F(a,b,c):d=a(b,c[0]);return F(a,d,c[1:])if y(c)>1 else d
def T(a,b,c=None,d=None):
 if c is None:c=b[0];d=[]
 z(d,a(c));return T(a,b,c+1,d)if c<b[1]else d

这个问题很有趣。我决定在不使用Python等效项的情况下编写函数(尽管这可能是一个有效的漏洞),并且像Python支持尾部递归一样编写函数。为了使此工作正常进行,我使用了许多可选参数,这些参数允许所需的调用仍然起作用。

下面我列出了每个功能的清单。

Apply

A = lambda function, arguments: function(*arguments) if type(arguments) is list else function(arguments)

Map

def M(function, arguments, result=None):
    result = result if result is not None else []
    length = len(arguments)
    if length != 0:
        result.append(A(function, arguments[0]))
    return M(function, arguments[1:], result) if length != 0 else result

Nest

def N(function, arguments, times):
    result = A(function, arguments)
    return N(function, result, times - 1) if times > 1 else result

请注意,此函数要求所传递的内容function能够可变地表示多个参数。另一种方法是强制该函数始终接收单个列表,但这将要求所传递的函数能够解释参数列表。无论哪种方式都有假设,因此我选择了更适合系统其余部分的假设。

Range

def R(ceiling, result=None):
    result = result if result is not None else []
    result.insert(0, ceiling)
    return result if ceiling <= 1 else R(ceiling - 1, result)

Fold

def F(function, initial, rest):
    result = function(initial, rest[0])
    return F(function, result, rest[1:] if len(rest) > 1 else result

Table

def T(function, iterator, current=None, result=None):
    if current is None:
        current = iterator[0]
        result = []
    result.append(function(current))
    return T(function, iterator, current + 1, result) if current < iterator[1] else result

这是使用以下辅助函数的示例输出:

square = lambda x: x * x
def add(*args):
    addTwo = lambda a, b: a + b
    if len(args) == 1 and type(args[0]) is list:
        return F(addTwo, 0, args[0])
    else:
        return F(addTwo, 0, args)

>>> M(square, R(10))
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> M(add, [R(i) for i in R(10)])
[1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
>>> T(square, [0, 10])
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> N(square, 2, 4)
65536
>>> N(lambda *args: F(lambda a, b: a * b, 1, args) if len(args) > 1 else str(args[0]) + 'a', R(5), 10)
'120aaaaaaaaa'

哇,看起来真不错!
WizardOfMenlo

那似乎是一种歪曲的审美观念; )自从我读了第一本关于Python如何实现可读性的书以来,我总是觉得看高尔夫球的Python很有趣。
sadakatsu

我确实对美学有偏见:)
WizardOfMenlo 2015年

我被别人的分数弄糊涂了。对于每个不使用循环的必需功能(全部都是),我占了所有分数的10%,但是对于不使用循环的每个功能,其他人则占了总分数的10%(可以是最高可享60%的折扣)。哪种方法正确?
sadakatsu

您的做法是正确的,我有一个不切实际的期望,所以最初我想到了60%的方法,但是现在我认为10%的方法会更刺激,并且两者之间更合适
WizardOfMenlo

2

锡兰,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]])];

实际上,只有两个函数(tf)实际上在使用递归(分别在列表和整数上),其他函数则基于这些。(应用有点离群值,它与其他元素并没有真正的联系。)

我将“列表”解释为锡兰的顺序类型,它是元素的不可变有序(可能为空)序列。[R*]代表Sequential<R>–由于某种原因,我们也可以编写它R[],它短了一个字节。

函数类型是Callable<R, A>,其中A是参数的元组类型,例如[X, Y, Z](即的某些子类型Anything[])。作为快捷方式,我们可以编写R(X,Y,Z)而不是Callable<R,[X,Y,Z]>

我别名IntegerI节省一些字节。

这是一个格式化(并稍加注释)的版本:

// 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分。尽管看起来更像是在作弊。)

如果..不允许,我们将不得不再次实现它。我们可以将这些实现用于rt(与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个字节,比完全递归的版本要好,但是在应用了红利之后却没有。


0

Groovy(146字节)(146 * 90%= 131.4)

PS:在这种情况下,我不知道您认为什么是“循环”,我只是在OP告诉我之后才应用了奖金,如果另外2-3个用户说这些收集函数和迭代器,则将删除该奖金是循环,我不配得到奖金。另外,如果您想使用1..it来叫我,请这样做,我将对其进行重做/更新我的字节数。

m={f,l->l.collect{f(it)}}            // Map
n={f,x,n->n.times{x=f(x)};x}         // Nest
a={f,l->f(l)}                        // Apply
r={1..it}                            // Range (Is this cheating?)
f={f,x,l->l.each{x=f(x,it)};x}       // Fold
t={f,l->(l[0]..l[1]).collect{f(it)}} // Table

输入/输出示例

f1={2*it}
f2={a,b,c,d,e->a*b*c*d*e}
f3={a,b->a*b}
l=[1,2,3,4,5]
l2=[1,9]
y=5
x=1
println m(f1,l)
println n(f1,x,y)
println a(f2,l)
println r(y)
println f(f3,x,l)
println t(f1,l2)

输出量

MAP:   [2, 4, 6, 8, 10]
NEST:  32
APPLY: 120
RANGE: [1, 2, 3, 4, 5]
FOLD:  120
TABLE: [2, 4, 6, 8, 10, 12, 14, 16, 18]

自己尝试:https : //groovyconsole.appspot.com/edit/5203951758606336


从技术上讲,这不使用循环,所以请记住奖金!否则,很好的答案!
WizardOfMenlo

技术上没有循环?!真?!.each {} .times {} .collect {}是迭代器。
魔术章鱼缸
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.