12
\$\begingroup\$

Write a program to calculate the first 500 digits of the mathematical constant e, meeting the rules below:

  • It cannot include "e", "math.e" or similar e constants, nor may it call a library function to calculate e.
  • It must execute in a reasonable time (under 1 minute) on a modern computer.
  • The digits are to include the 2 at the start. You do not need to output the . if you choose not to.

The shortest program wins.

\$\endgroup\$
14
  • 3
    \$\begingroup\$ What about \$(-1)^{1/i\pi}\$? \$\endgroup\$
    – Tbw
    Commented Jan 6 at 16:44
  • 2
    \$\begingroup\$ Since the output is always the same, can we hardcode the first 500 digits kolmogorov-complexity style, or must the program use some formula to compute e? \$\endgroup\$ Commented Jan 6 at 16:57
  • 2
    \$\begingroup\$ @RubenVerg You have to output the digits. \$\endgroup\$
    – Simd
    Commented Jan 6 at 17:03
  • 3
    \$\begingroup\$ May we output more than 500 digits? \$\endgroup\$ Commented Jan 6 at 22:38
  • 5
    \$\begingroup\$ Stop banning builtins \$\endgroup\$
    – Wheat Wizard
    Commented Jan 9 at 20:08

20 Answers 20

15
\$\begingroup\$

Python 3.8, 58 bytes

x=10**499
print(x+sum((x:=x//i)for i in range(1,253))+128)

Try it online!


Original version, before it was clearly specified that the decimal point could be omitted:

Python 3.8, 63 bytes

x=10**499
print(f'2.{sum((x:=x//i)for i in range(2,253))+128}')

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Remove the f-string to shave off 1 byte: online-python.com/yPGKEzH6lV \$\endgroup\$
    – vengy
    Commented Jan 7 at 2:01
  • 1
    \$\begingroup\$ @vengy No, that's 3 bytes longer. \$\endgroup\$
    – m90
    Commented Jan 7 at 16:13
14
\$\begingroup\$

Vyxal, 11 bytes

1∆ȯ1∆ṡ+500Ḟ

Try it Online!

Calculates cosh(1)+sinh(1) to 500 decimal places.

1∆ȯ         # cosh(1)
      +     # + 
   1∆ṡ      # sinh(1)
       500Ḟ # to 500 decimal places
\$\endgroup\$
5
  • 1
    \$\begingroup\$ »nor may it call a library function to calculate e« \$\endgroup\$ Commented Jan 9 at 13:02
  • 1
    \$\begingroup\$ @12431234123412341234123 This isn't calling a library function that explicitly calculates e. It's calling two distinct functions that, both evaluated at 1, happen to sum to e. \$\endgroup\$
    – emanresu A
    Commented Jan 9 at 13:09
  • \$\begingroup\$ It calculates with library functions, the challenge says »nor may it call a library function to calculate e« and not »nor may it call a library function that calculates e«. This is arguably a bad rule, since you are not allowed to use any library functions to do any calculation to calculate e, and it isn't very clear what a library function is and what not, but i didn't made the rules. \$\endgroup\$ Commented Jan 9 at 14:43
  • 3
    \$\begingroup\$ A better constraint on this problem would be to not use a library function which calculates any value based on the exponential function. Since cosh is defined as (e^x+e^(-x))/2 and sinh is (e^x-e^(-x))/2 I would argue it's still calling a library function which calculates the exponential function, and therefore not valid. \$\endgroup\$ Commented Jan 9 at 16:35
  • \$\begingroup\$ @Hossmeister Du kannst Sinus hyperbolicus auch als unendliche Summe aus der Taylorreihe definieren ohne auf die Exponetialfunktion zurückgreifen zu müssen. Naja, eine Regel die gewisse Funktionen verbietet sind meist schwammig. \$\endgroup\$ Commented Jan 17 at 10:41
11
\$\begingroup\$

Python 3, 54 bytes

n=x=z=499
while~-n:x=(x+10**z)//n;n-=1
print(f'2.{x}')

Try it online!

Python 3, 44 bytes

Outputs e without the ., courtesy of @xnor.

n=x=z=499
while n:x=x//n+10**z;n-=1
print(x)

Try it online!

\$\endgroup\$
2
  • 3
    \$\begingroup\$ The challenge now allows you to omit the decimal point, so you can just use the unshifted version. \$\endgroup\$
    – xnor
    Commented Jan 8 at 22:16
  • \$\begingroup\$ Using Python 2, you can replace // with / and remove the brackets around x. \$\endgroup\$ Commented Sep 4 at 0:29
8
\$\begingroup\$

R, 104 90 bytes

Since R doesn't have arbitrary precision arithmetic, and other answers already have used the limit definition and Taylor series of e, I use a decimal spigot algorithm to spice things up. I don't usually write loop-based code in R, so there is plenty of room for improvement. (divmod would be useful).

-7 bytes thanks to pajonk's better looping, and another -7 because I remembered R's colon operator can go backwards.

C=rep(1,254)
d=2
for(i in 1:500){cat(d)
d=0
for(j in 254:2)C[j]=(t=10*C[j]+d)-(d=t%/%j)*j}

Attempt This Online!

Based on The Calculation of e to Many Significant Digits by AHJ Sale (1968). The basic idea is to use an \$m\$th order Taylor polynomial, extract an integer part and fractional part, multiply the fractional part by 10, and repeat on the fractional part. Here's an example extracting the first decimal digit using 4 terms: (the 0 coefficients are coincidence)

\begin{alignat}{4} \newcommand\pp{\phantom{0}} e &\approx 2 + {} && \biggl[ &\frac 1 2 \biggl(\pp1 + {} &&\frac 1 3 \biggl(\pp1 + {} &\frac 1 4 (\pp1) \biggr) \biggr) \biggr]\\ &= 2 + \frac{1}{10} && \biggl[ &\frac 1 2 \biggl( 10 + {} &&\frac 1 3 \biggl( 10 + {} &\frac 1 4 (10) \biggr) \biggr) \biggr]\\ &= 2 + \frac{1}{10} && \biggl[ &\frac 1 2 \biggl( 10 + {} &&\frac 1 3 \biggl( 12 + {} &\frac 1 4 (\pp2) \biggr) \biggr) \biggr]\\ &= 2 + \frac{1}{10} && \biggl[ &\frac 1 2 \biggl( 14 + {} &&\frac 1 3 \biggl(\pp0 + {} &\frac 1 4 (\pp2) \biggr) \biggr) \biggr]\\ &= 2 + \frac{1}{10} && \biggl[7 + {} &\frac 1 2 \biggl(\pp0 + {} &&\frac 1 3 \biggl(\pp0 + {} &\frac 1 4 (\pp2) \biggr) \biggr) \biggr] \end{alignat}

Thanks to Steven B. Segletes for helping with MathJax formatting.

I believe the integers involved never exceed \$10m\$. The fractional part is always less than 1, so the computed digit can't affect the previous digit. \$e\$ is special because the coefficients of the Maclaurin series of \$e^x\$ are all 1. Trig functions for \$\pi\$ would have larger coefficients or produce negative digits, which would require amending previous digits. For example, here's Newton's arctan formula for \$\pi\$:

\begin{align} \frac \pi 2 &\approx 1 + \frac 1 3 \biggl( 1 + \frac 2 5 \biggl( 1 + \frac 3 7 (1) \biggr) \biggr) \\ &= 1 + \frac 1 3 \biggl( 1! + \frac 1 5 \biggl( 2! + \frac 1 7 (3!) \biggr) \biggr) \end{align}

There is no clean way to transform \$\frac 3 7 (10)\$ into an integer part while the fractional part is a multiple of \$\frac 3 7\$ and less than 1. The solution is modifying the spigot to maintain held predigits that are released once we are sure the digits are correct. See A Spigot Algorithm for the Digits of π by Rabinowitz and Wagon (1995).

\$m\$ can be calculated beforehand from the error of the finite sum using Stirling's approximation. For \$n+1\$ correct digits, find least \$m\$ satisfying \$m! > 10^{n+1}\$, equivalently $$\frac 1 2 \ln(2\pi m) + m(\ln m - 1) > (n+1) \ln 10$$

Ungolfed algorithm:

n = 500
m = 254
C = rep(1,m)
cat(2)
for(i in 2:n){
  d = 0
  for(j in m:2){
    t = 10*C[j] + d
    d = t %/% j
    C[j] = t - d*j
  }
  cat(d)
}
\$\endgroup\$
2
  • \$\begingroup\$ If it works in Algol 60, it works in R! \$\endgroup\$
    – Simd
    Commented Jan 8 at 17:23
  • 2
    \$\begingroup\$ Some golfs for -7 bytes (without actually trying to understand the algorithm, so further improvements are possible). \$\endgroup\$
    – pajonk
    Commented Jan 8 at 20:53
7
\$\begingroup\$

Wolfram Language (Mathematica), 25 bytes

Sum[1/k!,{k,0,∞}]~N~500

Try it online!

Wolfram Language (Mathematica), 29 bytes

Limit[(1+1/n)^n,n->∞]~N~500

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Tr[1/Range@260!]~N~500 would win by 1 byte, except it calculates \$e-1\$ isntead of \$e\$! \$\endgroup\$ Commented Jan 7 at 1:52
7
\$\begingroup\$

Python 2, 51 bytes (-2 thanks @xnor)

m=p=~2**3333
exec"m=m*m/~p;"*3333
print-m*10**499/p

Attempt This Online!

former Python 2, 53 bytes

p=4000
m=2**p+1
exec"m=m*m>>p;"*p
print`m*5**p`[:500]

Attempt This Online!

Outputs the digits as a single string, no decimal point.

How?

Approximately computes \$(1+1/n)^n\$ for \$n=2^{4000}\$ using repeated squaring.

\$\endgroup\$
3
  • \$\begingroup\$ Looks like p=~2**m works \$\endgroup\$
    – xnor
    Commented Jan 8 at 21:32
  • \$\begingroup\$ 51 bytes. Might be possible to do shorter by sticking to powers to 10, something like this. \$\endgroup\$
    – xnor
    Commented Jan 8 at 22:12
  • \$\begingroup\$ @xnor Thanks. I now found quite a few 51s but nothing better. \$\endgroup\$ Commented Jan 9 at 23:42
5
\$\begingroup\$

C, 126 116 109 bytes

Port of my R answer.

-10 bytes by rearranging loop logic printing leading 2, inspired by pajonk, and some small optimizations.

-7 bytes by using C with zeros instead of ones, credit chux - Reinstate Monica. Previously, the initialization of array C to 1s is a GNU extension.

i=500,d=2,j,t,C[255];main(){while(i--){putchar(d+48);d=0;j=254;while(j-->2)t=10*C[j]+d+10,d=t/j,C[j]=t%j-1;}}

Attempt This Online!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Great to see a C answer. +1 \$\endgroup\$
    – Simd
    Commented Jan 8 at 20:05
  • 1
    \$\begingroup\$ Maybe C[]={[0 ...255]=1} --> C[256] and t = 10 * C[j] + d + 10, d = t / j, C[j] = t % j - 1; or something along the lines of uses a zero'd C[]. \$\endgroup\$
    – chux
    Commented Jan 9 at 2:18
  • \$\begingroup\$ @qwr Shave off 3 bytes using for()'s instead of while()'s i=500,d=2,j,t,C[255];main(){for(;i--;putchar(d+48),d=0,j=254)for(;j-->2;)t=10*C[j]+d+10,d=t/j,C[j]=t%j-1;} example \$\endgroup\$
    – vengy
    Commented Jan 9 at 4:51
  • \$\begingroup\$ Building on @vengy 101 bytes \$\endgroup\$
    – ceilingcat
    Commented Jan 9 at 9:22
  • \$\begingroup\$ If you don't mind possible undefined behavior, define C[] (compiler assumes to have one element) and then rely upon the adjacent memory as usable space. 98 bytes. \$\endgroup\$
    – vengy
    Commented Jan 9 at 17:10
5
\$\begingroup\$

Charcoal, 23 bytes

≔⁰θF⊖φ≔÷⁺Xχ⁴⁹⁹θ⁻φιθ2.Iθ

Try it online! Link is to verbose version of code. Explanation:

≔⁰θ

Start with a running total of 0.

F⊖φ≔÷⁺Xχ⁴⁹⁹θ⁻φιθ

For each integer from 1000 down to 2, add 10**499 to the running total, then divide by that integer. This is equivalent to summing the reciprocals of the factorials from 2 to 1000 but without any loss of precision.

2.Iθ

Output e to 500 digits.

20 bytes to output without the decimal point:

≔⁰θFφ≔⁺Xχ⁴⁹⁹÷θ⁻φιθIθ

Try it online! Link is to verbose version of code. Explanation: As above but counts down to 1 and also adds the 10**499 after dividing so that the result includes the 0! and 1! terms.

\$\endgroup\$
5
\$\begingroup\$

Python, 100 bytes

from decimal import*
getcontext().prec=500
e=d=Decimal(1)
for x in range(2,254):e+=1/d;d*=x
print(e)

Attempt This Online!

-2 bytes thanks to RubenVerg

254 is the lowest number which gives the correct result, but this doesn't get slow until you start looping for thousands of iterations.

This uses the definition:

\$ \displaystyle e = \sum_{n=1} ^{\infty} \frac{1}{n!} = \frac{1}{1} + \frac{1}{1 \cdot 2} + \frac{1}{1 \cdot 2 \cdot 3} + \cdots \$

The only optimization used is to, rather than calculating the factorial of each n from 1 to 254, store the factorial of \$ n-1 \$ in the variable d, and in each iteration multiply d by the loop number x.

This uses Python's decimal library with getcontext() in order to calculate the number to 500 digits of precision.

\$\endgroup\$
2
  • \$\begingroup\$ change the range to start from 2 and you don't need the -1 in the last line \$\endgroup\$
    – RubenVerg
    Commented Jan 6 at 19:24
  • \$\begingroup\$ @RubenVerg Nice idea! \$\endgroup\$ Commented Jan 6 at 19:27
4
\$\begingroup\$

APL (NARS2000), 20 chars = 40 bytes

499⍕+/5 6x○≢⎕FPC←1E4

⎕FPC←1E4 set Floating Point Control to use ten thousand bit floats

 count that (gives 1)

5 6x○ compute sinh and cosh of that (while indicating with x that we want extended precision)

+/ sum

499⍕ output with 499 decimals, i.e. 500 digits in total

\$\endgroup\$
4
\$\begingroup\$

JavaScript (ES11), 45 bytes

-5 thanks to @l4m2

A port of Neil's method, as suggested by Neil himself.

f=(q=i=999n)=>i?f((q+10n**499n)/-~i--):"2."+q

Try it online!

\$\endgroup\$
5
  • 1
    \$\begingroup\$ 57 using recursion instead of a for loop Try it online! \$\endgroup\$ Commented Jan 6 at 21:57
  • 1
    \$\begingroup\$ You can save a byte by swapping the order of arguments q and x, and doing q+x instead of q+=x. Try it online! \$\endgroup\$ Commented Jan 6 at 22:34
  • 1
    \$\begingroup\$ You can save at least two bytes by porting my method instead. \$\endgroup\$
    – Neil
    Commented Jan 7 at 1:06
  • 1
    \$\begingroup\$ 45 \$\endgroup\$
    – l4m2
    Commented Jan 7 at 6:27
  • \$\begingroup\$ @l4m2 This is why I said "at least". (I had f=(i=252n,q=0n)=>--i?f(i,(q+10n**499n)/-~i):"2."+q but obviously the same trick applies.) \$\endgroup\$
    – Neil
    Commented Jan 7 at 8:43
4
\$\begingroup\$

GolfScript, 29 bytes

2 4000:a?:b){.*b/}a*5a?*+500<

Try it online!

Ports Albert.Lang's wonderful Python 2 solution to GolfScript. Check that answer for a better understanding of the math.

Code explanation:

2 4000:a?:b)
2 4000        # Push 2, 4000 to the stack.
      :a      # Store 4000 in variable a.
        ?     # Power; 2 ^ 4000
         :b   # Store 2 ^ 4000 in variable b.
           )  # Add one.

{.*b/}a*5a?*
{             # Open a block:
 .*           # * Duplicate and multiply (squaring
              #     the top of the stack.)
   b/         # * Integer divide by b.
     }a*      # Run this block a times.
        5a?   # Push 5 ^ a.
           *  # Multiply.

+500<
+      # Append this result to the implicit input,
       #   which is the empty string, therefore
       #   coercing the number to a string.
 500<  # Leave just the first 500 characters of
       #   this string.

GolfScript, 30 bytes

"2."128 10 499?{2+/.@+\}251,/;

Try it online!

Based on m90's Python solution, since GolfScript has big integers but no floats.

\$\endgroup\$
3
\$\begingroup\$

Jelly, 11 bytes

ȷ⁵*;R:\SDḣH

Try it online!

A Jelly version of m90’s Python answer. This is a niladic link which returns the first 500 digits of e as a list of decimal digits.

Explanation

ȷ           | 1000
 ⁵*         | 10 ** this
   ;R       | Concatenate to 1..1000
     :\     | Reduce using integer division, collecting intermediate results
       S    | Sum
        D   | Decimal digits
         ḣH | First 500 (since half of 1000 is 500)
\$\endgroup\$
3
\$\begingroup\$

Retina, 110 bytes


252*
L$`_
$>`,_
^
2.¶
749{`$
;
(_*);(_*)
10*$1$2;
¶(_+),(\1)*(_*);
;$#2*_¶$1,$3
)`^(.*)(¶.*);(_*)
$1$.3$2
1G`

Try it online! Too slow to produce 500 digits on TIO so link just produces 108. Explanation: Port of @qwr's R answer.


252*
L$`_
$>`,_

Generate the working array. (Note: This is an estimate of its size, but increasing it just requires additionally increasing the iteration count of the loop below to compensate.)

^
2.¶

Start with 2..

749{`
)`

Loop 749 times, which produces 499 digits for some reason.

$
;

Start another parallel iteration.

(_*);(_*)
10*$1$2;

Multiply each value by 10 and add the carry from the next element's previous iteration.

¶(_+),(\1)*(_*);
;$#2*_¶$1,$3

Divmod each value by its index and propagate the carry to the previous element for its next iteration.

^(.*)(¶.*);(_*)
$1$.3$2

Generate the next digit from the first element.

1G`

Remove all of the elements leaving just the final decimal expansion.

\$\endgroup\$
2
\$\begingroup\$

WolframAlpha, 26 bytes

N[Sum[1/k!,{k,0,∞}],500]

Try it on WolframAlpha

\$\endgroup\$
7
  • 1
    \$\begingroup\$ This is actually 26 bytes because is a 3-byte character for Mathematica. \$\endgroup\$ Commented Jan 7 at 1:55
  • \$\begingroup\$ @infinitezero Removed the E. Thanks. \$\endgroup\$
    – vengy
    Commented Jan 9 at 3:41
  • \$\begingroup\$ the TIO result printed 21 extra digits, plus `500 at the end. \$\endgroup\$
    – qwr
    Commented Jan 9 at 3:43
  • \$\begingroup\$ @qwr removed the TIO test, not sure why it was corrupted like that. \$\endgroup\$
    – vengy
    Commented Jan 9 at 3:56
  • 1
    \$\begingroup\$ N[Sum[1/k!,{k,0,∞}],500 funktioniert auch, das fehlende ] wird von WolframAlpha automatisch angenommen. \$\endgroup\$ Commented Jan 10 at 16:13
2
\$\begingroup\$

Wolfram Language (Mathematica), 17 bytes

Cosh@1+Sinh@1`500

Try it online! A direct port of emanresu A's nice answer.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ OP said in comments that Exp function isn’t allowed, fyi \$\endgroup\$ Commented Jan 8 at 17:42
  • \$\begingroup\$ Ok thanks—I only looked in the post itself. \$\endgroup\$ Commented Jan 9 at 6:01
2
\$\begingroup\$

APL(NARS), 76 chars

Q;r;d;k;v;⎕FPC
r←d←1⋄k←÷10x*501⋄v←0x
r+←d×←÷v+←1⋄→2×⍳k<∣d
⎕FPC←4×501⋄⎕←499⍕r

14+21+20+18+3=76

Calculus in rationals, and print with 499 digits after the point (499+1=500) the last digit rounded (but not changed because the 500th digit after the point should be 2<6)

2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320
  0305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408
  9149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000
  7520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844
  250569536967707854499699679468644549059879316368892300987931
\$\endgroup\$
4
  • \$\begingroup\$ You are printing 501 digits \$\endgroup\$
    – Tbw
    Commented Jan 6 at 22:19
  • \$\begingroup\$ @Tbw it seems are printed 500 digits after the point \$\endgroup\$
    – Rosario
    Commented Jan 6 at 22:25
  • \$\begingroup\$ 499 instead of 500 in function show the number \$\endgroup\$
    – Rosario
    Commented Jan 7 at 7:02
  • 2
    \$\begingroup\$ Your APL answer has to beat my C answer! \$\endgroup\$
    – qwr
    Commented Jan 8 at 18:33
1
\$\begingroup\$

05AB1E, 13 bytes

₅L₄°šÅ»÷}O₄;£

Port of @NickKennedy's Jelly answer, which in turn is based on @m90's Python answer, so make sure to upvote those answers as well.

Outputs the first 500 digits as a single concatted integer.

Try it online.

Explanation:"

₅L             # Push a list in the range [1,255]
  ₄°š          # Prepend 10**1000
     Å» }      # Cumulative left-reduce, keeping intermediate results
       ÷       #  by doing integer-division
         O     # Sum all those results together
          ₄;   # Push 500 (1000 halved)
            £  # Keep only the first 500 digits
               # (after which this integer is output implicitly as result)
\$\endgroup\$
0
\$\begingroup\$

Scala 3, 89 bytes

A port of @m90's Python answer in Scala.


Golfed version. Attempt This Online!

var x=BigInt(10) pow 499
println(s"2.${(BigInt(0)/:(2 to 252))((s,i) =>s+{x/=i;x})+128}")

Ungolfed version. Attempt This Online!

object Main {
  def main(args: Array[String]): Unit = {
    var x = BigInt(10).pow(499)
    val result = (for (i <- 2 to 252) yield {
      val div = x / i
      x = div
      div
    }).sum + 128
    println(s"2.$result")
  }
}
\$\endgroup\$
-1
\$\begingroup\$

SageMath, 20 18 Byte

Sehr unkreativ:

n(i^(2/i/pi),1664)

Alte Antwort:

n((-1)^(-i/pi),1664)

Onlinetest

i^(2/i/pi) =e : e^(πi) = -1 => e^(πi/2) = i => e = i^(2/πi)

n(....) : Kontentiere zu Dezimal

1664 : Mit einer Genauigkeit von 1664 bit

\$\endgroup\$
1
  • \$\begingroup\$ Moin. Willkommen. Es gibt keine Regel, die vorschreibt, dass Antworten auf Englisch erfolgen müssen, aber Fragen müssen und auf Englisch bekommt man eine bessere Reaktion. \$\endgroup\$
    – Wheat Wizard
    Commented Jan 12 at 0:04

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