Combinator จุดคง Golfed


9

เขียนcombinator จุดคงที่ในตัวละครน้อยที่สุดในภาษาที่คุณเลือก

  • รูปแบบอิสระ ( เช่นอะไรก็ตามที่สั้นที่สุด): ทั้งโปรแกรมฟังก์ชันที่แท้จริงโค้ดขนาดสั้น
  • คุณไม่สามารถใช้ไลบรารีมาตรฐานของคุณถ้ามันมี
  • อย่างไรก็ตามคุณสามารถดึงมันออกมาจากฟังก์ชั่นระดับสูงอื่น ๆ ที่คุณต้องการทำมากกว่าสร้างจากฐาน

โปรดรวมแฟกทอเรียลแบบเรียกซ้ำหรือฟีโบนักชีที่ใช้เป็นตัวอย่าง

ในคำถามนี้การอ้างอิงตนเองเป็นที่ยอมรับจุดมุ่งหมายนั้นเพียงเพื่อลบออกจากฟังก์ชั่นวนซ้ำที่จะนำไปใช้


การใช้ภาษาที่ขี้เกียจนั้นโอเคไหม? (คุณจะยอมรับ(define Y(lambda(f)(f(Y f))))ไหม)
Eelvex

การใช้งานใด ๆ ที่คุณสามารถสาธิตได้ด้วยตัวอย่างที่ร้องขออย่างใดอย่างหนึ่งก็โอเค
JB

1
ถ้าฉันไม่เข้าใจผิดพูดอย่างเคร่งครัดคำว่า "Y combinator" หมายถึงตัวแก้ไข combinator เดียวที่ค้นพบโดย Haskell Curry, λf. (λx.f (xx)) (λx.f (xx))
Joey Adams

@ สิบสอง: เห็นได้ชัดว่าทั้งสองคำตอบจนถึง (รวมถึงคำตอบของ OP) ใช้วิธีการโกงดังนั้นฉันเดาว่ามันไม่เป็นไร :-P โดยส่วนตัวแล้วฉันอยากจะไปกับวิธีการของ @ Joey และพูดว่ามีเพียงผู้ประสานงาน Y ที่แท้จริง (ไม่ใช่อ้างอิงตนเอง) เท่านั้นที่จะทำได้ ;-)
Chris Jester-Young

@Chris: โอ้ฉัน นั่นคือสิ่งที่ฉันมีอยู่ในใจในตอนแรกและจากนั้นฉัน ... ลืมไปตลอดทาง มันสายเกินไปที่จะเปลี่ยนแปลงตอนนี้เราจะต้องเปิดคำถามอีกข้อ
JB

คำตอบ:


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แม้ว่าการดำเนินการค่อนข้างมาก verbosely


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;

การสาธิต 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 ตัวอักษร

#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 น้อยกว่าการใช้ตัวกรอง
Labo

มันจะ Pythonic น้อยลง แต่สิ่งที่เพิ่มเติมคือการเขียนโปรแกรมใช้งานได้ซึ่งเป็นประเด็นของฉัน
Cyoce
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.