16
\$\begingroup\$

Background

It can be shown that for any integer k >= 0, f(k) = tan(atan(0) + atan(1) + atan(2) + ... + atan(k)) is a rational number.

Goal

Write a complete program or function which when given k >= 0, outputs f(k) as a single reduced fraction (the numerator and denominator are coprime).

Test cases

The first few values are

f(0) = (0,1)
f(1) = (1,1)
f(2) = (-3,1)
f(3) = (0,1)
f(4) = (4,1)
f(5) = (-9,19)
f(6) = (105,73)

Rules

  • Standard loopholes are forbidden.
  • Input and output may be in any convenient format. You may output f(k) as a string numerator/denominator, as a tuple of two integers, a fraction or rational object, etc. If you output a string, give two integers only, that is, output 3/2 instead of 1 1/2.
  • This is code-golf, the shortest answer (in bytes) wins.
\$\endgroup\$
  • 1
    \$\begingroup\$ Can you further specify in your test cases what the input/output values are? \$\endgroup\$ – Ian H. Aug 8 '17 at 6:22
  • 1
    \$\begingroup\$ Are the integers in the range in degrees or radians? \$\endgroup\$ – Erik the Outgolfer Aug 8 '17 at 6:59
  • 1
    \$\begingroup\$ OEIS: A180657 \$\endgroup\$ – Sisyphus Aug 8 '17 at 7:00
  • 4
    \$\begingroup\$ The atan(0) term is unnecessary. \$\endgroup\$ – Adám Aug 8 '17 at 7:08
  • 3
    \$\begingroup\$ @pizzapants184 f(0) = tan∑∅ = tan 0 = 0 \$\endgroup\$ – Adám Aug 8 '17 at 7:14

11 Answers 11

4
\$\begingroup\$

M, 11 bytes

×C÷@+
R0;ç/

Try it online!

Uses the OEIS formula x(n) = (x(n-1)+n)/(1-n*x(n-1)) with x(0) = 0.

\$\endgroup\$
11
\$\begingroup\$

Mathematica, 28 bytes

Fold[+##/(1-##)&,0,Range@#]&

Try it online!

A longer, but more interesting approach (32 bytes):

Im@#/Re@#&@Product[1+n I,{n,#}]&

Try it online!

\$\endgroup\$
  • \$\begingroup\$ +1 o'_'o Mathematica and its built-ins o'_'o \$\endgroup\$ – Mr. Xcoder Aug 8 '17 at 7:37
  • 3
    \$\begingroup\$ @Mr.Xcoder Not really in this case. OP is using series summation cleverly (if I read the code right). \$\endgroup\$ – Adám Aug 8 '17 at 7:38
11
\$\begingroup\$

Python 2, 76 72 bytes

from fractions import*
f=lambda k:Fraction(k and(k+f(k-1))/(1-k*f(k-1)))

Use the identity:

tan(A + B) = (tan(A) + tan(B)) / (1 - tan(A) * tan(B))

We have:

f(k) = 0                                    if k = 0
     = (k + f(k - 1)) / (1 - k * f(k - 1))  if k > 0

Try it online!

Thanks to Luis Mendo, save 4 bytes.

\$\endgroup\$
  • 1
    \$\begingroup\$ Hope you do not mind: I added a TiO link. \$\endgroup\$ – Mr. Xcoder Aug 8 '17 at 7:05
  • \$\begingroup\$ @LuisMendo LGTM, Edited. \$\endgroup\$ – tsh Aug 8 '17 at 10:08
3
\$\begingroup\$

APL (Dyalog), 14 bytes

Requires ⎕FR←1287 (128 bit Floating-point Representation) for small input. Takes k as right argument.

1(∧÷,)3○¯3+.○⍳

Try it online!

 integers one through k (zero is not needed as 0 = arctan 0)

¯3+.○ sum of arcus tangents

3○ tangent

1() apply the following tacit function with 1 as left argument and the above as right argument:

 the lowest common multiple (of 1 and the right argument); gives the numerator

÷ divided by

, the concatenation (of 1 and the right argument); gives the numerator and the denominator

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

Haskell, 52 bytes

This uses the OEIS series expansion:

import Data.Ratio
f 0=0%1
f n|p<-f$n-1=(p+n)/(1-n*p)

Try it online!

Or a pointfree version:

(scanl1(\f n->(f+n)/(1-n*f))[0%1..]!!)
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 80 bytes

f=n=>n?([a,b]=f(n-1),g=(a,b)=>a?g(b%a,a):b,c=g(d=b*n+a,e=b-n*a),[d/c,e/c]):[0,1]

Returns a [numerator, denominator] pair. Explanation: Let f(n-1) = a/b then f(n) = atan(tan(n)+tan(a/b)) = (n+a/b)/(1-n*a/b) = (b*n+a)/(b-n*a). It then remains to reduce the fraction to its lowest terms.

Online ES6 Environment

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

Pari/GP, 36 bytes

n->imag(x=prod(i=0,n,1+i*I))/real(x)

Try it online!

Or the same length:

n->fold((x,y)->(x+y)/(1-x*y),[0..n])

Try it online!

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

05AB1E, 33 26 bytes

0X)Iƒ©`N*+®`sN*-‚D¿D_i\¤}/

Try it online!

Explanation

0X)                          # initialize stack with [0,1]
   Iƒ                        # for N in range [0 ... input] do:
     ©                       # store a copy of the current pair in the register
      `                      # push the pair separately to the stack
       N*                    # multiply the denominator with N
         +                   # add the numerator
          ®`s                # push the denominator then the numerator to the stack
             N*              # multiply the numerator by N
               -             # subtract it from the denominator
                D¿D          # get 2 copies of the greatest common divisor
                   0Qi  }    # if the gcd equals 0
                      \¤     # replace it with the denominator
                         /   # divide the pair with this number
\$\endgroup\$
1
\$\begingroup\$

Octave, 30 bytes

format rat
tan(sum(atan(0:k)))

Try it online!

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

Casio-Basic, 35 bytes

tExpand(tan(sum(seq(tan⁻¹(n),n,0,k

tan-1 should be entered as the one on the Trig keyboard; or the -1 can be entered separately from the abc>Math keyboard. According to the fx-CP400's manual, it's a single two-byte character (764).

Function, 34 bytes for the code, +1 byte to add k as an argument.

Explanation

seq(tan-1(n),n,0,k) generates all the values for tan-1(n) from 0 to k.

sum adds them all together, then tan does the tangent function on them.

tExpand will then turn them into a single fraction.

\$\endgroup\$
  • \$\begingroup\$ @Adám This is Casio, not TI, so it's not done the same way. \$\endgroup\$ – numbermaniac Aug 8 '17 at 7:55
  • \$\begingroup\$ According to Wikipedia, and ¹ are two bytes each; E5CC and E5C1. \$\endgroup\$ – Adám Aug 8 '17 at 8:05
  • \$\begingroup\$ @Adám oh nice, I didn't realise that article existed! However, this is an fx-CP400, not the 9860G; I just checked the manual, and the superscript -1 is actually a single character, code 764; so it's a single two byte character. \$\endgroup\$ – numbermaniac Aug 8 '17 at 8:14
0
\$\begingroup\$

Julia 0.6.0 40 bytes

k->rationalize(tan(sum(x->atan(x),1:k)))

It's a straightforward implementation of the question. The precision of rationalize can sometimes be weird but works fine 99% of the time.

\$\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.