1
\$\begingroup\$

This question already has an answer here:

Introduction

We know that the factorial notation is valid for all natural numbers. However, Euler had extended it for all positive real numbers, as well as for complex numbers by defining a function, which is known as the Gamma Function. It is represented by Γ.

Challenge

You will be given a non-negative floating point number, say 'n' (with a maximum of 2 decimal places in it), and you need to output the factorial of that number correct to at least 3 decimal places. Assume all inputs to be valid, and n <= 7.

Now talking about Gamma function, there is an integral which can be used to find the value of any factorial. You may choose to use it. You can find more information here. The Gamma function is recursive in nature. One important property, which would probably be useful to you is:

Γ(n) = (n-1)! , which means that, n! = Γ(n) . n

Also note that we really do not need to know Γ(n) for all values of n. For instance, look at the number 4.5 - we can write its factorial as:

4.5! = 4.5 * 3.5 * 2.5 * 1.5 * 0.5! = 59.0625 * 0.5!

So here we need only the value of 0.5! , which means the value of Γ(1.5). Also, similarly, we can find the factorial of any decimal if we know the values of factorials of numbers between 0 and 1, i.e, values of gamma function of numbers between 1 and 2. You need it, so that is why there is a table below for your help:

Table For Values of Gamma Function

Using this table, we can see that 0.5!, i.e, the value of Γ(1.5) = 0.88623, which gives our result: (4.5)! = 59.0625 * 0.88623 = 52.3429594 , which is indeed a good result. Similarly,

(5.7)! = (5.7)*(4.7)*(3.7)*(2.7)*(1.7)*(0.7)! = 454.97457 * 0.90864 = 413.408093

Also, if you do not wish to use the table for calculating the gamma function, here is a simple integral to help you out:

Integral for Gamma Function

Remember that you can provide your answers only up to 3 decimal places if you want to. But the value should have minimum error. Like, +- 0.003 is acceptable.

You are free to decide in what way you want to compute the factorial - whether by the integral, or by the table, or using any other method.

Examples

Please note that here the answer is correct to 3 decimal places.

2.4 -> 2.981
3.9 -> 20.667
2.59 -> 3.675
1.7 -> 1.545
0.5 -> 0.886

Scoring

This is , so the shortest code wins!

\$\endgroup\$

marked as duplicate by Dennis code-golf Mar 6 '18 at 18:56

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • \$\begingroup\$ Please note that this challenge was posted on sandbox and people decided that this is not a dupe because this challenge allows built ins. \$\endgroup\$ – Manish Kundu Mar 6 '18 at 16:07
  • \$\begingroup\$ Can we output as a rational number (i.e fraction)? Like, 8275608925237915/2251799813685248 for the 3rd test case. \$\endgroup\$ – Mr. Xcoder Mar 6 '18 at 16:48
  • \$\begingroup\$ Sorry but as per the rules, decimal answers only \$\endgroup\$ – Manish Kundu Mar 6 '18 at 16:50
  • 4
    \$\begingroup\$ Since all built-in solutions are being combined in a single post, I consider this a duplicate of the Gamma challenge. \$\endgroup\$ – Dennis Mar 6 '18 at 18:54
  • 1
    \$\begingroup\$ I think that near 7! the table is actually very likely to fail for 3 digits after .. And even if it didn't, you don't want to have to think about 1000.000499 vs 1000.000501 so you should really have asked for accuracy as a max absolute error \$\endgroup\$ – Ton Hospel Mar 6 '18 at 19:21
1
\$\begingroup\$

Perl 5, -p 40 bytes

Very slow. One run takes about 13 minutes for me.

#!/usr/bin/perl -p
$\=5e8**++$_/$_;$\/=1+$'/$_ for//..5e8}{

Try it online!

The TIO link uses 1e7 instead of 5e8 to avoid timeouts and is therefore not accurate enough

Old version, -p 60 bytes, not accurate enough

Uses a Stirling approximation. But even with the first correction term that is pretty inaccurate for small n. So instead I approximate (n+2)!/(n+2)/(n+1).

Notice that I don't bother trying to get the first 3 digits right, but the relative error seems to properly be < 0.001 in the range [0, 7]. E.g. 0! outputs 0.999481433067179 which would be 1.000 if rounded to 3 digits.

#!/usr/bin/perl -p
$_=(($_+=2)/exp 1)**$_*(2+1/6/$_)/$_/($_-1)*sqrt$_*atan2 1,0

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Community wiki for built-in solutions

This answer is intended to collect answers that are simply built-ins. It's a community wiki, so anybody can edit in without approval. Go ahead and include any built-in only solution here, following xnor's proposal and according to our consensus.

Jelly, 1 byte

!

Try it online!

J , 1 byte

!

Try it online!

2sable, 1 byte

!

Try it online!

Pyth, 2 bytes

.!

Try it online!

R, 9 bytes

factorial

Try it online!

Stax, 2 bytes

|F

Try and debug online!

Wolfram Language (Mathematica), 3 bytes

#!&

Try it online!

\$\endgroup\$
  • \$\begingroup\$ ! is not a function in Mathematica, it is an operator, and hence is not a valid submission. \$\endgroup\$ – totallyhuman Mar 6 '18 at 19:12
  • 1
    \$\begingroup\$ @totallyhuman Fixed. \$\endgroup\$ – Scott Milner Mar 6 '18 at 22:52
0
\$\begingroup\$

APL (Dyalog Unicode), 1 byte

!

Try it online!

In APL, the factorial primitive has always included the entire domain of the gamma function.

\$\endgroup\$
  • 1
    \$\begingroup\$ I've created a community wiki answer for built-in only answers following our consensus and xnor's proposal. You can transfer your solution there if you want, but feel free to keep it as-is otherwise. \$\endgroup\$ – Mr. Xcoder Mar 6 '18 at 16:32
  • \$\begingroup\$ Unsurprisingly, this also works in J. \$\endgroup\$ – cole Mar 6 '18 at 16:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.