| Bytes | Lang | Time | Link |
|---|---|---|---|
| 075 | JavaScript ES7 | 170108T233725Z | Arnauld |
| 030 | APLNARS | 250330T194239Z | Rosario |
| 045 | Wolfram Language Mathematica | 170107T232044Z | LegionMa |
| 042 | Desmos | 220505T012711Z | fireflam |
| 043 | PARI/GP | 170108T021539Z | Christia |
| 031 | MATL | 170108T033120Z | Luis Men |
| 092 | Python + scipy | 170107T230913Z | orlp |
JavaScript (ES7), 80 75 bytes
-5 bytes thanks to @emanresu A (-8 with eval)
Based on orlp's answer. This JS implementation is quite slow. You may want to try i=1e-7 or higher for a faster approximation.
p=>{for(s=x=i=5e-8;x<1;x+=i)s+=2*i/p*(x**(k=1-p)+(1-x)**k)**(1/p);return s}
Or 72 bytes with eval() (even slower)
APL(NARS), 30 chars
p←⎕⋄(2÷p)×{p√+/(1-p)*⍨⍵,1-⍵}∫1
Just the integral other has in answers, i don't know if the function
of integral is (2÷p)×{p√+/(1-p)*⍨⍵,1-⍵} or {p√+/(1-p)*⍨⍵,1-⍵}
or before make integration and after the product, i think in both way would return the same result....
test:
p←⎕⋄(2÷p)×{p√+/(1-p)*⍨⍵,1-⍵}∫1
⎕:
1.5
3.259767993
p←⎕⋄(2÷p)×{p√+/(1-p)*⍨⍵,1-⍵}∫1
⎕:
4
3.396934823
Wolfram Language (Mathematica), 49 46 45 bytes
3 bytes saved thanks to alephalpha.
1 byte saved thanks to att.
\!\(2N@∫\_0\%1\@+++(a^-#-1)^(1-#)\%#a\)&
Try it online! Pure function. Takes a number as input and returns a number as output. The Unicode characters are U+222B for \[Integral] and U+F74C for \[DifferentialD].
Desmos, 42 bytes
f(p)=2∫_0^1(x/x^p+(1-x)^{1-p})^{1/p}dx/p
Port of orlp's integration formula. Yay for integration built-in!
PARI/GP, 48 43 bytes
It's easy after @orlp has found the formula, and @alephalpha's version saves 5 bytes:
p->2*intnum(u=0,1,(1+(u^-p-1)^(1-p))^(1/p))
To add something slightly useful, let's calculate the p for which we get 3.2:
? f=p->2*intnum(u=0,1,(1+(u^-p-1)^(1-p))^(1/p));
? solve(p=1,2,f(p)-3.2)
%2 = 1.623002382384469009676324702
Correct usage
While the code gives results that are much more exact than the challenge demands, it can easily be improved a lot: if we replace the upper integration limit 1 with [1,1/p-1] (giving what the manual calls the singularity exponent) then all shown digits of f(2) agree with Pi. This is still true if we increase the precision to 100 (type \p100).
However, after that change the solve computation no longer worked. I changed the inner term to explicitely handle the case u=0 and also changed to a different computer with a newer PARI version and 64 bit (which implies a higher default precision).
Here is the improved calculation of the p value for Pi=3.2, and let's also have a look at the real Pi:
? f=p->2*intnum(u=0,[1,1/p-1],if(u,(1+(u^-p-1)^(1-p))^(1/p),0));
? f(2)
%2 = 3.1415926535897932384626433832795028842
? Pi
%3 = 3.1415926535897932384626433832795028842
? solve(p=1,2,f(p)-3.2)
%4 = 1.6230023823844690096763253745604419761
MATL, 31 bytes
0:1e-3:1lyG^-lG/^v!d|G^!slG/^sE
Try it online! Or verify all test cases.
Explanation
This generates the x,y coordinates of one quarter of the unit circle sampled at 1001 points with step 0.001 in x. The length of the quarter of circle is approximated by that of the polygonal line that passes through those points; that is, the sum of the lengths of the 1000 segments. Length is of course computed according to p-norm. Multiplying the result by 2 gives the approximate lenght of half a circle, that is, pi.
0:1e-3:1 % Push [0 0.001 0.002 ... 0.999 1]. These are the x coordinates of
% the vertices of the polygonal line that will approximate a quarter
% of the unit circle
l % Push 1
y % Duplicate [0 0.001 0.002 ... 0.999 1] onto the top of the stack.
G % Push input, p
^ % Element-wise power: gives [0^p 0.001^p ... 1^p]
- % Element-wise subtract from 1: gives [1-0^p 1-0.001^p ... 1-1^p]
lG/ % Push 1, push p, divide: gives 1/p
^ % Element-wise power: gives [(1-0^p)^(1/p) (1-0.001^p)^(1/p) ...
% ... (1-1^p)^(1/p)]. These are the y coordinates of the vertices
% of the polygonal line
v % Concatenate vertically into a 2×1001 matrix. The first row contains
% the x coordinates and the second row contains the y coordinates
! % Transpose
d| % Compute consecutive differences down each column. This gives a
% 1000×2 matrix with the x and y increments of each segment. These
% increments will be referred to as Δx, Δy
G % Push p
^ % Element-wise power
! % Transpose
s % Sum of each column. This gives a 1×1000 vector containing
% (Δx)^p+(Δy)^p for each segment
lG/ % Push 1/p
^ % Element-wise power. This gives a 1×1000 vector containing
% ((Δx)^p+(Δy)^p)^(1/p) for each segment, that is, the length of
% each segment according to p-norm
s % Sum the lenghts of all segments. This approximates the length of
% a quarter of the unit circle
E % Multiply by 2. This gives the length of half unit circle, that is,
% pi. Implicitly display
Python + scipy, 92 bytes
from scipy.integrate import*
lambda p:2/p*quad(lambda x:(x/x**p+(1-x)**(1-p))**(1/p),0,1)[0]
Formula is from this math.SE question.