Gama Fonksiyonu Golf


17

Gerçek sayısı göz önüne alındığında tiçinde (-10^9,13)(dahil değil -10^9veya 13giriş, çıkış gibi) Γ(t)olarak da bilinen, Gama fonksiyonu şu şekilde tanımlanmıştır:

gama fonksiyonu tanımı

Bu görevi çözmek için yerleşik bir Gamma işlevi veya yerleşik sayısal veya sembolik entegrasyon işlevleri kullanamazsınız. Çıktınız 10^-6, verilen değer için daha az kısıtlayıcı olan 6 önemli rakama veya gerçek değere uygun olmalıdır. Gerçek değeri belirlemek için Python'un yerleşik Gamma işlevi kullanılacaktır. Bir pozitif gerçek sayı veya tamsayı olmayan negatif gerçek bir sayı Γ(t)tanımlandığını varsayabilirsiniz . İşte Python'un yerleşik Gamma işlevini kullanarak gerçek değerleri elde etmek için kullanabileceğiniz bir referans programı.t|Γ(t)| ≤ 10^9

Örnekler

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

kurallar

  • Bu , çok kısa cevap (bayt cinsinden) kazanır.
  • Standart boşluklar yasaktır.
  • Giriş ve çıkış, diliniz için standart kabul edilen herhangi bir şekilde gerçekleştirilebilir.
  • Tam bir program, bir işlev veya normal olarak diliniz için geçerli bir yanıt olarak kabul edilen herhangi bir şey yazabilirsiniz

Liderler Sıralaması

Bu yazının altındaki Yığın Snippet'i, a) her dil için en kısa çözüm listesi ve b) genel bir lider tablosu olarak cevaplardan lider tablosunu oluşturur.

Yanıtınızın göründüğünden emin olmak için lütfen aşağıdaki Markdown şablonunu kullanarak yanıtınızı bir başlıkla başlatın:

## Language Name, N bytes

Ngönderiminizin büyüklüğü nerede . Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

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

Başlığınıza birden fazla sayı eklemek istiyorsanız (örneğin, puanınız iki dosyanın toplamı olduğu veya yorumlayıcı bayrak cezalarını ayrı olarak listelemek istediğiniz için), gerçek puanın başlıktaki son sayı olduğundan emin olun :

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

Dil adını, daha sonra snippet'te görünecek bir bağlantı da yapabilirsiniz:

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


1
Lütfen t için açık sınırlar verin ki | gama (t) | <10 ^ 9
flawr

Bağlantı bir referans uygulaması değil, ...
sergiol

@sergiol Reworded
Mego

Yanıtlar:


2

Pyth, 21 bayt

TI-BASIC yanıtımda olduğu gibi, bunu tam 8 ^ 10 yineleme ile test edemedim, ancak her şey daha küçük vakalarda iyi görünüyor.

cu*Gc^hc1HQhcQHS^8T1Q

Açıklama:

                            [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

Burada 8 ^ 10 yerine 2000 yineleme ile deneyin .


10

C ++ 14, 86 85 81 bayt

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

Bunun için fazla zaman harcamadım. Ben sadece (bayt biçiminde) uygulamak en kolay gibi görünüyordu yaklaşımı baktı. Değerin hesaplanması biraz zaman alacaktır (döngü tüm pozitif tamsayıların üzerinde olduğundan), ancak meydan okumada zaman sınırlaması belirtilmemiştir. Anonim bir işlevdir (lambda), herhangi bir argümanı alır ( Tbunlara dönüştürülebilir pow(double, T)ve operator/(T,int)çağrılabilir) ve döndürürdouble .

Kullanımdan bağımsız

#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 Tabii ki öyle! Teşekkürler.
Zereges

Peki -10 ^ 9 ve 10 ^ 9 için hangi değeri elde edersiniz? Benim oyumu almadan önce eşyalarınızın ne kadar iyi çalıştığını bilmek istiyorum.
Kusur

@Mego Microsoft derleyicisinin hiçbirine ihtiyaç duymaz.
Zereges

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

@flawr Mine programı çıktılar, gamma(-10e9)ancak OP için , yalnızca gama işlevinin tanımlandığı parametrelerin dikkate alınabileceğini belirtti. gamma(10e9)döner inf, Python'un dahili Gamma işlevi gerçek değeri belirlemek için kullanılacağını söylüyorOverflowError: math range error
Zereges

7

Minkolang 0.12 , 35 34 25 bayt

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

Bu bir hata ile durur (0'a bölmeye çalışırken), ancak Meta konsensüsüne izin verilir . .Normal olarak duran bir programın sonuna a ekleyin . Tüm test senaryolarını bir kerede deneyin. (Döngü yalnızca 1e4 kez yinelenir, böylece daha sonra değil, daha erken biter.)

açıklama

Zereges alternatif, sonsuz ürün tanımlarından birini kullandı . Anlaşıldığı üzere, diğeri Minkolang'da uygulamaya çok daha uygundur.

Euler's alternative formulation of the gamma function

Gibi bu bir sınırdır nben hem hesaplayabilirsiniz olduğunu hangi araçlar, sonsuza gider n!ve (t+n)ben gitmek gibi. Ben çıkarıyorum 1/t(çünkü 0!=1) ve n^tçünkü bunun bitiş değerini bilmeden sıralı olarak hesaplanamaz n. Olduğu gibi, çünkün , sınır , iki kez kullanabilirim. Bir kez hesaplamada bir faktör olarak ve bir kez de döngüyü çalıştırma sayısı olarak.

Sıralı sonsuz bir ürün genellikle 1 ile başlamalıdır. Bu durumda, öyle n^t/t. Döngünün gövdesinde, bunu k/(t+k)şimdiye kadar ürünle hesaplayıp çarparım. Sonunda, tüm ürün hesaplandı ve çıktılandı. Bu benim programımın yaptığı, ncevabın yeterince kesin olduğu kadar yüksek.

exploded version of the infinite product

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

Hayır olmadığı için .etrafı sarar ve baştan başlar. Ancak, nşimdi -1giriş boş olduğu için üretilir, bu da sonunda programı 0'a bölmeye çalışır ve bu da programı durdurur.


5

Julia, 141 bayt

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

Bu, gerçek bir sayıyı kabul eden ve gerçek bir sayı döndüren adsız bir lambda işlevi oluşturur. Gamma'yı hesaplamak için Spounge yaklaşımını kullanır .

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

Çok, çok geç golf, ancak 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 bayt için çalışmalıdır (en azından Julia
0.6'da

3

Japt, 45 bayt

Japt kısaltılmış versiyonudur Ja vaScri nk . yorumlayıcı

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

Tabii ki, 1E9 = 1000000000 yineleme böylece test için, değiştirmeyi deneyin, sonsuza kadar sürer 9bir ile 6. (1e6, ~ 5 önemli rakama doğrudur. 1e8'i girişinde kullanmak 12, ilk altıyı elde etmek için yeterlidir.)

Test senaryosu sonuçları: (1e7 hassasiyet kullanarak)

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

Nasıl çalışır

         // 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 bayt

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

Bu Zereges ile aynı algoritmayı kullanır.

Dikkat: Bunu tam 1e9 yinelemeleriyle test etmedim; daha küçük değerler için harcanan zamana bağlı olarak, çalışma zamanının aylar arasında olmasını bekliyorum . Ancak, yakınsama gibi görünüyor ve yuvarlama hataları ile ilgili herhangi bir sorun olmamalıdır. TI, sayıları 14 basamaklı ondalık sayı olarak kaydeder.


Test etmedin mi ?!
TanMath

1
@TanMath isterim, ama gelecek ay bir final sınavı için hesap makineme ihtiyacım var.
lirtosiast

3

Python 3, 74 68 78 73 bayt

@Mego ve @xnor teşekkürler

Bu Zereges'in C ++ cevabının bir çevirisidir. Temel olarak, bu, gama işlevinin alternatif bir tanımıdır, bu nedenle daha doğrudur (ve harika olan, daha az bayt kullanır!)

Tüm hatalar için özür dilerim!

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

1
+1Eğer milyarlarca verilerle çalışıyorken dizi önemli değildir. Ayrıca, bu Python 3 olduğunu belirtmelidir - Size gereken tek şey from __future__ import divisiongerçeği ile başa çıkmak için şamandıra bölünme ve RAM birkaç terabayt için rangedöner Python 2. Plus listesi, sen yerine 1.0sahip s 1, 4 kapalı s ve tıraş bayt.
Mego

2
@TanMath: ^xor, **üssü demek istemedin mi?
jermenkoo

3
int(1e9)sadece 10**9, ve etraftaki parenslere ihtiyacınız yok (1+1/i)**z.
xnor

3

Python, 348 448 407 390 389 bayt

@Mego'ya özel teşekkürler!

Üzerinde çarpı işareti olan 448 (neredeyse) hala bir 448! : p

Bu Lanzcos yaklaşımına dayanmaktadır. Buradan golf

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
Lütfen gönderiminizi en azından boşlukları kaldırarak ( import *örneğin - öncesi ve sonrası - = ve içindeki boşluklar ) ve tek karakterli bir işlev adı kullanarak golf yapın . Ayrıca, yalnızca gerçek girişi desteklemeniz gerektiğini unutmayın.
lirtosiast

@ThomasKwa Düzenledim. Orijinal sürümüm işe yaramadı, işte daha yeni bir sürüm.
TanMath

@Mego düzenlendi ...
TanMath

Bu bir özyineleme hatasına neden olur - düzeltmek z-=1;için ilk satırındaki öğesini kaldırın gamma. Ayrıca adlandırmak gerekir gammaiçin gbayt kaydeder ve adlandırma çakışmaları önlemek için cmath.gamma. Ayrıca yabancı önde gelen sıfırları da bırakın.
Mego

1

Julia, 41 bayt

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

Bu Zereges'in C ++ cevabının bir çevirisidir. Diğer Julia cevabım anında bitiyor olsa da, bu oldukça yavaş. Bilgisayarımdaki test durumlarını birkaç saniye içinde hesaplar.

Ungolfed:

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

1

Prolog, 114 bayt

Bu Zereges'in C ++ cevabının bir çevirisidir.

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),!.

Çevrimiçi olarak buradan deneyin
Formun bir sorgusuyla çalıştırın:

p(12).

1e9 özyineleme ile çalıştırmak yaklaşık 15 dakika sürer.
Eğer 1e6 değerine düşürürseniz, daha kolay (ancak daha az hassas) testler yapan yaklaşık 1 saniye sürer.
Bilgisayarınızda / dizüstü bilgisayarınızda bir tercümanda çalıştırmak, çoğu insan için de daha hızlıdır.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.