Gamma Chức năng Golf


17

Cho một số thực ttrong (-10^9,13)(không bao gồm -10^9hoặc 13) làm đầu vào, đầu ra Γ(t), còn được gọi là hàm Gamma , được định nghĩa như sau:

định nghĩa hàm gamma

Bạn không được sử dụng chức năng Gamma tích hợp để giải quyết nhiệm vụ này, bạn cũng không thể sử dụng các hàm tích hợp số hoặc biểu tượng tích hợp. Đầu ra của bạn phải chính xác đến 6 con số quan trọng hoặc bên trong 10^-6giá trị thực tế, tùy theo giá trị nào ít hạn chế hơn đối với giá trị đã cho. Hàm Gamma tích hợp của Python sẽ được sử dụng để xác định giá trị thực. Bạn có thể giả sử Γ(t)được xác định - nghĩa là tsố thực dương hoặc số thực âm không nguyên - và đó |Γ(t)| ≤ 10^9. Đây là một chương trình tham khảo mà bạn có thể sử dụng để lấy các giá trị thực tế, sử dụng hàm Gamma tích hợp của Python.

Ví dụ

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

Quy tắc

  • Đây là , vì vậy câu trả lời ngắn nhất (tính bằng byte) sẽ thắng.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đầu vào và đầu ra có thể được thực hiện theo bất kỳ cách nào được coi là tiêu chuẩn cho ngôn ngữ của bạn.
  • Bạn có thể viết một chương trình đầy đủ, một chức năng hoặc bất cứ điều gì thường được coi là câu trả lời hợp lệ cho ngôn ngữ của bạn

Bảng xếp hạng

Đoạn trích Stack ở cuối bài này tạo bảng xếp hạng từ các câu trả lời a) dưới dạng danh sách các giải pháp ngắn nhất cho mỗi ngôn ngữ và b) dưới dạng bảng xếp hạng tổng thể.

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề, sử dụng mẫu Markdown sau:

## Language Name, N bytes

nơi Nlà kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh bại chúng thông qua. Ví dụ:

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

Nếu bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vì điểm của bạn là tổng của hai tệp hoặc bạn muốn liệt kê riêng các hình phạt cờ của thông dịch viên), hãy đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề:

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

Bạn cũng có thể đặt tên ngôn ngữ thành liên kết sau đó sẽ hiển thị trong đoạn trích:

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


1
Vui lòng cung cấp giới hạn rõ ràng cho t sao cho | gamma (t) | <10 ^ 9
flawr

Liên kết không phải là một triển khai tham chiếu, ...
sergiol

@sergiol Thưởng nó
Mego

Câu trả lời:


2

Bình thường, 21 byte

Như với câu trả lời TI-BASIC của tôi, tôi chưa thể kiểm tra điều này với 8 lần lặp lại đầy đủ 8 ^ 10, nhưng mọi thứ có vẻ tốt với các trường hợp nhỏ hơn.

cu*Gc^hc1HQhcQHS^8T1Q

Giải trình:

                            [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

Hãy thử nó ở đây với 2000 lần lặp thay vì 8 ^ 10.


10

C ++ 14, 86 85 81 byte

[](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ôi đã không dành nhiều thời gian cho việc này. Tôi chỉ nhìn vào xấp xỉ có vẻ dễ thực hiện nhất (theo cách của byte). Sẽ mất một chút thời gian để tính giá trị (vì vòng lặp trên tất cả các số nguyên dương), nhưng giới hạn thời gian không được chỉ định trong thử thách. Đây là hàm ẩn danh (lambda), nhận bất kỳ đối số nào (có thể chuyển đổi sang Tđó pow(double, T)operator/(T,int)có thể được gọi) và trả về double.

Vô dụng với cách sử dụng

#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 Tất nhiên rồi! Cảm ơn.
Khu vực

Vậy giá trị nào bạn nhận được cho -10 ^ 9 và cho 10 ^ 9? Trước tiên tôi muốn biết công cụ của bạn hoạt động tốt như thế nào trước khi bạn nhận được upvote của tôi.
flawr

@Mego Trình biên dịch Microsoft không cần cả hai điều này bao gồm.
Khu vực

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

@flawr Chương trình khai thác đầu ra 0 cho gamma(-10e9)nhưng OP đã nêu, chỉ các tham số, cho chức năng gamma được xác định, có thể được xem xét. gamma(10e9)trả về inf, trong khi chức năng Gamma tích hợp của Python sẽ được sử dụng để xác định giá trị thực tế nóiOverflowError: math range error
Zereges

7

Chồn 0,12 , 35 34 25 byte

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

Điều này không dừng lại với một lỗi (khi cố gắng chia cho 0), nhưng điều đó được cho phép theo sự đồng thuận của Meta . Thêm một .ở cuối cho một chương trình tạm dừng bình thường. Hãy thử tất cả các trường hợp thử nghiệm cùng một lúc. (Vòng lặp chỉ lặp lại 1e4 lần nên sẽ kết thúc sớm hơn là muộn hơn.)

Giải trình

Zereges đã sử dụng một trong những định nghĩa sản phẩm vô hạn thay thế . Hóa ra, cái khác thì dễ thực hiện hơn ở Minkolang.

Công thức thay thế của Euler của chức năng gamma

Đây là một giới hạn khi nđi đến vô tận, có nghĩa là tôi có thể tính toán cả n!(t+n)khi tôi đi. Vì vậy, tôi lấy ra 1/t(vì 0!=1) và n^tbởi vì người ta không thể tính toán tuần tự mà không biết giá trị kết thúc của n. Khi nó xảy ra, vì nlà giới hạn, tôi có thể sử dụng nó hai lần. Một lần là một yếu tố trong tính toán và một lần là số lần chạy vòng lặp.

Một sản phẩm vô hạn tuần tự phải bắt đầu bằng thứ gì đó, thường là 1. Trong trường hợp này, đó là n^t/t . Trong phần thân của vòng lặp, tôi tính toán k/(t+k)và nhân số này với sản phẩm cho đến nay. Cuối cùng, toàn bộ sản phẩm đã được tính toán và đầu ra. Đây thực chất là những gì chương trình của tôi làm, với nđủ cao để câu trả lời đủ chính xác.

phiên bản bùng nổ của sản phẩm vô hạ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

Như không có . , nó quấn quanh và bắt đầu lại. Tuy nhiên, nbây giờ sản xuất -1vì đầu vào trống, cuối cùng dẫn đến việc cố gắng chia cho 0, làm dừng chương trình.


5

Julia, 141 byte

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

Điều này tạo ra một hàm lambda không tên, chấp nhận một số thực và trả về một số thực. Nó sử dụng phép tính gần đúng của Spounge để tính toán Gamma.

Ung dung:

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

Chơi golf rất , rất muộn, nhưng 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)))nên hoạt động với tốc độ 137 byte (ít nhất là trong Julia 0,6)
Ông Xcoder

3

Japt, 45 byte

Japt là phiên bản rút gọn của Ja vaScri pt . Thông dịch viên

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

Tất nhiên, 1e9 = 1.000.000.000 lần lặp sẽ mất mãi mãi, vì vậy để thử nghiệm, hãy thử thay thế 9bằng a 6. (1e6 chính xác đến ~ 5 số liệu có ý nghĩa. Sử dụng 1e8 cho đầu vào của12 là đủ để có được sáu con số đầu tiên.)

Kết quả trường hợp thử nghiệm: (sử dụng độ chính xác 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...

Làm thế nào nó hoạt động

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

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

Điều này sử dụng thuật toán tương tự như Zereges.

Hãy cẩn thận: Tôi chưa thực sự thử nghiệm điều này với các lần lặp 1e9 đầy đủ; dựa trên thời gian dành cho các giá trị nhỏ hơn, tôi hy vọng thời gian chạy sẽ theo thứ tự tháng . Tuy nhiên, nó dường như hội tụ và không có vấn đề với các lỗi làm tròn. TI lưu các số dưới dạng số thập phân với độ chính xác 14 chữ số.


Bạn đã không kiểm tra nó?!
TanMath

1
@TanMath Tôi sẽ, nhưng tôi cần máy tính của mình cho kỳ thi cuối tháng tới.
lirtosiast

3

Python 3, 74 68 78 73 byte

Cảm ơn @Mego và @xnor

Đây là bản dịch câu trả lời C ++ của Zereges. Về cơ bản, đây là một định nghĩa thay thế của hàm gamma, do đó chính xác hơn (và điều tuyệt vời là sử dụng ít byte hơn!)

Tôi xin lỗi vì tất cả những sai lầm!

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

1
Các +1trên phạm vi không quan trọng khi bạn đang đối phó với hàng tỷ. Ngoài ra, bạn nên xác định rằng đây là Python 3 - bạn cần from __future__ import divisionphân chia float và một vài terabyte RAM để đối phó với thực tế rangetrả về một danh sách trong Python 2. Plus, bạn có thể thay thế 1.0s bằng 1s và tắt 4 byte.
Mego

2
@TanMath: ^là xor, ý bạn không phải là **lũy thừa?
jermenkoo

3
int(1e9)chỉ là 10**9, và bạn không cần parens xung quanh (1+1/i)**z.
xnor

3

Python, 348 448 407 390 389 byte

Đặc biệt cảm ơn @Mego!

Một con số bị gạch bỏ là 448 (gần như) vẫn là con số 448! : p

Điều này dựa trên xấp xỉ Lanzcos. Chơi gôn từ đây

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
Vui lòng gửi bài nộp của bạn bằng cách, ở mức tối thiểu, xóa khoảng trắng (khoảng trắng trước và sau - = và import *ví dụ) và sử dụng tên hàm một ký tự. Cũng lưu ý rằng bạn chỉ cần hỗ trợ đầu vào thực sự.
lirtosiast

@ThomasKwa Tôi đã chỉnh sửa nó. Phiên bản gốc của tôi không hoạt động, đây là phiên bản mới hơn.
TanMath

@Mego chỉnh sửa ...
TanMath

Điều này gây ra lỗi đệ quy - xóa z-=1;dòng đầu tiên gammađể sửa lỗi. Bạn cũng nên đổi tên gammathành glưu byte và để tránh đặt tên xung đột với cmath.gamma. Cũng thả các số 0 đầu ngoài.
Mego

1

Julia, 41 byte

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

Đây là bản dịch câu trả lời C ++ của Zereges. Trong khi câu trả lời Julia khác của tôi kết thúc ngay lập tức, điều này khá chậm. Nó tính toán các trường hợp thử nghiệm trong một vài giây trên máy tính của tôi.

Ung dung:

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

1

Prolog, 114 byte

Đây là bản dịch câu trả lời C ++ của 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),!.

Dùng thử trực tuyến tại đây
Chạy với một truy vấn có dạng:

p(12).

Chạy nó với 1e9 thu hồi mất khoảng 15 phút.
Nếu bạn giảm xuống còn 1e6, sẽ mất khoảng 1 giây, giúp cho việc kiểm tra dễ dàng hơn (nhưng kém hiệu quả hơn).
Chạy nó trong một trình thông dịch trên máy tính / máy tính xách tay của bạn rất có thể sẽ nhanh hơn đối với hầu hết mọi người.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.