16
\$\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\$
  • 7
    \$\begingroup\$ This challenge had such potential... Until you allowed builtins... \$\endgroup\$ – HyperNeutrino May 8 '17 at 17:32
  • \$\begingroup\$ @HyperNeutrino Yep, I posted because I saw the challenge allowed builtins. FGITW \$\endgroup\$ – NoOneIsHere May 8 '17 at 17:33
  • 2
    \$\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\$ – Jonathan Allan May 8 '17 at 17:34
  • \$\begingroup\$ @JonathanAllen I've cleared up the rounding spec \$\endgroup\$ – Beta Decay May 8 '17 at 18:40
  • 3
    \$\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\$ – Jonathan Allan May 8 '17 at 21:56

18 Answers 18

11
\$\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\$
  • 3
    \$\begingroup\$ N@*Zeta saves two bytes. \$\endgroup\$ – Martin Ender May 8 '17 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\$ – Greg Martin May 8 '17 at 18:18
  • \$\begingroup\$ @BetaDecay For 1 it outputs ComplexInfinity, and it rounds to 5 places. (e.g. 1.64493) \$\endgroup\$ – NoOneIsHere May 8 '17 at 19:12
  • \$\begingroup\$ @MartinEnder How does the * work? \$\endgroup\$ – NoOneIsHere May 8 '17 at 19:25
  • 1
    \$\begingroup\$ @NoOneIsHere your answer uses N~5 but your explanation uses 6. \$\endgroup\$ – numbermaniac May 14 '17 at 23:55
8
\$\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\$
  • \$\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\$ – Nic Hartley May 8 '17 at 20:30
  • \$\begingroup\$ Replace Array(1e6).fill() with [...Array(1e6)], and replace the first (s) with s \$\endgroup\$ – Conor O'Brien May 8 '17 at 20:50
  • 1
    \$\begingroup\$ @QPaysTaxes Good point! Unicode variable names ftw! \$\endgroup\$ – Frxstrem May 8 '17 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 '17 at 21:15
  • \$\begingroup\$ @Frxstrem Note that ζ takes two bytes \$\endgroup\$ – CocoaBean Oct 29 '17 at 17:16
6
\$\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
    \$\begingroup\$ 1E6 -> !9­­ \$\endgroup\$ – ngn Dec 19 '18 at 13:17
  • \$\begingroup\$ @ngn Thank you. \$\endgroup\$ – Adám Dec 19 '18 at 13:44
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\$
  • \$\begingroup\$ Does float work? \$\endgroup\$ – l4m2 Nov 30 '18 at 9:32
5
+100
\$\begingroup\$

TI-Basic, 16 bytes (no builtins)

Fix 5:Σ(X^~Ans,X,1,99
\$\endgroup\$
  • \$\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\$ – pizzapants184 May 18 '17 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 '17 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 '17 at 1:42
4
\$\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\$
  • 1
    \$\begingroup\$ The question has been edited. You can output language native infinity symbols. \$\endgroup\$ – 2501 May 8 '17 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 '17 at 19:51
  • \$\begingroup\$ @ceilingcat f(1) doesn't seem correct. \$\endgroup\$ – cleblanc Nov 28 '18 at 14:13
  • \$\begingroup\$ 83 bytes \$\endgroup\$ – ceilingcat Nov 28 '18 at 22:15
3
\$\begingroup\$

Julia, 36 bytes

x->x!=1?@sprintf("%.5f",zeta(x)):Inf
\$\endgroup\$
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\$
  • 1
    \$\begingroup\$ function(a)round("if"(a-1,sum((1:9^6)^-a)),5) is a few bytes shorter. \$\endgroup\$ – Giuseppe Nov 29 '18 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\$ – Michael Lugo Nov 29 '18 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 '18 at 20:22
2
\$\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\$
  • \$\begingroup\$ Why this equation instead of Σ(1/(n^s))? It seems much more complicated... \$\endgroup\$ – Beta Decay May 10 '17 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\$ – RosLuP May 10 '17 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 '17 at 16:07
  • 1
    \$\begingroup\$ 85 bytes \$\endgroup\$ – ceilingcat Nov 28 '18 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\$ – RosLuP Nov 29 '18 at 6:29
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
\$\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\$
  • 1
    \$\begingroup\$ Does this output for input 1? \$\endgroup\$ – ETHproductions May 8 '17 at 18:43
  • 1
    \$\begingroup\$ Similarly, is this rounding to five decimal places? \$\endgroup\$ – Beta Decay May 8 '17 at 18:51
  • 1
    \$\begingroup\$ @ETHproductions It outputs inf which is allowed. \$\endgroup\$ – totallyhuman May 8 '17 at 19:18
  • \$\begingroup\$ Super late, but couldn't you just use zetac(n) instead of zeta(n,1)? \$\endgroup\$ – NoOneIsHere Nov 4 '18 at 22:37
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\$
  • \$\begingroup\$ ȷ6 is a numeric literal of a million, removing the factorial workaround. \$\endgroup\$ – Jonathan Allan May 9 '17 at 14:50
0
\$\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\$
0
\$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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