9
\$\begingroup\$

In trigonometry, there are certain angles known as "special angles". This is because when you take sin, cos or tan of one of these angles, you get a result that is easy to remember because it is a square root of a rational number. These special angles are always multiples of either pi/6, or pi/4. Here is a visualization of all the special angles, and their corresponding trig values.

trig values

As you can see, for each angle their is a corresponding pair of numbers. The first number is cosine of that angle, and the second is sine of that angle. To find tangent of one of these angles, just divide sin by cos. For example, tan(pi/6) is equal to

sin(pi/6) / cos(pi/6) == 
(1/2) / (√3/2) ==
1/√3 ==
√3/3

The Challenge

You must write a full program that takes 3 inputs.

  1. A single char representing the trig function you're supposed to calculate. This will be either 's' (sin), 'c' (cos), or 't' (tan).

  2. The numerator of the input angle. This can be any positive integer. Note that an input of 5 means the numerator is 5 * pi.

  3. The denominator of the input angle. This will always be one of the following: 1, 2, 3, 4, 6

Then print out the exact value the trig function of that angle. Here is a list of sin, cos, and tan of all angles up to 2 * pi:

sin(0pi):    0
sin(pi/6):   1/2
sin(pi/4):   root(2)/2
sin(pi/3):   root(3)/2
sin(pi/2):   1
sin(2pi/3):  root(3)/2
sin(3pi/4):  root(2)/2
sin(5pi/6):  1/2
sin(1pi):    0
sin(7pi/6):  -1/2
sin(5pi/4):  -root(2)/2
sin(4pi/3):  -root(3)/2
sin(3pi/2):  -1
sin(5pi/3):  -root(3)/2
sin(7pi/4):  -root(2)/2
sin(11pi/6): -1/2
sin(2pi):    0

cos(0pi):    1
cos(pi/6):   root(3)/2
cos(pi/4):   root(2)/2
cos(pi/3):   1/2
cos(pi/2):   0
cos(2pi/3):  -1/2
cos(3pi/4):  -root(2)/2
cos(5pi/6):  -root(3)/2
cos(1pi):    -1
cos(7pi/6):  -root(3)/2
cos(5pi/4):  -root(2)/2
cos(4pi/3):  -1/2
cos(3pi/2):  0
cos(5pi/3):  1/2
cos(7pi/4):  root(2)/2
cos(11pi/6): root(3)/2
cos(2pi):    1

tan(0pi):    0
tan(pi/6):   root(3)/3
tan(pi/4):   1
tan(pi/3):   root(3)
tan(pi/2):   nan
tan(2pi/3):  -root(3)
tan(3pi/4):  -1
tan(5pi/6):  -root(3)/3
tan(1pi):    0
tan(7pi/6):  root(3)/3
tan(5pi/4):  1
tan(4pi/3):  root(3)
tan(3pi/2):  nan
tan(5pi/3):  -root(3)
tan(7pi/4):  -1
tan(11pi/6): -root(3)/3
tan(2pi):    0

If you get a number larger than 2pi, subtract 2pi from it until you get a number that is in range. For example, sin(17pi/6) is the same as sin(5pi/6) == 1/2. Your program is expected to do basic simplification, for example, if your input is cos(2pi/4) this is the same as cos(pi/2) == 0. Builtin trigonometry functions are disallowed.

Shortest answer in bytes wins!

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

Pyth, 125 122 bytes

Uses the formula n = 4 - |floor(4.5-9k)|, where kπ = θ i.e. k is the quotient of the second and third inputs, to determine which special angle is in question: the angles 0, 30, 45, 60 and 90 degrees are numbered 0 to 4 respectively, and the 90~180 degrees angles go in reverse; this formula works for θ∈[0,π]. The values of corresponding sines would be sqrt(n)/2 and existent, non-zero tangents would be 3^(n/2-1). However, my implementation uses lists with hard-coded compressed strings for higher control of output format, and it seems the code is shorter that way too.

A,c." t8¾Îzp³9ÓÍÕ¬$ ·Íb³°ü"dc." t@a'óè©ê¶oyÑáîwÀ(";J+cEE?qz\c.5ZK-4.as-4.5*3*3%J1?qz\t+?>%J1 .5\-k@GK+?>%J2 1\-k@HK

Let's turn it into pythonic pseudocode:

                                   z = input()
                                   k = ""
                                   d = " "
                                   Z = 0
A,c." t8¾Îzp³9ÓÍÕ¬$ ·Íb³°ü"d       G = "0 sqrt(3)/3 1 sqrt(3) nan".split(d)
  c." t@a'óè©ê¶oyÑáîwÀ(";          H = "0 1/2 sqrt(2)/2 sqrt(3)/2 1".split()
J+cEE                              J = eval(input())/eval(input()) +
  ?qz\c.5Z                             0.5 if z == "c" else Z
                                   # the second term converts sin to cos
K-4.as-4.5*3*3%J1                  K = 4 - abs(int(4.5 - 3*3*(J%1)))
                                   # 9* would lose precision so 3*3* instead
?qz\t                              if z == "t"
  +?>%J1 .5\-k                         print(("-" if J%1 > 0.5 else k) +
   @GK                                     G[K])
                                   else:
  +?>%J2 1\-k                          print(("-" if J%2 > 1 else k) +
   @HK                                     H[K])

Test online.

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