高尔夫定点组合器


9

用您选择的语言编写尽可能少的字符的定点组合器

  • 自由形式(最短的形式):整个程序,实际功能,代码段
  • 如果您有一个标准库,则可能无法使用
  • 但是,您可能希望从其他高级函数中提取它,而不是从基础上构造它

请包括将其用作演示的递归阶乘或斐波那契。

在这个问题中,自引用是可以接受的,其目的仅仅是将其从递归函数中删除。


惰性语言实现可以吗?(您接受(define Y(lambda(f)(f(Y f))))吗?)
Eelvex 2011年

您可以使用所要求的示例之一进行演示的任何实现都可以。
JB

1
如果我没记错的话,严格来说,术语“ Y组合器”专门指Haskell Curry发现的单个定点组合器λf。(λx.f(xx))(λx.f(xx))。
乔伊·亚当斯

@Eelvex:到目前为止,显然两个答案(包括OP自己的答案)都使用作弊方式,因此,我认为这样还可以。:-P就个人而言,我宁愿使用@Joey的方法,并说只有真正的(非自我引用)Y组合器才能使用。;-)
Chris Jester-Young

@克里斯:天哪。最初我就是这样想的,然后我...一路上忘记了。现在进行更改为时已晚,我们将不得不提出另一个问题。
JB

Answers:


13

Haskell:10个字符

y f=f$y f

用于创建阶乘或nth-Fibonacci的递归定义的示例:

> map ( y(\f n->if n <= 1 then 1 else n*f(n-1)) ) [1..10]
[1,2,6,24,120,720,5040,40320,362880,3628800]

> map ( y(\f n->if n <= 1 then 1 else f(n-1)+f(n-2)) ) [0..10]
[1,1,2,3,5,8,13,21,34,55,89]

不过,更常见的使用y方式是直接生成这些序列,而不是将其作为函数:

> take 10 $ y(\p->1:zipWith (*) [2..] p)
[1,2,6,24,120,720,5040,40320,362880,3628800]

> take 11 $ y(\f->1:1:zipWith (+) f (tail f))
[1,1,2,3,5,8,13,21,34,55,89]

当然,对于Haskell,这有点像在桶中射鱼!该Data.Function库具有称为的功能,fix但实现起来较为详细。


4

Perl,37岁

sub f{my$s=$_[0];sub{$s->(f($s),@_)}}

析因演示:

sub fact {
  my ($r, $n) = @_;
  return 1 if $n < 2;
  return $n * $r->($n-1);
}
print "Factorial $_ is ", f(\&fact)->($_), "\n" for 0..10;

斐波那契演示:

sub fib {
  my ($r, $n) = @_;
  return 1 if $n < 2;
  return $r->($n-1) + $r->($n-2);
}
print "Fibonacci number $_ is ", f(\&fib)->($_), "\n" for 0..10;

3

GNU C-89个字符

#define fix(f,z)({typeof(f)__f=(f);typeof(__f(0,z))x(typeof(z)n){return __f(x,n);}x(z);})

例:

#define lambda2(arg1, arg2, expr) ({arg1;arg2;typeof(expr)__f(arg1,arg2){return(expr);};__f;})

int main(void)
{
    /* 3628800 */
    printf("%ld\n", fix(lambda2(
        long factorial(int n), int n, 
            n < 2 ? 1 : n * factorial(n-1)
        ), 10));

    /* 89 */
    printf("%ld\n", fix(lambda2(
        long fibonacci(int n), int n, 
            n < 2 ? 1 : fibonacci(n-1) + fibonacci(n-2)
        ), 10));

    return 0;
}

1

k2,12个字符

明显的自引用实现最短。这是良好的语言设计的标志。不幸的是,K不是很懒,所以我们只能按值管理电话。

Y:{x[Y[x]]y}

尽管我在下面的示例中假定为k2,但该定义也应该在k4和q中正常工作。

  Y:{x[Y[x]]y}
  fac: {[f;arg] :[arg>0; arg*f[arg-1]; 1]}
  Y[fac] 5
120
  fib: {[f;arg] :[arg>1; f[arg-1] + f[arg-2]; arg]}
  Y[fib]' !10
0 1 1 2 3 5 8 13 21 34

适度的18个字符可以让我们准确地转录(λx. x x) (λxyz. y (x x y) z)为K。

{x[x]}{y[x[x;y]]z}

也许有一天(k7?),看起来可能像Y:{x Y x}


0

Python 3,30字节

Y=lambda f:lambda a:f(Y(f))(a)

演示:

Y=lambda f:lambda a:f(Y(f))(a)
quicksort = Y(
lambda f:
    lambda x: (
        f([item for item in x if item < x[0]])
        + [y for y in x if x[0] == y]
        + f([item for item in x if item > x[0]])
    ) if x
    else []
)
print(quicksort([1, 3, 5, 4, 1, 3, 2]))

学分:https : //gist.github.com/WoLpH/17552c9508753044e44f


Python 3具有过滤器。我也很抱歉忽略了此评论是一个玩笑
Cyoce '16

Python 3的过滤器返回过滤器对象而不是列表。使用过滤器将较不易读或Python式。
Labo

这将是较少的Pythonic,但更多的是函数式编程,这就是我的观点
Cyoce '16
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.