伽玛功能高尔夫


17

给定的实数t(-10^9,13)(不包括-10^913)作为输入,输出Γ(t),也被称为伽玛函数,其定义如下:

伽玛函数定义

您不得使用内置的Gamma函数来解决此任务,也不得使用内置的数字或符号积分函数。您的输出应精确到6个有效数字或在10^-6实际值以内,以对给定值的限制较小为准。Python的内置Gamma函数将用于确定实际值。您可能会假设Γ(t)已定义-即是t正实数或非整数负实数-且那个|Γ(t)| ≤ 10^9是一个参考程序,您可以使用它使用Python的内置Gamma函数来获取实际值。

例子

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
瑕疵

该链接不是参考实现,...
sergiol

@sergiol改写了它
Mego,

Answers:


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

我没有花太多时间在这上面。我只是看了看似最容易实现的近似值(以字节的方式)。计算该值将花费一些时间(因为循环遍历所有正整数),但是挑战中未指定时间限制。它是匿名函数(lambda),它接受任何参数(可转换为 Ton pow(double, T)operator/(T,int)可以调用),并返回double

放心使用

#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,您获得什么价值?首先,我想知道您的工作效果如何,然后再得到我的支持。
flawr

@Mego Microsoft编译器不需要这两个主题。
Zereges

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

@flawr我的程序的输出为0,gamma(-10e9)但OP声明,只能考虑为其定义了伽马函数的参数。gamma(10e9)返回值inf,而Python的内置Gamma函数将用于确定实际值,则表示OverflowError: math range error
Zereges 2015年

7

Minkolang 0.1235个 34 25字节

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

这确实会因错误而停止(尝试除以0时),但是根据Meta共识允许。.在正常停止的程序的末尾添加a 。一次尝试所有测试用例。(该循环仅迭代1e4次,因此它会尽早完成,而不是稍后完成。)

说明

Zereges使用了一种替代的无限产品定义。事实证明,另一个更适合在Minkolang中实现。

欧拉的伽马函数替代公式

这是一个极限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

朱莉娅,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])))

这将创建一个未命名的lambda函数,该函数接受一个实数并返回一个实数。它使用Spounge的近似值来计算Gamma。

取消高尔夫:

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个字节(至少在Julia 0.6中有效)
Xcoder先生,18年

3

Japt,45个字节

JaptJa vaScri pt的缩写。口译员

$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相同的算法。

警告:我尚未真正使用完整的1e9迭代进行测试;基于较小值所花费的时间,我希望运行时约为几个月。但是,它似乎收敛了,四舍五入错误应该没有问题。TI将数字存储为14位精度的十进制浮点数。


您没有测试吗?
TanMath

1
@TanMath我愿意,但是下个月我需要我的计算器进行期末考试。
lirtosiast

3

Python 3,74 68 78 73字节

谢谢@Mego和@xnor

这是Zereges对C ++答案的翻译。基本上,这是gamma函数的替代定义,因此更准确(并且最大的好处是使用了更少的字节!)

我为所有的错误感到抱歉!

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进行浮点除法和数TB的RAM来处理range在Python 2 中返回列表的事实。此外,您可以将1.0s 替换为1s并削除4个字节。
Mego 2015年

2
@TanMath:^是xor,您不是说**求幂吗?
jermenkoo

3
int(1e9)是公正的10**9,而且你不需要周围的人(1+1/i)**z
xnor

3

蟒蛇, 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 2015年

这会导致递归错误-删除z-=1;的第一行以gamma进行修复。您还应该重命名gamma为,g以节省字节并避免与命名冲突cmath.gamma。还要删除无关的前导零。
Mego 2015年

1

朱莉娅,41个字节

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

这是Zereges C ++答案的翻译。当我的其他Julia答案立即完成时,这相当慢。它在我的计算机上每秒钟计算测试用例。

取消高尔夫:

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

1

Prolog,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秒钟,这将使测试更容易(但不那么精确)。
对大多数人来说,在计算机/笔记本电脑上的解释器中运行它也可能更快。


0

Mathematica,40个字节

NProduct[(1+1/n)^#/(1+#/n),{n,1,∞}]/#&
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.