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.

asked Jan 6, 2024 at 16:30
\$\endgroup\$
14
  • 4
    \$\begingroup\$ What about \$(-1)^{1/i\pi}\$? \$\endgroup\$ Commented Jan 6, 2024 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, 2024 at 16:57
  • 2
    \$\begingroup\$ @RubenVerg You have to output the digits. \$\endgroup\$ Commented Jan 6, 2024 at 17:03
  • 3
    \$\begingroup\$ May we output more than 500 digits? \$\endgroup\$ Commented Jan 6, 2024 at 22:38
  • 6
    \$\begingroup\$ Stop banning builtins \$\endgroup\$ Commented Jan 9, 2024 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!

answered Jan 6, 2024 at 17:48
\$\endgroup\$
2
  • \$\begingroup\$ Remove the f-string to shave off 1 byte: online-python.com/yPGKEzH6lV \$\endgroup\$ Commented Jan 7, 2024 at 2:01
  • 1
    \$\begingroup\$ @vengy No, that's 3 bytes longer. \$\endgroup\$ Commented Jan 7, 2024 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
answered Jan 6, 2024 at 17:34
\$\endgroup\$
5
  • 1
    \$\begingroup\$ »nor may it call a library function to calculate e« \$\endgroup\$ Commented Jan 9, 2024 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\$ Commented Jan 9, 2024 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, 2024 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, 2024 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, 2024 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!

answered Jan 7, 2024 at 3:48
\$\endgroup\$
2
  • 3
    \$\begingroup\$ The challenge now allows you to omit the decimal point, so you can just use the unshifted version. \$\endgroup\$ Commented Jan 8, 2024 at 22:16
  • \$\begingroup\$ Using Python 2, you can replace // with / and remove the brackets around x. \$\endgroup\$ Commented Sep 4, 2024 at 0:29
9
\$\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!

answered Jan 6, 2024 at 17:56
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Tr[1/Range@260!]~N~500 would win by 1 byte, except it calculates \$e-1\$ isntead of \$e\$! \$\endgroup\$ Commented Jan 7, 2024 at 1:52
9
\$\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 \10ドルm\$. 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)
}
answered Jan 8, 2024 at 17:22
\$\endgroup\$
2
  • \$\begingroup\$ If it works in Algol 60, it works in R! \$\endgroup\$ Commented Jan 8, 2024 at 17:23
  • 2
    \$\begingroup\$ Some golfs for -7 bytes (without actually trying to understand the algorithm, so further improvements are possible). \$\endgroup\$ Commented Jan 8, 2024 at 20:53
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.

answered Jan 7, 2024 at 19:46
\$\endgroup\$
3
  • \$\begingroup\$ Looks like p=~2**m works \$\endgroup\$ Commented Jan 8, 2024 at 21:32
  • \$\begingroup\$ 51 bytes. Might be possible to do shorter by sticking to powers to 10, something like this. \$\endgroup\$ Commented Jan 8, 2024 at 22:12
  • \$\begingroup\$ @xnor Thanks. I now found quite a few 51s but nothing better. \$\endgroup\$ Commented Jan 9, 2024 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!

answered Jan 8, 2024 at 18:22
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Great to see a C answer. +1 \$\endgroup\$ Commented Jan 8, 2024 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\$ Commented Jan 9, 2024 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\$ Commented Jan 9, 2024 at 4:51
  • \$\begingroup\$ Building on @vengy 101 bytes \$\endgroup\$ Commented Jan 9, 2024 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\$ Commented Jan 9, 2024 at 17:10
5
\$\begingroup\$

Charcoal, 23 bytes

≔0θF⊖φ≔÷+Xχ499θ−φιθ2.Iθ

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

≔0θ

Start with a running total of 0.

F⊖φ≔÷+Xχ499θ−φιθ

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:

≔0θFφ≔+Xχ499÷θ−φιθ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.

answered Jan 6, 2024 at 18:06
\$\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.

answered Jan 6, 2024 at 17:40
\$\endgroup\$
2
  • \$\begingroup\$ change the range to start from 2 and you don't need the -1 in the last line \$\endgroup\$ Commented Jan 6, 2024 at 19:24
  • \$\begingroup\$ @RubenVerg Nice idea! \$\endgroup\$ Commented Jan 6, 2024 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

answered Jan 6, 2024 at 22:28
\$\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!

answered Jan 6, 2024 at 21:36
\$\endgroup\$
5
  • 1
    \$\begingroup\$ 57 using recursion instead of a for loop Try it online! \$\endgroup\$ Commented Jan 6, 2024 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, 2024 at 22:34
  • 1
    \$\begingroup\$ You can save at least two bytes by porting my method instead. \$\endgroup\$ Commented Jan 7, 2024 at 1:06
  • 1
    \$\begingroup\$ 45 \$\endgroup\$ Commented Jan 7, 2024 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\$ Commented Jan 7, 2024 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.

answered Jan 6, 2024 at 23:16
\$\endgroup\$
3
\$\begingroup\$

Jelly, 11 bytes

ȷ5*;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
 5* | 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)
answered Jan 7, 2024 at 14:18
\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 17 bytes

Cosh@1+Sinh@1`500

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

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

Retina, 110 bytes


252*
L$`_
$>`,_
^
2.¶
749{`$
;
(_*);(_*)
10*1ドル2ドル;
¶(_+),(1円)*(_*);
;$#2*_¶1,ドル3ドル
)`^(.*)(¶.*);(_*)
1ドル$.32ドル
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ドル$.32ドル

Generate the next digit from the first element.

1G`

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

answered Jan 9, 2024 at 13:11
\$\endgroup\$
2
\$\begingroup\$

WolframAlpha, 26 bytes

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

Try it on WolframAlpha

answered Jan 7, 2024 at 1:03
\$\endgroup\$
7
  • 1
    \$\begingroup\$ This is actually 26 bytes because is a 3-byte character for Mathematica. \$\endgroup\$ Commented Jan 7, 2024 at 1:55
  • \$\begingroup\$ @infinitezero Removed the E. Thanks. \$\endgroup\$ Commented Jan 9, 2024 at 3:41
  • \$\begingroup\$ the TIO result printed 21 extra digits, plus `500 at the end. \$\endgroup\$ Commented Jan 9, 2024 at 3:43
  • \$\begingroup\$ @qwr removed the TIO test, not sure why it was corrupted like that. \$\endgroup\$ Commented Jan 9, 2024 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, 2024 at 16:13
2
\$\begingroup\$

APL(NARS), 76 chars

Q;r;d;k;v;⎕FPC
r←d←1⋄k←÷10x*501⋄v←0x
r+←d×ばつ⍳k<∣d×ばつ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
answered Jan 6, 2024 at 21:49
\$\endgroup\$
4
  • \$\begingroup\$ You are printing 501 digits \$\endgroup\$ Commented Jan 6, 2024 at 22:19
  • \$\begingroup\$ @Tbw it seems are printed 500 digits after the point \$\endgroup\$ Commented Jan 6, 2024 at 22:25
  • \$\begingroup\$ 499 instead of 500 in function show the number \$\endgroup\$ Commented Jan 7, 2024 at 7:02
  • 2
    \$\begingroup\$ Your APL answer has to beat my C answer! \$\endgroup\$ Commented Jan 8, 2024 at 18:33
1
\$\begingroup\$

05AB1E, 13 bytes

5L4°šÅ»÷}O4;£

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:"

5L # Push a list in the range [1,255]
 4°š # Prepend 10**1000
 Å» } # Cumulative left-reduce, keeping intermediate results
 ÷ # by doing integer-division
 O # Sum all those results together
 4; # Push 500 (1000 halved)
 £ # Keep only the first 500 digits
 # (after which this integer is output implicitly as result)
answered Jan 11, 2024 at 9:46
\$\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")
 }
}
answered Jan 9, 2024 at 6:13
\$\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

answered Jan 9, 2024 at 16:16
\$\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\$ Commented Jan 12, 2024 at 0:04

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.