18
\$\begingroup\$

Challenge

Given an integer, \$s\$, as input where \$s\geq 1\$ output the value of \$\zeta(s)\$ (Where \$\zeta(x)\$ represents the Riemann Zeta Function).

Further information

\$\zeta(s)\$ is defined as:

$$\zeta(s) = \sum\limits^\infty_{n=1}\frac{1}{n^s}$$

You should output your answer to 5 decimal places (no more, no less). If the answer comes out to be infinity, you should output \$\infty\$ or equivalent in your language.

Riemann Zeta built-ins are allowed, but it's less fun to do it that way ;)

Examples

Outputs must be exactly as shown below

Input -> Output
1 -> ∞ or inf etc.
2 -> 1.64493
3 -> 1.20206
4 -> 1.08232
8 -> 1.00408
19 -> 1.00000

Bounty

As consolation for allowing built-ins, I will offer a 100-rep bounty to the shortest answer which does not use built-in zeta functions. (The green checkmark will still go to the shortest solution overall)

Winning

The shortest code in bytes wins.

\$\endgroup\$
15
  • 8
    \$\begingroup\$ This challenge had such potential... Until you allowed builtins... \$\endgroup\$
    – hyper-neutrino
    May 8, 2017 at 17:32
  • \$\begingroup\$ @HyperNeutrino Yep, I posted because I saw the challenge allowed builtins. FGITW \$\endgroup\$ May 8, 2017 at 17:33
  • 4
    \$\begingroup\$ Is "to a precision of 5 decimal places" strict? (i.e. can we output to more precision?) If not the test cases should show 6dp really. \$\endgroup\$ May 8, 2017 at 17:34
  • \$\begingroup\$ @JonathanAllen I've cleared up the rounding spec \$\endgroup\$
    – Beta Decay
    May 8, 2017 at 18:40
  • 5
    \$\begingroup\$ @BetaDecay (sigh no ping) should an input of 19 really output the text 1.00000? Wouldn't 1 or 1.0 be valid? It seems you have made it into a chameleon challenge. \$\endgroup\$ May 8, 2017 at 21:56

22 Answers 22

13
\$\begingroup\$

Mathematica, 9 7 11 bytes

Zeta@#~N~6&

Explanation:

Zeta@#       (* Zeta performed on input *)
      ~N     (* Piped into the N function *)
        ~6   (* With 6 digits (5 decimals) *)
          &  (* Make into function *)

Mathematica result

Without builtin:

Mathematica, 23 UTF-8 bytes

Sum[1/n^#,{n,∞}]~N~6&

Thanks to Kelly Lowder

\$\endgroup\$
8
  • 4
    \$\begingroup\$ N@*Zeta saves two bytes. \$\endgroup\$ May 8, 2017 at 18:02
  • \$\begingroup\$ @* is the (left) composition operator: f@*g denotes a function whose value at the argument x is f[g[x]]. \$\endgroup\$ May 8, 2017 at 18:18
  • \$\begingroup\$ @BetaDecay For 1 it outputs ComplexInfinity, and it rounds to 5 places. (e.g. 1.64493) \$\endgroup\$ May 8, 2017 at 19:12
  • \$\begingroup\$ @MartinEnder How does the * work? \$\endgroup\$ May 8, 2017 at 19:25
  • 1
    \$\begingroup\$ @NoOneIsHere your answer uses N~5 but your explanation uses 6. \$\endgroup\$ May 14, 2017 at 23:55
9
\$\begingroup\$

Javascript, 81 70 66 65 bytes

s=>s-1?new Int8Array(1e6).reduce((a,b,i)=>a+i**-s).toFixed(5):1/0

Runnable examples:

ζ=s=>s-1?new Int8Array(1e6).reduce((a,b,i)=>a+i**-s).toFixed(5):1/0

const values = [ 1, 2, 3, 4, 8, 19 ];
document.write('<pre>');
for(let s of values) {
  document.write('ζ(' + s + ') = ' + ζ(s) + '\n')
}

\$\endgroup\$
6
  • \$\begingroup\$ Why call it Z? The zeta symbol is a valid function name in JS, and you don't need it to be golfed. \$\endgroup\$
    – anon
    May 8, 2017 at 20:30
  • 1
    \$\begingroup\$ Replace Array(1e6).fill() with [...Array(1e6)], and replace the first (s) with s \$\endgroup\$ May 8, 2017 at 20:50
  • 1
    \$\begingroup\$ @QPaysTaxes Good point! Unicode variable names ftw! \$\endgroup\$
    – Frxstrem
    May 8, 2017 at 21:15
  • \$\begingroup\$ @ConorO'Brien Huh, I never realized that Array trick (I thought sparse arrays didn't iterate but I guess I was wrong). Thanks! \$\endgroup\$
    – Frxstrem
    May 8, 2017 at 21:15
  • \$\begingroup\$ @Frxstrem Note that ζ takes two bytes \$\endgroup\$
    – CocoaBean
    Oct 29, 2017 at 17:16
7
\$\begingroup\$

APL (Dyalog), 22 21 bytes

Look ma, no built-ins! -1 thanks to ngn.

Since Dyalog APL does not have infinities, I use Iverson's proposed notation.

{1=⍵:'¯'⋄5⍕+/÷⍵*⍨⍳!9}

Try it online!

{ anonymous function:

1=⍵: if the argument is one, then:

  '¯' return a macron

 else

  !9 factorial of nine (362880)

   first that many integers integers

  ⍵*⍨ raise them to the power of the argument

  ÷ reciprocal values

  +/ sum

  5⍕ format with five decimals

} [end of anonymous function]

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 1E6 -> !9­­ \$\endgroup\$
    – ngn
    Dec 19, 2018 at 13:17
5
\$\begingroup\$

C, 74 70 69 bytes

n;f(s){double z=n=0;for(;++n>0;)z+=pow(n,-s);printf("%.5f",z/=s!=1);}

Compile with -fwrapv. It will take some time to produce an output.

See it work here. The part ++n>0 is replaced with ++n<999999, so you don't have to wait. This keeps identical functionality and output.

\$\endgroup\$
1
  • \$\begingroup\$ Does float work? \$\endgroup\$
    – l4m2
    Nov 30, 2018 at 9:32
5
+100
\$\begingroup\$

TI-Basic, 16 bytes (no builtins)

Fix 5:Σ(X^~Ans,X,1,99
\$\endgroup\$
3
  • \$\begingroup\$ You really need to go up to about 150000 to get the answer right for Ans=2, which would take upwards of half an hour to calculate on an 84 Plus CE. Also, you could multiply by (Ans-1)^0 somewhere to get an error for Ans=1, TI-Basic's closest representation of infinity! \$\endgroup\$ May 18, 2017 at 3:56
  • \$\begingroup\$ @pizzapants184 I'm fully aware that 2, 3, etc. might take more than 99 iterations. You can achieve this functionality by replacing 99 with E9 where E is the scientific E, i.e. representing 10^9. (Or obviously something smaller like E5). Understanding that E99 is generally used for positive infinity also allows for this functionality theoretically, if the upper bound of the summation was E99. Emulators can provide this much faster than a physical calculator. Thanks for your thoughts :) \$\endgroup\$
    – Timtech
    May 18, 2017 at 14:23
  • \$\begingroup\$ I don't think this counts as displaying infinity. It won't even throw an error if you added 1 infinitely, due to floating-point imprecision. \$\endgroup\$
    – lirtosiast
    Jul 11, 2017 at 1:42
5
\$\begingroup\$

C (gcc), 112 101 94 84 bytes

Thanks for the golfing tips from ceilingcat.

n;f(s){float r;for(n=98;n;r+=pow(n--,-s));printf("%.5f",r+pow(99,-s)*(.5+99./--s));}

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ The question has been edited. You can output language native infinity symbols. \$\endgroup\$
    – 2501
    May 8, 2017 at 19:26
  • \$\begingroup\$ @2501 I reverted back to the previous answer, although I'm still quite a few bytes away from your solution. \$\endgroup\$
    – cleblanc
    May 8, 2017 at 19:51
  • \$\begingroup\$ @ceilingcat f(1) doesn't seem correct. \$\endgroup\$
    – cleblanc
    Nov 28, 2018 at 14:13
  • \$\begingroup\$ 83 bytes \$\endgroup\$
    – ceilingcat
    Nov 28, 2018 at 22:15
3
\$\begingroup\$

Julia, 36 bytes

x->x!=1?@sprintf("%.5f",zeta(x)):Inf
\$\endgroup\$
0
3
\$\begingroup\$

C,129 130 128 bytes

#include<math.h>
f(s,n){double r=0;for(n=1;n<999;++n)r+=(n&1?1:-1)*pow(n,-s);s-1?printf("%.5f\n",r/(1-pow(2,1-s))):puts("oo");}

it uses the following formula

\zeta(s) = \frac{1}{1-2^{1-s}}\sum\limits_{n=1}^{\infty}{\frac{(-1)^{n+1}}{n^s}}

test and results

main(){f(2,0);f(1,0);f(3,0);f(4,0);f(8,0);f(19,0);}

1.64493
+oo
1.20206
1.08232
1.00408
1.00000
\$\endgroup\$
5
  • \$\begingroup\$ Why this equation instead of Σ(1/(n^s))? It seems much more complicated... \$\endgroup\$
    – Beta Decay
    May 10, 2017 at 10:18
  • \$\begingroup\$ @BetaDecay because it seems to me more fast in find the result; here there is the range for sum s in 1..999, in the 'Σ(1/(n^s)) ' there is need s in the range 1..10^6 \$\endgroup\$
    – user58988
    May 10, 2017 at 12:01
  • 1
    \$\begingroup\$ I see. FYI, simply oo is fine, you don't need to specify it as positive \$\endgroup\$
    – Beta Decay
    May 10, 2017 at 16:07
  • 1
    \$\begingroup\$ 85 bytes \$\endgroup\$
    – ceilingcat
    Nov 28, 2018 at 22:19
  • \$\begingroup\$ @ceilingcat you can write one other entry for this question... it seems I remember here without math.h header it not link... \$\endgroup\$
    – user58988
    Nov 29, 2018 at 6:29
3
\$\begingroup\$

Rust, 133 129 120 117 bytes

fn f(s:f64){let mut y@mut n=0.;while n<999.{n+=1.;y-=f64::powf(-1.,n)/n.powf(s)}print!("{:.5}",y/(1.-(1.-s).exp2()))}

Try it online!

Thanks to @Steffan for -9.

Slightly golfed less

fn f(s:f64){
  let mut y@mut n=0.;
  while n<999.{
    n+=1.;
    y-=f64::powf(-1.,n)/n.powf(s)
  }
  print!("{:.5}",y/(1.-(1.-s).exp2()))
}
\$\endgroup\$
3
  • \$\begingroup\$ n+=1.;} no need for the semicolon \$\endgroup\$
    – naffetS
    Jan 5, 2023 at 1:09
  • \$\begingroup\$ and \n can be a literal newline \$\endgroup\$
    – naffetS
    Jan 5, 2023 at 1:10
  • \$\begingroup\$ You can save even more using a newer version than on TIO: ATO \$\endgroup\$
    – naffetS
    Jan 5, 2023 at 1:13
2
\$\begingroup\$

MATL, 21 bytes

q?'%.5f'2e5:G_^sYD}YY

Try it online!

Explanation

Input 1 is special-cased to output inf, which is how MATL displays infinity.

For inputs other than 1, summing the first 2e5 terms suffices to achieve a precision of 5 decimal places. The reason is that, from direct computation, this number of terms suffices for input 2, and for greater exponents the tail of the series is smaller.

q         % Input (implicit) minus 1
?         % If non-zero
  '%.5f'  %   Push string: format specifier
  2e5:    %   Push [1 2 ... 2e5]
  G       %   Push input again
  _       %   Negate
  ^       %   Power. element-wise
  s       %   Sum of array
  YD      %   Format string with sprintf
}         % Else
YY        %   Push infinity
          % End (implicit)
          % Display (implicit)
\$\endgroup\$
2
\$\begingroup\$

R, 54 bytes

function(a){round(ifelse(a==1,Inf,sum((1:9^6)^-a)),5)}

Finds the sum directly and formats as desired, outputs Inf if a is 1. Summing out to 9^6 appears to be enough to get five-place accuracy while still being testable; 9^9 would get better accuracy in the same length of code. I could get this shorter if R had a proper ternary operator.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ function(a)round("if"(a-1,sum((1:9^6)^-a)),5) is a few bytes shorter. \$\endgroup\$
    – Giuseppe
    Nov 29, 2018 at 18:30
  • \$\begingroup\$ Yes, but it throws an error if a = 1. function(a)round("if"(a-1,sum((1:9^6)^-a),Inf),5) works and is still shorter than my original solution. \$\endgroup\$ Nov 29, 2018 at 20:18
  • \$\begingroup\$ Oh yes of course! I forgot to include the Inf, that's what I get for typing code into the comment box directly... \$\endgroup\$
    – Giuseppe
    Nov 29, 2018 at 20:22
2
\$\begingroup\$

Python 3: 67 bytes (no built-ins)

f=lambda a:"∞"if a<2else"%.5f"%sum([m**-a for m in range(1,10**6)])

Nothing fancy, only uses python 3 because of the implicit utf-8 encoding.

Try it online with test cases.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ def f(a): is two bytes less than f=lambda a:... \$\endgroup\$
    – Mark Reed
    Jan 5, 2023 at 1:37
1
\$\begingroup\$

Perl 6, 50 bytes

{$_-1??(1..1e6).map(* **-$_).sum.fmt('%.5f')!!∞}
\$\endgroup\$
1
\$\begingroup\$

PARI/GP, 27 26 bytes

\p 6
s->trap(,inf,zeta(s))
\$\endgroup\$
1
\$\begingroup\$

Jelly, 23 bytes

ȷ6Rİ*⁸S÷Ị¬$ær5;ḷỊ?”0ẋ4¤

Try it online!

How?

  • Sums the first million terms
  • Divides by 0 when abs(input)<=1 to yield inf (rather than 14.392726722864989) for 1
  • Rounds to 5 decimal places
  • Appends four zeros if abs(result)<=1 to format the 1.0 as 1.00000
  • Prints the result

ȷ6Rİ*⁸S÷Ị¬$ær5;ḷỊ?”0ẋ4¤ - Main link: s
ȷ6                      - literal one million
  R                     - range: [1,2,...,1000000]
   İ                    - inverse (vectorises)
     ⁸                  - link's left argument, s
    *                   - exponentiate
      S                 - sum
          $             - last two links as a monad:
        Ị               -   insignificant? (absolute value of s less than or equal to 1?)
         ¬              -   not (0 when s=1, 1 when s>1)
       ÷                - divide (yielding inf when s=1, no effect when s>1)
           ær5          - round to 10^-5
                      ¤ - nilad followed by link(s) as a nilad:
                  ”0    -   literal '0'
                    ẋ4  -   repeated four times
                Ị?      - if insignificant (absolute value less than or equal to 1?)
              ;         -       concatenate the "0000" (which displays as "1.00000")
               ḷ        - else: left argument
                        - implicit print
\$\endgroup\$
1
\$\begingroup\$

Python 3 + SciPy, 52 bytes

lambda n:'%.5f'%zeta(n,1)
from scipy.special import*

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Does this output for input 1? \$\endgroup\$ May 8, 2017 at 18:43
  • 1
    \$\begingroup\$ Similarly, is this rounding to five decimal places? \$\endgroup\$
    – Beta Decay
    May 8, 2017 at 18:51
  • 1
    \$\begingroup\$ @ETHproductions It outputs inf which is allowed. \$\endgroup\$ May 8, 2017 at 19:18
  • \$\begingroup\$ Super late, but couldn't you just use zetac(n) instead of zeta(n,1)? \$\endgroup\$ Nov 4, 2018 at 22:37
1
\$\begingroup\$

MathGolf, 14 bytes (no builtins)

┴¿Å'∞{◄╒▬∩Σ░7<

Note that in the TIO link, I have substituted for , which pushed \$10^6\$ instead of \$10^7\$. This is because the version submitted here timeouts for all test cases. This results in the answers for 3 and 8 to be off by 1 decimal place. However, there are way bigger 1-byte numerical literals in MathGolf, allowing for arbitrary decimal precision.

Try it online!

Explanation

┴                check if equal to 1
 ¿               if/else (uses one of the next two characters/blocks in the code)
  Å              start block of length 2
   '∞            push single character "∞"
     {           start block or arbitrary length
      ◄          push 10000000
       ╒         range(1,n+1)
        ▬        pop a, b : push(b**a)
         ∩       pop a : push 1/a (implicit map)
          Σ      sum(list), digit sum(int)
           ░     convert to string (implicit map)
            7    push 7
             <   pop(a, b), push(a<b), slicing for lists/strings
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 64 bytes

s=>[...Array(1e6)].reduce((a,b,i)=>s>1>i?a:i**-s+a,0).toFixed(5)

Try it online!

Pointed in Frxstrem's

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

Vyxal, 19 bytes

ċ[₆(n⁰eĖ⅛)¾∑øḋ7Ẏ|\∞

Try it Online!

No builtins used, used 4 bytes on the decimal places

\$\endgroup\$
0
\$\begingroup\$

Jelly, 26 bytes

⁵*5İH+µŒṘḣ7
⁴!Rİ*³Sǵ’ݵ’?

Don't try it online with this link! (Since this uses 16!~20 trillion terms, running on TIO produces a MemoryError)

Try it online with this link instead. (Uses 1 million terms instead. Much more manageable but takes one more byte)

Returns inf for input 1.

Explanation

⁵*5İH+µŒṘḣ7    - format the output number
⁵*5İH+         - add 0.000005
      µŒṘ      - get a string representation
         ḣ7    - trim after the fifth decimal.

⁴!Rİ*³Sǵ’ݵ’? - main link, input s
           µ’? - if input minus 1 is not 0...
⁴!R            -   [1,2,3,...,16!] provides enough terms.
   İ           -   take the inverse of each term
    *³         -   raise each term to the power of s
      S        -   sum all terms
       Ç       -   format with the above link
               - else:
        µ’İ    -   return the reciprocal of the input minus 1 (evaluates to inf)

Out of the 26, bytes, 7 are used for computation, 12 are for formatting, and 7 are for producing inf on zero. There has to be a better golf for this.

\$\endgroup\$
1
  • \$\begingroup\$ ȷ6 is a numeric literal of a million, removing the factorial workaround. \$\endgroup\$ May 9, 2017 at 14:50
0
\$\begingroup\$

J, 33 bytes (no built-ins)

_:^:('*'&e.)7j5":1#.1%[^~1+i.@1e6

Attempt This Online!

_:^:('*'&e.)7j5":1#.1%[^~1+i.@1e6
                           i.@1e6  NB. integers up to 1e6
                         1+        NB. add one
                      [^~          NB. nʸ for each in 1..1e6
                    1%             NB. reciprocal of each
                 1#.               NB. sum the result
            7j5":                  NB. format each result, width of 7, 5 decimal places
  ^:                               NB. if
    ('*'&e.)                       NB. '*' is in the formatted result
                                   NB. (": fills with *'s if the width is too small)
_:                                 NB. return an infinity
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 20 bytes

i'∞ë6°LImzO5.ò¾4׫7£

4 bytes are used to account for edge case \$n=1\$, and 9 bytes to round to five decimal places (6 of which for edge case 1.00000)..

Try it online or verify all test cases.

Explanation:

i          # If the (implicit) input-integer is 1:
 '∞       '#  Push "∞"
ë          # Else:
 6°        #  Push 10 to the power 6: 1,000,000
   L       #  Pop and push a list in the range [1,1000000]
    Im     #  Get the power of the input on each integer
      z    #  Calculate 1/value for each
       O   #  Sum everything together
 5.ò       #  Round to 5 decimal places
    ¾4×    #  Push a string of 4 zeros: "0000"
       «   #  Append it to the result
        7£ #  Pop and leave just the first 7 characters: "1.abcde"
           # (after which the result is output implicitly as result)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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