Golf con función gamma

17

Dado un número real ten (-10^9,13)(sin incluir -10^9o 13) como entrada, salida Γ(t), también conocida como la función Gamma , que se define de la siguiente manera:

definición de la función gamma

No puede usar una función Gamma incorporada para resolver esta tarea, ni puede usar funciones de integración numérica o simbólica incorporadas. Su salida debe ser precisa a 6 cifras significativas o dentro 10^-6del valor real, lo que sea menos restrictivo para el valor dado. La función Gamma incorporada de Python se utilizará para determinar el valor real. Puede suponer que Γ(t)está definido, es decir, tes un número real positivo o un número real negativo no entero, y eso |Γ(t)| ≤ 10^9. Aquí hay un programa de referencia que puede usar para obtener los valores reales, utilizando la función Gamma incorporada de Python.

Ejemplos

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

Reglas

  • Este es el , por lo que gana la respuesta más corta (en bytes).
  • Las lagunas estándar están prohibidas.
  • La entrada y la salida se pueden realizar de cualquier manera que se considere estándar para su idioma.
  • Puede escribir un programa completo, una función o cualquier cosa que normalmente se considere una respuesta válida para su idioma

Tabla de clasificación

El Fragmento de pila al final de esta publicación genera la tabla de clasificación a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.

Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:

## Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

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

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

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

También puede hacer que el nombre del idioma sea un enlace que aparecerá en el fragmento:

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

Mego
fuente
1
Proporcione límites explícitos para t tales que | gamma (t) | <10 ^ 9
error
El enlace no es una implementación de referencia, ...
sergiol
@sergiol Reescrito
Mego

Respuestas:

2

Pyth, 21 bytes

Al igual que con mi respuesta de TI-BASIC, no he podido probar esto con las iteraciones completas de 8 ^ 10, pero todo parece bien con casos más pequeños.

cu*Gc^hc1HQhcQHS^8T1Q

Explicación:

                            [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

Pruébelo aquí con 2000 iteraciones en lugar de 8 ^ 10.

lirtosiast
fuente
10

C ++ 14, 86 85 81 bytes

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

No pasé mucho tiempo con este. Solo busqué una aproximación que parecía la más fácil de implementar (en forma de bytes). Tomará algún tiempo calcular el valor (ya que el bucle está sobre todos los enteros positivos), pero la limitación de tiempo no se especifica en el desafío. Es función anónima (lambda), que toma un argumento (convertible Ten la que pow(double, T)y operator/(T,int)puede ser llamado) y vuelve double.

Sin golfos con el uso

#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
}
Zereges
fuente
@Mego ¡Por supuesto que sí! Gracias.
Zereges
Entonces, ¿qué valor obtienes para -10 ^ 9 y para 10 ^ 9? Primero quiero saber qué tan bien funcionan sus cosas antes de recibir mi voto positivo.
falla
@Mego Microsoft compilador no necesita ninguno de estos incluye.
Zereges
@MegoMicrosoft (R) C/C++ Optimizing Compiler Version 19.00.23026 for x86
Zereges
@flawr El programa de mina genera 0 para gamma(-10e9)OP, pero declaró que solo se pueden considerar los parámetros para los que se define la función gamma. gamma(10e9)regresa inf, mientras que la función Gamma incorporada de Python se utilizará para determinar el valor real diceOverflowError: math range error
Zereges
7

Minkolang 0.12 , 35 34 25 bytes

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

Esto se detiene con un error (al tratar de dividir por 0), pero eso está permitido según el consenso de Meta . Agregue un .al final para un programa que se detiene normalmente. Pruebe todos los casos de prueba a la vez.(El bucle itera solo 1e4 veces para que termine más pronto que tarde).

Explicación

Zereges utilizó una de las definiciones alternativas e infinitas de productos . Como resultado, el otro es mucho más fácil de implementar en Minkolang.

La formulación alternativa de Euler de la función gamma

Este es un límite que nva hasta el infinito, lo que significa que puedo calcular ambos n!y sobre la marcha (t+n). Entonces saco 1/t(porque 0!=1) y n^tporque ese no puede calcularse secuencialmente sin conocer el valor final de n. Como sucede, porque nes el límite, puedo usarlo dos veces. Una vez como factor en el cálculo y una vez como el número de veces para ejecutar el ciclo.

Un producto infinito secuencial tiene que comenzar con algo, generalmente 1. En este caso, es n^t/t. En el cuerpo del ciclo, calculo k/(t+k)y multiplico esto con el producto hasta ahora. Al final, todo el producto ha sido calculado y producido. Esto es esencialmente lo que hace mi programa, con un nnivel lo suficientemente alto como para que la respuesta sea lo suficientemente precisa.

versión explotada del producto infinito

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

Como no hay . , se envuelve y comienza de nuevo. Sin embargo, nahora se produce -1porque la entrada está vacía, lo que finalmente lleva a intentar dividir por 0, lo que detiene el programa.

El'endia Starman
fuente
5

Julia, 141 bytes

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

Esto crea una función lambda sin nombre que acepta un número real y devuelve un número real. Usa la aproximación de Spounge. para calcular Gamma.

Sin golf:

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
Alex A.
fuente
Golf muy , muy tarde, pero 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)))debería funcionar para 137 bytes (al menos en Julia 0.6)
Sr. Xcoder
3

Japt, 45 bytes

Japt es una versión abreviada de Ja vaScri pt . Interprete

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

Por supuesto, 1e9 = 1,000,000,000 de iteraciones toma una eternidad, así que para probar, intente reemplazar el 9con a 6. (1e6 tiene una precisión de ~ 5 cifras significativas. Usar 1e8 en una entrada de 12es suficiente para obtener los primeros seis).

Resultados de casos de prueba: (utilizando precisión 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...

Cómo funciona

         // 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).
ETHproducciones
fuente
3

TI-BASIC, 35 bytes

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

Esto usa el mismo algoritmo que Zereges.

Advertencia: en realidad no he probado esto con las iteraciones completas de 1e9; basado en el tiempo necesario para valores más pequeños, espero que el tiempo de ejecución sea del orden de meses . Sin embargo, parece converger, y no debería haber problemas con los errores de redondeo. TI almacena números como flotantes decimales con 14 dígitos de precisión.

lirtosiast
fuente
¿No lo probaste?
TanMath
1
@TanMath Lo haría, pero necesito mi calculadora para un examen final el próximo mes.
lirtosiast
3

Python 3, 74 68 78 73 bytes

Gracias @Mego y @xnor

Esta es una traducción de la respuesta C ++ de Zereges. Básicamente, esta es una definición alternativa de la función gamma, por lo tanto, más precisa (¡y lo mejor es que usa menos bytes!)

Lo siento por todos los errores!

def g(z,v=1):
 for i in range(1,10**9):v*=(1+1/i)**z/(1+z/i)
 return v/z
TanMath
fuente
1
En +1el rango no importa cuando se trata de miles de millones. Además, debe especificar que se trata de Python 3: necesitaría from __future__ import divisionuna división flotante y unos pocos terabytes de RAM para lidiar con el hecho de que rangedevuelve una lista en Python 2. Además, puede reemplazar la 1.0s con 1s y afeitarse 4 bytes
Mego
2
@TanMath: ^es xor, ¿no te refieres **a la exponenciación?
jermenkoo
3
int(1e9)es justo 10**9, y no necesitas los padres alrededor (1+1/i)**z.
xnor
3

Python, 348 448 407 390 389 bytes

Un agradecimiento especial a @Mego!

¡Un 448 tachado es (casi) todavía un 448! :pag

Esto se basa en la aproximación de Lanzcos. Golfé desde aquí

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
TanMath
fuente
1
Golf su envío, como mínimo, eliminando espacios en blanco (los espacios antes y después de - = y en, import *por ejemplo) y utilizando un nombre de función de un carácter. También tenga en cuenta que solo necesita admitir entradas reales.
lirtosiast
@ThomasKwa Lo he editado. Mi versión original no funcionó, aquí hay una nueva.
TanMath
@Mego editado ...
TanMath
Esto provoca un error de recursión: elimine el z-=1;en la primera línea de gammapara solucionarlo. También debe cambiar el nombre gammade gpara guardar bytes y evitar conflictos de nombres con cmath.gamma. También elimine los ceros a la izquierda extraños.
Mego
1

Julia, 41 bytes

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

Esta es una traducción de la respuesta C ++ de Zereges. Mientras mi otra respuesta de Julia termina instantáneamente, esto es bastante lento. Calcula los casos de prueba en un par de segundos cada uno en mi computadora.

Sin golf:

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

Prólogo, 114 bytes

Esta es una traducción de la respuesta C ++ de Zereges.

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

Pruébelo en línea aquí
Ejecútelo con una consulta del formulario:

p(12).

Ejecutarlo con 1e9 recursiones lleva unos 15 minutos.
Si lo reduce a 1e6, se tarda aproximadamente 1 segundo, lo que facilita las pruebas (pero menos precisas).
Ejecutarlo en un intérprete en su computadora / laptop también es más rápido para la mayoría de las personas.

Emigna
fuente
0

Mathematica, 40 bytes

NProduct[(1+1/n)^#/(1+#/n),{n,1,∞}]/#&
alephalpha
fuente