Kết hợp điểm cố định


9

Viết một tổ hợp điểm cố định bằng càng ít ký tự càng tốt, bằng ngôn ngữ bạn chọn.

  • hình thức miễn phí ( nghĩa là bất cứ điều gì ngắn nhất): toàn bộ chương trình, chức năng thực tế, đoạn mã
  • bạn không thể sử dụng thư viện tiêu chuẩn của mình nếu nó có
  • tuy nhiên bạn có thể trích xuất nó từ các chức năng cấp cao khác mà bạn muốn làm điều đó hơn là xây dựng nó từ các cơ sở

Vui lòng bao gồm một giai thừa đệ quy hoặc Fibonacci sử dụng nó làm bản demo.

Trong câu hỏi này, tự tham chiếu là chấp nhận được, mục đích chỉ là loại bỏ nó khỏi chức năng đệ quy mà nó sẽ áp dụng.


Là một ngôn ngữ lười biếng ok? (Bạn có chấp nhận (define Y(lambda(f)(f(Y f))))không?)
Eelvex

Bất kỳ triển khai nào bạn có thể chứng minh với một trong những ví dụ được yêu cầu là ok.
JB

1
Nếu tôi không nhầm, nói đúng ra, thuật ngữ "Y combinator" chỉ cụ thể là một tổ hợp điểm cố định duy nhất được phát hiện bởi Haskell Curry, λf. (X.f (xx)) (x.f (xx)).
Joey Adams

@Eelvex: Rõ ràng cả hai câu trả lời cho đến nay (bao gồm cả câu trả lời của chính OP) đều sử dụng cách gian lận, vì vậy, tôi đoán điều đó làm cho nó ổn. :-P Cá nhân, tôi muốn đi theo cách tiếp cận của @ Joey và nói rằng chỉ có người kết hợp Y thực sự (không tự giới thiệu) mới làm. ;-)
Chris Jester-Young

@Chris: Ôi trời. Đó là những gì tôi đã nghĩ trong đầu, và sau đó tôi ... quên trên đường đi. Bây giờ đã quá muộn để thay đổi, chúng ta sẽ phải mở một câu hỏi khác.
JB

Câu trả lời:


13

Haskell: 10 ký tự

y f=f$y f

Ví dụ về việc sử dụng để tạo các định nghĩa đệ quy của giai thừa hoặc giai đoạn thứ 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]

Mặc dù, một cách phổ biến hơn để sử dụng ysẽ là tạo ra các chuỗi này trực tiếp, chứ không phải là các hàm:

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

Tất nhiên, với Haskell, điều này hơi giống với việc bắn cá vào thùng! Các Data.Functionthư viện có chức năng này, được gọi là fix, mặc dù thực hiện phần nào một cách chi tiết hơn.


4

Perl, 37

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

Trình diễn nhân tố:

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

Trình diễn Fibonacci:

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 ký tự

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

Thí dụ:

#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 char

Việc thực hiện tự tham khảo rõ ràng là ngắn nhất. Đây là một dấu hiệu của thiết kế ngôn ngữ tốt. Thật không may, K không lười biếng, vì vậy chúng tôi chỉ có thể quản lý cuộc gọi theo giá trị.

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

Định nghĩa này cũng sẽ hoạt động trong k4 và q mà không gặp rắc rối, mặc dù tôi giả sử k2 cho các ví dụ dưới đây.

  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 ký tự khiêm tốn hơn cho phép chúng tôi phiên âm chính xác (λx. x x) (λxyz. y (x x y) z)thành K.

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

Có lẽ một ngày nào đó (k7?), Điều này có thể trông như thế nào Y:{x Y x}.


0

Python 3, 30 byte

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

Bản giới thiệu :

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]))

Tín dụng: https://gist.github.com/WoLpH/17552c9508753044e44f


Python 3 có bộ lọc. Ngoài ra, tôi xin lỗi, tôi đã bỏ qua việc đánh dấu nhận xét đó là một trò đùa
Cyoce

Bộ lọc của Python 3 trả về một đối tượng bộ lọc chứ không phải danh sách. Nó sẽ ít đọc hoặc pythonic để sử dụng bộ lọc.
Labo

nó sẽ ít Pythonic hơn, nhưng phù hợp hơn là lập trình chức năng , đó là quan điểm của tôi
Cyoce
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.