ゴルフされた固定小数点コンビネーター


9

書く不動点コンビネータお好みの言語で、できるだけ少ない文字数では。

  • 自由形式(つまり、最も短いもの):プログラム全体、実際の関数、コードスニペット
  • 標準ライブラリがある場合は使用できません
  • ただし、他の高水準関数から抽出することもできますが、ベースから構築するよりも、そうする方が得策です。

デモとして使用する再帰的な階乗またはフィボナッチを含めてください。

この質問では、自己参照は許容されます。目的は、それを適用する再帰関数からそれを削除することだけです。


遅延言語の実装は大丈夫ですか?(受け入れ(define Y(lambda(f)(f(Y f))))ますか?)
Eelvex、2011

要求された例の1つを使用してデモンストレーションできる実装はすべて問題ありません。
JB

1
私が誤解していない場合、厳密に言えば、「Yコンビネータ」という用語は、Haskell Curryによって発見された単一の固定小数点コンビネータλf。(λx.f(xx))(λx.f(xx))を具体的に指します。
Joey Adams

@Eelvex:明らかに、これまでの両方の回答(OP自身の回答を含む)は不正な方法を使用しているので、それで問題ないと思います。:-P個人的には、@ Joeyのアプローチを使用して、実際の(非自己参照)Yコンビネータのみが実行すると言います。;-)
Chris Jester-Young

@クリス:あらまあ。それは私が最初に考えていたもので、それから私は...途中で忘れていました。今変更するには遅すぎるので、別の質問を開かなければなりません。
JB

回答:


13

Haskell:10文字

y f=f$y f

階乗またはn番目のフィボナッチの再帰的な定義を作成するための使用例:

> 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}

この定義はk4とqでも問題なく機能するはずですが、以下の例ではk2を想定しています。

  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 '

Python 3のフィルターは、リストではなくフィルターオブジェクトを返します。フィルターを使用することは、可読性やpythonicに劣ります。
ラボ、2016年

それはあまりPython的であってもよいが、より多くのラインにあっただろう機能、プログラミング私のポイントだった、
Cyoce
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.