Output first \$n\$ digits of \$\pi^{1/\pi}\$

-4

4

This challenge is to produce the shortest code for the constant \$\pi^{1/\pi}\$. Your code must output the first \$n\$ consecutive digits of \$\pi^{1/\pi}\$, where \$n\$ is given in the input. Alternatively, your program may accept no input, and output digits indefinitely

This is code golf, so the shortest submission (in bytes) wins except that it must output the 1000 digits for \$n = 1000\$ in less than 10 seconds on a reasonable PC.

You may not use a built-in for \$\pi\$, the gamma function or any trigonometic functions.

If the input is \$n = 1000\$ then the output should be:

1.439619495847590688336490804973755678698296474456640982233160641890243439489175847819775046598413042034429435933431518691836732951984722119433079301671110102682697604070399426193641233251599869541114696602206159806187886346672286578563675195251197506612632994951137598102148536309069039370150219658973192371016509932874597628176884399500240909395655677358944562363853007642537831293187261467105359527145042168086291313192180728142873804095866545892671050160887161247841159801201214341008864056957496443082304938474506943426362186681975818486755037531745030281824945517346721827951758462729435404003567168481147219101725582782513814164998627344159575816112484930170874421446660340640765307896240719748580796264678391758752657775416033924968325379821891397966642420127047241749775945321987325546370476643421107677192511404620404347945533236034496338423479342775816430095564073314320146986193356277171415551195734877053835347930464808548912190359710144741916773023586353716026553462614686341975282183643

Note the 1000 decimal places includes the first \$1\$.

Output format

Your code can output in any format you wish.

This related question tackles a simpler variant but with the same restrictions.

Notes

If it's helpful, you can assume \$\pi^{1/\pi}\$ is irrational and in fact you can even assume it is a Normal number.

Anush

Posted 2019-05-20T08:26:33.650

Reputation: 3 202

9

Banning a built-in for pi or trigonometric functions is kind of useless. For example, we can use $\Gamma(1/2)^2$

– Luis Mendo – 2019-05-20T09:05:40.733

4I'm curious, is this even possible? Could it not be that digit number 1000000 of pi^(1/pi) relies on digit number 1000099? Or even 9999999, in theory at least..? At some point you'll have ...4599999999999999999999999999999999......, but that could be 4600000000000000000000000000000000..... if your calculations included more digits. I believe it's impossible to say how many more digits is needed..? Or? – Stewie Griffin – 2019-05-20T10:01:16.817

1@StewieGriffin It's certainly possible but I don't know how quickly you can add a new digit once you have already outputted thousands, say. – Anush – 2019-05-20T10:28:44.013

11Why the restriction on how the digits are output? It adds absolutely nothing to the challenge. – Shaggy – 2019-05-20T11:12:56.917

You said that it should print digits forever. Can we assume infinite memory or only infinite time? Do we have to come up with some clever way to calculate the 10^15th digit without using more than a petabyte of memory? – Stewie Griffin – 2019-05-20T11:21:06.703

@StewieGriffin It is possible, but the number of digits cannot be known in advance. Instead, it should be computed on the fly, which makes the challenge ¿unnecessarily? complicated

– Luis Mendo – 2019-05-20T12:10:19.950

2

For the record: https://math.stackexchange.com/q/3232906/92515

– Stewie Griffin – 2019-05-20T12:46:39.627

@StewieGriffin You can assume both infinite memory and time. – Anush – 2019-05-20T13:00:15.433

1I'm not sure that Generally you may not use any built-in that computes pi for you means. If my language has a variable-precision function that takes a string like 'pi' and a number N and symbolically computes N decimals of what the string represents, is that acceptable? – Luis Mendo – 2019-05-20T13:52:04.930

3Is ConvertDegreesToRadians(180) interesting enough as a way to produce pi? – my pronoun is monicareinstate – 2019-05-20T15:26:01.507

2How can a [tag:restricted-time] challenge assume infinite time? – Xcali – 2019-05-24T21:26:41.480

@Xcali. The challenge has been edited since it was closed (and now reopened). In any case, the time is restricted for the n=1000 case. – Anush – 2019-05-25T04:00:47.870

Is there a way to calculate that number without use pi? – RosLuP – 2019-05-25T10:56:26.440

1@RosLuP You can compute $\pi$ to enough precision and go from there or try to find a direct way to compute $\pi^{1/\pi}$ without first computing $\pi$. I think both are good. – Anush – 2019-05-26T10:10:07.547

Answers

9

Python, 149 bytes

Saved one byte due to @H.PWiz.

k=n=int(input())+1
i=j=8*n
e=l=p=z=10**n
while i:p=2*z-i//2*p//~i;i-=2
q=z-z*z//p
while j:l=q//j+q*l//z;j-=1
while k:e=z+e*l//k//p;k-=1
print(e//100)

Try it online!

Input n = 1000 finishes in less than 0.5s.

\$\sqrt[\pi]{\pi}\$ is calculated as the \$e^\frac{\ln(\pi)}{\pi}\$.\$\pi\$ is calculated with the usual Euler-Leibniz: \$\pi=\sum_{n=0}\limits^{\infty}{\frac{n!}{(2n+1)!!}}\$.

\$e^x\$ and \$\ln(x)\$ are both computed using a Taylor series: \$e^x=\sum\limits_{n=0}^{\infty}{\frac{x^n}{n!}}\$ and \$\ln(1-x)=-\sum\limits_{n=1}^{\infty}{\frac{x^n}{n}}\$. Because the iteration for \$\ln(x)\$ converges only when \$|x|<1\$, this is instead calculated as \$\ln(\pi)=-\ln(\frac{1}{\pi})\$.

Given that Python uses Karasuba Multiplication, the overall runtime complexity is \$\mathcal{O}(n^{1+\log_2(3)})\$ - in other words, twice as many digits will take approximately 6 times as long.


Subquadratic Complexity

import sys
from gmpy2 import isqrt, mpz

def piks(a, b):
  if a == b:
    if a == 0:
      return (1, 1, 1123)
    p = a*(a*(32*a-48)+22)-3
    q = a*a*a*24893568
    t = 21460*a+1123
    return (p, -q, p*t)
  m = (a+b) >> 1
  p1, q1, t1 = piks(a, m)
  p2, q2, t2 = piks(m+1, b)
  return (p1*p2, q1*q2, q2*t1 + p1*t2)

n = int(sys.argv[1])-1
m = n*20//3
z = mpz(10)**n

# n / log(777924, 10)
pi_terms = mpz(n*0.16975227728583067)

pp, pq, pt = piks(0, pi_terms)
pq *= 3528

pi2m = (pq << m) // pt

a, b = 2 << m, 8
while a != b:
  a, b = (a + b) >> 1, isqrt(a*b)

mlog2_pi = (z << m) // a

a, b = 2*pi2m, 8
while a != b:
  a, b = (a + b) >> 1, isqrt(a*b)
logpi_pi = z * pi2m // a - mlog2_pi

mlog2 = mlog2_pi * pq // pt

d = e = (15044673 << m) // 10450451
pt //= z
while d:
  a, b = 2*e, 8
  while a != b:
    a, b = (a + b) >> 1, isqrt(a*b)
  lnx = (pq * e) // (pt * a) - mlog2
  d = e * (lnx - logpi_pi) // z
  e -= d

print(e * z >> m)

Try it online!

Input n = 20000 finishes in less than one second.

\$\pi\$ can be computed in subquadratic time by use of Karatsuba splitting a.k.a. Fast E-function Evaluation, which reduces a summation to n terms to a single rational value p/q, splitting in binary descent. I've chosen to use Ramanujan #39, which is the fastest converging series of its kind that doesn't require an arbitrary precision square root, to my knowledge. Explicitly, this is computed as:

\$\large{\left.{3528}\middle/{\sum\limits_{n=0}^{\infty}\frac{(-1)^n (4n)! (1123+21460n)}{(n!)^4 14112^{2n}}}\right.}\$

For \$\ln(x)\$ and \$e^x\$, using the same technique wouldn't provide any benefit, because both are computed as a power series of an arbitrary precision variable. Fortunately, Gauss has gifted us with an elegant quadratically converging formula for \$\ln(x)\$, based on the Arithmetic-Geometric Mean:

\$\DeclareMathOperator{\AGM}{AGM}\large\ln(x)=\lim\limits_{n\rightarrow\infty}\frac{\pi x^n}{2n\AGM(x^n,4)}\$

or, in cases when large powers of x are inconvenient, this can also be computed as:

\$\large\ln(x)\approx\frac{\pi x 2^m}{2\AGM(x 2^m,4)}-m\log(2)\$

Conveniently, division by \$\pi\$ can be acheived simply by not multiplying through by \$\pi\$.

With the natural logarithm thusly defined, \$e^\frac{\ln(\pi)}{\pi}\$ can be computed via Newton's method on \$x_{n+1}=x_n-x_n(\ln(x_n)-\frac{\ln(\pi)}{\pi})\$. The overall complexity is then \$\mathcal{O}(n^*\log^3(n))\$, where \$n^*\$ will vary with the complexity of the multiplication algorithm GMP is using for any given bit length.

primo

Posted 2019-05-20T08:26:33.650

Reputation: 30 891

1This is very nice! – Anush – 2019-05-30T18:22:13.097

3-1 – H.PWiz – 2019-05-30T20:32:02.903

1What a great update! – Anush – 2019-06-12T13:49:04.857

3

Wolfram Language (Mathematica), 62 bytes

In my first try I used Zeta function but this one uses the imaginary part of ln(-1) for pi. (@someone)
Prints more than 4000 digits in the first 10 seconds,

q=Im@Log@-1;Do[Print@RealDigits[N[q^(1/q),2k]][[1,k]],{k,∞}]

Try it online!

9 bytes saved from @someone

J42161217

Posted 2019-05-20T08:26:33.650

Reputation: 15 931

I was hoping they might all be printed on the same line so the first 1000 digits look like the example I gave in the question. – Anush – 2019-05-20T10:06:07.373

@Anush I can print digits for ever or give you any number of digits (but then it should stop). You must decide – J42161217 – 2019-05-20T10:09:33.970

Your code should print digits forever. I just meant they should be printed horizontally and not vertically. – Anush – 2019-05-20T10:11:15.417

4This is the first time you are saying that. The question does not ask that. – J42161217 – 2019-05-20T10:13:49.563

Apologies. I have clarified the question now. – Anush – 2019-05-20T10:15:28.843

14it is highly recommended that you don't change the rules of a challenge after even one answer is submitted. I would suggest you to use sandbox next time. – J42161217 – 2019-05-20T10:19:05.880

For some reason I have never seen anyone use non-printable ASCII chars in Wolfram answers here, but if we assume Wolfram is "the language that TIO calls Wolfram and interprets", this seems to work for 68 bytes: Try it online!

– my pronoun is monicareinstate – 2019-05-20T15:02:36.917

That previous golf actually was for 66 bytes; I mistyped things and realized that after 5 minutes since the comment. You can also save several bytes by using Im@Log@-1 for pi (as $ln(-1) = i \pi$) – my pronoun is monicareinstate – 2019-05-20T15:15:47.637

I now allow any output format. – Anush – 2019-05-20T16:11:58.183

Calculate the digit in a different way to save several bytes; assuming I did not produce any mistakes. Try it online!

– my pronoun is monicareinstate – 2019-05-21T04:10:15.673

Now you can output the first n digits, allowing you to save several bytes. q^(1/q) -> q^q^-1 to save one byte as well. – my pronoun is monicareinstate – 2019-05-25T15:58:14.400

Save a byte by using Log@-1/I for pi. – Roman – 2019-06-05T22:16:15.200

2

Wolfram Language (Mathematica), 23 22 bytes

(p=Log@-1/I)^p^-1~N~#&

Try it online!

-1 byte by @someone — the use and reuse of p beats the pure function

Taking a lot of inspiration from @J42161217 and displaying n digits instead of an infinite stream.

Note that I'm using ToString in Tio to suppress the trailing precision specifier in the output, which does not appear when this code is executed in Mathematica.

Maybe using 180° for pi would work; but maybe that's too close to being trigonometric and is disallowed.

Roman

Posted 2019-05-20T08:26:33.650

Reputation: 1 190

22 bytes – my pronoun is monicareinstate – 2019-06-18T02:34:43.073

1

AXIOM, 221 bytes

m(k)==(v:=8.*k;(4/(v+1)-2/(v+4)-1/(v+5)-1/(v+6))*16^-k)
p(n:PI):String==(d:=digits(n+9);e:=10.^-digits();i:=s:=0;repeat(k:=m(i);k<e=>break;s:=s+k;i:=i+1);r:=concat split((s^(1/s))::String,char " ");digits(d);r.(1..(n+1)))

test and ungolf:

(3) -> p 1000
   (3)
  "1.43961949584759068833649080497375567869829647445664098223316064189024343948
  91758478197750465984130420344294359334315186918367329519847221194330793016711
  10102682697604070399426193641233251599869541114696602206159806187886346672286
  57856367519525119750661263299495113759810214853630906903937015021965897319237
  10165099328745976281768843995002409093956556773589445623638530076425378312931
  87261467105359527145042168086291313192180728142873804095866545892671050160887
  16124784115980120121434100886405695749644308230493847450694342636218668197581
  84867550375317450302818249455173467218279517584627294354040035671684811472191
  01725582782513814164998627344159575816112484930170874421446660340640765307896
  24071974858079626467839175875265777541603392496832537982189139796664242012704
  72417497759453219873255463704766434211076771925114046204043479455332360344963
  38423479342775816430095564073314320146986193356277171415551195734877053835347
  93046480854891219035971014474191677302358635371602655346261468634197528218364
  3"
                                                             Type: String
           Time: 0.03 (IN) + 0.53 (EV) + 0.25 (OT) + 0.15 (GC) = 0.97 sec


-- Bailey-Borwein-Plouffe formula for pi
-- https://en.m.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%93Plouffe_formula   
--       +oo
--      -----          --                                      --
--      \          1   |     4         2         1         1    |
--   pi= |      -------|  ------- - ------- - ------- - ------- |
--      /            k |   8*k+1     8*k+4     8*k+5     8*k+6  |
--      ----- k   16   --                                      --
--        0
m(k)==(v:=8.*k;(4/(v+1)-2/(v+4)-1/(v+5)-1/(v+6))*16^-k)
p(n:PI):String==
      d:=digits(n+9); e:=10.^-digits(); i:=s:=0
      repeat
          k:=m(i)
          k<e=>break
          s:=s+k;i:=i+1
      r:=concat split((s^(1/s))::String,char " ")
      digits(d)
      r.(1..(n+1))

the function m calculate the term of the sum; the p() function loop, sum them in the variable s until the term is < than min float value (one can see as epsilon); p() function return one string of that number pi^(1/pi); it seems the required digits are returned in less than 1 second for input to p() function 1000.

RosLuP

Posted 2019-05-20T08:26:33.650

Reputation: 3 036