Gamma Function Golf


17

กำหนดจำนวนจริงtใน(-10^9,13)(ไม่รวม-10^9หรือ13) เป็นอินพุตเอาต์พุตΓ(t)หรือที่เรียกว่าฟังก์ชันแกมมาซึ่งกำหนดไว้ดังนี้:

นิยามฟังก์ชันแกมมา

คุณไม่สามารถใช้ฟังก์ชันแกมมาในตัวเพื่อแก้ปัญหานี้และห้ามใช้ฟังก์ชันการรวมตัวเลขหรือสัญลักษณ์ในตัว ผลลัพธ์ของคุณควรถูกต้องถึง 6 ตัวเลขที่มีนัยสำคัญหรือภายใน10^-6มูลค่าจริงแล้วแต่จำนวนใดจะน้อยกว่าสำหรับค่าที่กำหนด ฟังก์ชันแกมมาในตัวของ Python จะถูกใช้เพื่อกำหนดค่าจริง คุณอาจจะสมมติΓ(t)ถูกกำหนด - นั่นคือtเป็นทั้งจำนวนจริงบวกหรือเป็นจำนวนจริงที่ไม่ใช่จำนวนเต็มลบ - |Γ(t)| ≤ 10^9และ นี่คือโปรแกรมอ้างอิงที่คุณอาจใช้เพื่อรับค่าจริงโดยใช้ฟังก์ชันแกมม่าในตัวของ Python

ตัวอย่าง

1 -> 1.000000
-2.5 -> -0.945309
3.14159265 -> 2.288038
-2.71828182846 -> -0.952682
12 -> 39916800.000000
0.5 -> 1.772454
8.675309 -> 20248.386956
-10.1 -> -0.000002

กฎระเบียบ

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

ลีดเดอร์บอร์ด

สแต็คส่วนย่อยที่ด้านล่างของโพสต์นี้สร้างกระดานแต้มนำจากคำตอบ a) เป็นรายการคำตอบสั้นที่สุดต่อภาษาและ b) เป็นกระดานแต้มนำโดยรวม

เพื่อให้แน่ใจว่าคำตอบของคุณปรากฏขึ้นโปรดเริ่มคำตอบด้วยหัวข้อโดยใช้เทมเพลต Markdown ต่อไปนี้:

## Language Name, N bytes

ที่Nมีขนาดของส่งของคุณ หากคุณปรับปรุงคะแนนของคุณคุณสามารถเก็บคะแนนเก่าไว้ในพาดหัวโดยการตีพวกเขาผ่าน ตัวอย่างเช่น

## Ruby, <s>104</s> <s>101</s> 96 bytes

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

## Perl, 43 + 2 (-p flag) = 45 bytes

คุณยังสามารถตั้งชื่อภาษาให้เป็นลิงค์ซึ่งจะปรากฏในตัวอย่างข้อมูล:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


1
โปรดระบุขอบเขตที่ชัดเจนสำหรับ t เช่นนั้น | gamma (t) | <10 ^ 9
flawr

ลิงก์ไม่ใช่การใช้งานอ้างอิง ...
sergiol

@sergiol Reworded มัน
Mego

คำตอบ:


2

Pyth, 21 ไบต์

เช่นเดียวกับคำตอบ TI-BASIC ของฉันฉันไม่สามารถทดสอบได้ด้วยการทำซ้ำ 8 ^ 10 เต็มรูปแบบ แต่ทุกอย่างดูดีในกรณีที่เล็กกว่า

cu*Gc^hc1HQhcQHS^8T1Q

คำอธิบาย:

                            [implicit: Q=input]
                ^8T         8**10
               S^8T         [1,2,3,...,8**10]
  *Gc^hc1HQhcQH             lambda G,H:G*(1+1/H)**Q/(1+Q/H)
                   1        Base case
 u*Gc^hc1HQhcQHS^8T1        Reduce with base case 1
c                   Q       Divide by Q

ลองที่นี่ด้วยซ้ำ 2000 แทนที่จะเป็น 8 ^ 10


10

C ++ 14, 86 85 81 ไบต์

[](auto t){auto v=1.;for(int x=1;x<1e9;++x)v*=pow(1+1./x,t)/(1+t/x);return v/t;};

ฉันไม่ได้ใช้เวลามากกับอันนี้ ฉันเพิ่งดูการประมาณที่ดูเหมือนจะง่ายที่สุดที่จะใช้ (ในลักษณะของไบต์) จะใช้เวลาสักครู่ในการคำนวณค่า (เนื่องจากการวนซ้ำมีค่าเป็นจำนวนเต็มบวกทั้งหมด) แต่การ จำกัด เวลาไม่ได้ระบุในการท้าทาย มันเป็นฟังก์ชั่นที่ไม่ระบุชื่อ (แลมบ์ดา) ซึ่งรับอาร์กิวเมนต์ใด ๆ Tที่pow(double, T)และoperator/(T,int)สามารถเรียกว่า) doubleและผลตอบแทน

Ungolfed กับการใช้งาน

#include <iostream>
int main()
{
    auto r = [](auto t)
    {
        auto v = 1.;
        for (int x = 1; x < 1e9; ++x)
            v *= pow(1 + 1. / x, t) / (1 + t / x);
        return v / t;
    };
    std::cout << r(-2.71828182846); // outputs -0.952682
}

@ Mego แน่นอนมันเป็น! ขอบคุณ
Zereges

แล้วคุณจะได้ค่าอะไรสำหรับ -10 ^ 9 และ 10 ^ 9? ก่อนอื่นฉันต้องการทราบว่าเนื้อหาของคุณทำงานได้ดีเพียงใดก่อนที่คุณจะได้รับการโหวตขึ้น
ข้อบกพร่อง

@ ผู้เรียบเรียงไมโครซอฟท์ไม่จำเป็นต้องมีของเหล่านี้รวมถึง
Zereges

@MegoMicrosoft (R) C/C++ Optimizing Compiler Version 19.00.23026 for x86
Zereges

@flawr Mine โปรแกรมเอาต์พุต 0 สำหรับgamma(-10e9)แต่ OP ระบุว่าต้องพิจารณาเฉพาะพารามิเตอร์ที่กำหนดฟังก์ชันแกมม่าเท่านั้น gamma(10e9)ผลตอบแทนinfในขณะที่ฟังก์ชั่นแกมมาในตัวของไพ ธ อนจะถูกนำมาใช้ในการกำหนดมูลค่าที่แท้จริงพูดว่าOverflowError: math range error
Zereges

7

Minkolang 0.12 , 35 34 25 ไบต์

n$zl8;dz;z$:r[i1+dz+$:*]N

นี้ไม่หยุดกับข้อผิดพลาด (ในการพยายามที่จะหารด้วย 0) แต่ที่ได้รับอนุญาตตามMeta ฉันทามติ เพิ่ม.ท้ายเพื่อโปรแกรมที่หยุดตามปกติ ลองกรณีทดสอบทั้งหมดในครั้งเดียว (การวนซ้ำวนซ้ำเพียง 1e4 ครั้งดังนั้นมันจะเสร็จเร็วกว่าแทนในภายหลัง)

คำอธิบาย

Zereges ใช้เป็นหนึ่งในทางเลือกที่คำจำกัดความสินค้าที่ไม่มีที่สิ้นสุด เมื่อมันปรากฏออกมาคนอื่น ๆ ก็มีความสุขมากกว่าที่จะนำไปใช้ในมิงโกลัง

สูตรทางเลือกของออยเลอร์ของฟังก์ชันแกมม่า

นี่เป็นขีด จำกัด สำหรับnไปที่อินฟินิตี้ซึ่งหมายความว่าฉันสามารถคำนวณทั้งสองn!และ(t+n)ไปได้ ดังนั้นผมจึงจะออก1/t(เพราะ0!=1) และเนื่องจากว่าไม่สามารถคำนวณได้ตามลำดับโดยไม่ทราบว่าค่าสิ้นสุดของn^t nอย่างที่มันnเป็นเพราะขีด จำกัด ฉันสามารถใช้ได้สองครั้ง ครั้งหนึ่งเคยเป็นปัจจัยในการคำนวณและจำนวนครั้งที่จะเรียกใช้วง

เป็นผลิตภัณฑ์ที่ไม่มีที่สิ้นสุดตามลำดับมีการเริ่มต้นกับสิ่งที่มัก 1. n^t/tในกรณีนี้ก็คือ ในร่างกายของลูปฉันคำนวณk/(t+k)และคูณกับผลิตภัณฑ์จนถึงตอนนี้ ในตอนท้ายผลิตภัณฑ์ทั้งหมดได้รับการคำนวณและส่งออก นี่คือสิ่งที่โปรแกรมของฉันทำมีnสูงพอที่คำตอบนั้นแม่นยำพอ

เวอร์ชั่นขยายตัวของผลิตภัณฑ์ไม่มีที่สิ้นสุด

n                            Take number from input
 $z                          Store it in the register (this is t; retrieved with z)
   l8;                       10^8 (this is n, the limit)
      d                      n,n
       z;                    n,n^t
         z$:                 n,n^t/t
            r                Reverse stack -> n^t/t,n
             [               For loop that runs n times
              i1+            k
                 d           k,k
                  z+         k,t+k
                    $:       k/(t+k)
                      *      Multiply
                       ]N    Close for loop and output as integer

เนื่องจากไม่มี.มันจะล้อมรอบและเริ่มต้นใหม่ อย่างไรก็ตามnตอนนี้สร้างขึ้น-1เนื่องจากอินพุตว่างเปล่าซึ่งท้ายที่สุดจะนำไปสู่การพยายามหารด้วย 0 ซึ่งหยุดโปรแกรม


5

Julia, 141 ไบต์

z->(z-=1;a=90;c(k)=(k=big(k);(-1)^(k-1)/factorial(k-1)*(a-k)^(k-.5)*exp(a-k));(z+a)^(z+.5)*exp(-z-a)*(√(2π)+sum([c(k)/(z+k)for k=1:a-1])))

สิ่งนี้จะสร้างฟังก์ชั่นแลมบ์ดาที่ไม่มีชื่อที่รับจำนวนจริงและส่งกลับจำนวนจริง มันใช้การประมาณของ Spoungeเพื่อคำนวณแกมมา

Ungolfed:

function Γ(z::Real)
    # Spounge's approxmation is for Γ(z+1), so subtract 1
    z -= 1

    # Choose a number for the constant a, which determines the
    # bound on the error
    a = 90

    # Define a function for the sequence c_k
    function c(k::Integer)
        # Convert k to a BigInt
        k = big(k)
        return (-1)^(k-1) / factorial(k-1) * (a-k)^(k-1/2) * exp(a-k)
    end

    # Compute the approximation
    return (z+a)^(z+1/2) * exp(-z-a) * (√(2π) + sum([c(k)/(z+k) for k=1:a-1]))
end

มากมากกอล์ฟปลาย แต่z->(z-=1;a=90;c(k)=(k=big(k);(-1)^~-k/factorial(k-1)*(a-k)^(k-.5)*exp(a-k));(z+a)^(z+.5)*exp(-z-a)*(√(2π)+sum(c(k)/(z+k)for k=1:a-1)))ควรจะทำงานสำหรับ 137 ไบต์ (อย่างน้อยในจูเลีย 0.6)
นาย Xcoder

3

Japt, 45 ไบต์

Japtเป็นรุ่นสั้นJa vaScri พอยต์ ล่าม

$for(V=X=1;X<1e9;)$V*=(1+1/X pU /(1+U/X++;V/U

แน่นอน 1e9 = 1,000,000,000 ซ้ำตลอดเวลาดังนั้นสำหรับการทดสอบลองเปลี่ยนด้วย9 6(1e6 นั้นมีความแม่นยำถึง ~ 5 ตัวเลขสำคัญการใช้ 1e8 ในอินพุตของ12นั้นเพียงพอที่จะได้รับหกครั้งแรก)

ผลการทดสอบกรณี: (ใช้ความแม่นยำ 1e7)

       1:  1
    -2.5: -0.9453083...
      pi:  2.2880370...
      -e: -0.9526812...
      12:  39916536.5...
     0.5:  1.7724538...
8.675309:  20248.319...
   -10.1: -0.0000022...

มันทำงานอย่างไร

         // Implicit: U = input number
$for(    // Ordinary for loop.
V=X=1;   //  Set V and X to 1.
X<1e9;)$ //  Repeat while X is less than 1e9.
V*=      // Multiply V by:
(1+1/X   //  1 plus (1 over X),
pU /     //  to the power of U, divided by
(1+U/X++ //  1 plus (U over X). Increment X by 1.
;V/U     // Output the result of (V over U).

3

TI-BASIC, 35 ไบต์

Input Z
1
For(I,1,ᴇ9
Ans(1+I⁻¹)^Z/(1+Z/I
End
Ans/Z

ใช้อัลกอริธึมเดียวกันกับ Zereges

Caveat: ฉันยังไม่ได้ทดสอบสิ่งนี้กับการทำซ้ำ 1e9 ทั้งหมด ขึ้นอยู่กับเวลาที่ค่าขนาดเล็กที่ฉันคาดหวังรันไทม์ที่จะอยู่ในคำสั่งของเดือน อย่างไรก็ตามดูเหมือนว่าจะมาบรรจบกันและไม่ควรมีปัญหากับข้อผิดพลาดในการปัดเศษ TI เก็บตัวเลขเป็นทศนิยมทศนิยมด้วยความแม่นยำ 14 หลัก


คุณไม่ได้ทดสอบเหรอ!
TanMath

1
@ TanMath ฉันต้องการ แต่ฉันต้องการเครื่องคิดเลขสำหรับการสอบปลายภาคในเดือนหน้า
lirtosiast

3

Python 3, 74 68 78 73 ไบต์

ขอบคุณ @Mego และ @xnor

นี่คือการแปลของคำตอบ C ++ โดย Zereges โดยพื้นฐานแล้วนี่คือคำจำกัดความอื่นของฟังก์ชันแกมมาดังนั้นจึงมีความแม่นยำมากขึ้น (และสิ่งที่ยอดเยี่ยมมากคือใช้ไบต์น้อยกว่า!)

ฉันขอโทษสำหรับความผิดพลาดทั้งหมด!

def g(z,v=1):
 for i in range(1,10**9):v*=(1+1/i)**z/(1+z/i)
 return v/z

1
+1ในช่วงไม่สำคัญเมื่อคุณกำลังติดต่อกับพันล้าน นอกจากนี้คุณควรระบุว่านี่คือ Python 3 - คุณจะต้องfrom __future__ import divisionใช้การแบ่งทศนิยมและ RAM สักสองสามเทราไบต์เพื่อจัดการกับความจริงที่rangeส่งคืนรายการใน Python 2 นอกจากนี้คุณสามารถแทนที่1.0s ด้วย1และกำจัด 4 ไบต์
Mego

2
@TanMath: ^xor คุณไม่ได้หมายถึง**การยกกำลังหรือเปล่า?
jermenkoo

3
int(1e9)เป็นเพียง10**9และคุณไม่จำเป็นต้อง parens (1+1/i)**zรอบ
xnor

3

Python, 348 448 407 390 389 ไบต์

ขอขอบคุณเป็นพิเศษกับ @Mego!

เครื่องหมายกากบาท 448 คือ (เกือบ) ยังเป็น 448! : p

สิ่งนี้ขึ้นอยู่กับการประมาณ Lanzcos กอล์ฟจากที่นี่

from cmath import*
C=[0.9999999999998099,676.5203681218851,-1259.1392167224028,771.3234287776531,-17‌6.6150291621406,12.507343278686905,-0.13857109526572012,9.984369578019572e-6,1.5‌​056327351493116e-7]
def g(z):
 z-=1;if z.real<0.5:return pi/(sin(pi*z)*gamma(1-z))
 else:
  x=C[0]
  for i in range(1,9):x+=C[i]/(z+i)
  t=z+7.5;return sqrt(2*pi)*t**(z+0.5)*exp(-t)*x

1
โปรดตีกอล์ฟของคุณโดยลบอย่างน้อยหนึ่งช่องว่าง (ช่องว่างก่อนและหลัง - = และimport *ตัวอย่างเช่น) และใช้ชื่อฟังก์ชั่นหนึ่งตัวอักษร นอกจากนี้โปรดทราบว่าคุณต้องรองรับอินพุตจริงเท่านั้น
lirtosiast

@ThomasKwa ฉันได้แก้ไขแล้ว เวอร์ชันเดิมของฉันใช้งานไม่ได้นี่เป็นเวอร์ชั่นใหม่
TanMath

@Mego แก้ไข ...
TanMath

สิ่งนี้ทำให้เกิดข้อผิดพลาดในการเรียกซ้ำ - ลบz-=1;ในบรรทัดแรกของgammaเพื่อแก้ไข นอกจากนี้คุณควรเปลี่ยนชื่อgammaเพื่อไบต์ช่วยประหยัดและเพื่อหลีกเลี่ยงความขัดแย้งกับการตั้งชื่อg cmath.gammaยังวางเลขศูนย์นำที่ไม่เกี่ยวข้อง
Mego

1

Julia, 41 ไบต์

x->prod([(1+1/i)^x/(1+x/i)for i=1:1E7])/x

นี่คือการแปลคำตอบของ Zereges 'C ++ ในขณะที่จูเลียคนอื่น ๆ ของฉันตอบคำถามเสร็จในทันทีมันค่อนข้างช้า มันคำนวณกรณีทดสอบในไม่กี่วินาทีในคอมพิวเตอร์ของฉัน

Ungolfed:

function f(x::Real)
    prod([(1 + 1/i)^x / (1 + x/i) for i = 1:1E7]) / x
end

1

อารัมภบท, 114 ไบต์

นี่คือการแปลคำตอบของ Zereges 'C ++

q(F,F,V,Z):-X is V/Z,write(X).
q(F,T,V,Z):-W is(1+1/F)**Z/(1+Z/F)*V,I is F+1,q(I,T,W,Z).
p(N):-q(1.0,1e9,1,N),!.

ลองออนไลน์ได้ที่นี่
ใช้กับแบบสอบถามแบบฟอร์ม:

p(12).

เรียกใช้ด้วยการเรียกซ้ำ 1e9 ใช้เวลาประมาณ 15 นาที
หากคุณลดลงเป็น 1e6 จะใช้เวลาประมาณ 1 วินาทีซึ่งจะทำให้การทดสอบง่ายขึ้น (แต่ลดน้อยลง)
การใช้งานในล่ามกับคอมพิวเตอร์ / แล็ปท็อปของคุณน่าจะเร็วกว่าสำหรับคนส่วนใหญ่เช่นกัน


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