Help me with trigonometry!

8

2

Thank you guys so much for your help with calculus. Now I need some help with my upcoming trigonometry test.

On the test, I'll need to simplify expressions. I’ll be given input like 4sin(x)/(2cos(x)) and will have to produce a simpler, but equivalent expression (such as 2tan(x)). All angles are in degrees, and we'll pretend there are no division-by-zero or invalid-domain issues. (For example, we'll assume that tan(x+1)cot(x+1)sin(x)/sin(x) is always 1.)

I snuck into the professor's office, and got a list of 100 problems that might be on the test. Please give me teh code to solve them all. It’s possible that some of the problems are already simplified as much as possible; if so just give back the input.

I need expressions to be simplified, but I also want a short program (or function) so the professor won't notice. Try to minimize the sum of the program’s length and the total length of all of the solutions.

Just to clarify, it's okay if some of the expressions are returned unchanged, or even returned in an equivalent but longer form. Also, the program only needs to work on the expressions listed below; it can return incorrect results or even break for other inputs.

As you can tell, all of the problems follow a similar format. x is the only variable used, there are no spaces, and parentheses follow each function name. (The functions are sin, cos, tan, sec, csc, and tan.) There are no nested functions, but inside a function may be an expression like 3x+4.5 or -2-.7x. Exponents may be used, but only on functions (e.g. sin(x-.5)^7), and the power is always a integer above one. Multiplication is indicated through concatenation.

The outputs will need to be in this format as well. Invalid: sin x, sin(x)/cos(x)tan(x) [is the tangent multiplied or divided?], cos(x [close all parentheses], 4*sin(x), sec(x)^1

I can use any programming language, unless it relies on built-in simplification or expression-handling functions. Built-in trig functions are okay. (I'll have a very basic scientific calculator during the test.) Also, since I'll be reading the program written on paper, I can only use printable ASCII characters (0x20 through 0x7E) and newlines.

1/(sec(x))
4+sin(x)+3
(cos(7x+4)-sin(-3x))/(sin(-3x))
2sin(x)2tan(x).25cos(x)^3cos(x)+1+1
7cos(x)sec(x)/(14tan(x)csc(x))
sin(x)cos(x)/sec(x)
8sin(x)cos(x)sin(x)/tan(x)+8sin(x)
sin(x)^9cos(x)cot(x)sec(x)csc(x)sec(x)tan(x)/(cot(x)^2tan(x)cos(x)^4cot(x)sin(x))
tan(x)cos(x)csc(x)
tan(x+1)sin(x-1)cos(x+1)^3tan(x-1)^2sin(-x+1)csc(x+1)tan(-x+1)/(cos(x-1)cot(x+1))
(cos(2x)+cot(2x)-sin(2x)+csc(2x)^3)/(cot(2x)+sin(2x))
cos(90-x)cos(x)
sin(x+180)sec(450-x)
tan(-x)sin(x+90)sec(x-90)
tan(x+180)^2
cot(-x)cos(-x)
cot(180-x)^3cos(270-x)^2
sin(.1x-.2)sin(.1x-.2)sin(.1x-.2)sin(.2-.1x)sin(.2-.1x)
sin(x)
sin(90-x)sin(x)+cos(90-x)/sec(x)
tan(3x+2)cos(3x+2)/sin(3x+2)-1
cos(x)cos(x)cos(x)cos(x)cos(x)
sec(2x+1)sec(-1-2x)+sec(-2x-1)sec(2x+1)
cos(4x)cot(4x)tan(4x)sin(4x)csc(4x)
-cos(x)+cos(x)+sin(2x-4)-1/csc(2x-4)
sec(x)sec(x+2)cot(x)tan(x-2)tan(x+180)
tan(x)(tan(x))
3sin(x)sin(x)/(3)
cos(x)sin(x)
tan(x)sec(x)^2
tan(x)^2-sec(x)^2
7+sin(x)csc(x)csc(x)+cot(x)^2
sin(90)+cos(-90)+sec(180)
csc(1)+csc(10)-csc(30)-csc(60)+csc(90)
sin(36000001)
csc(800)+(cot(720+x)-sec(4x-720))
sin(-x)+sin(x)
csc(-x)+csc(x)
4sin(x)-sin(x)+tan(x)-2tan(x)
cot(x)+10cot(x+90)+99cot(x+180)+.01cot(x-90)
tan(x)tan(x+180)
sec(x)sin(x+180)tan(x-270)cot(x-450)csc(x+90)
sin(x)/cot(x)+sin(x)/cot(x)
sin(x)csc(x)+tan(x)cot(x)+cos(x)sec(x)
cot(x)
9tan(x+90)+90tan(x+9)
cos(x-9999)+tan(x+99999)
2tan(x)tan(x)/2
tan(x)/tan(x-360)+cos(x+180)/cos(x)
csc(4x)sec(270-4x)
cot(91+x)tan(x-449)
csc(2x)(csc(2x)-sin(2x))
csc(x+1)^2-cot(x+1)cot(x+1)
cot(x)cot(x)+1
tan(x)^2-sec(x)sec(x)
tan(x)/cot(x)+csc(x)/csc(x)
cot(x)sin(x)/cos(x)
csc(x)tan(x)cos(x)
csc(x)cot(x)cos(x)
csc(x+90)csc(-x+270)-1
cot(x)/cot(x)+tan(x)/cot(x)+cot(x)cot(x)
sec(x)sec(x)sec(x)sec(x+90)sec(x-90)sec(x+180)
1-cos(x)cos(x+180)+sin(x)^2
sec(x)sec(x)sec(x)sec(x)/cos(x)+cot(x)
cot(x+1)csc(x-1)sec(x+1)tan(x-1)sin(x+1)cos(x-1)
sin(x)-cos(x)+tan(x)-sec(x)+cos(x)-csc(x)
tan(x+23515)-sec(-.27x-23456)
sec(-.9x)
-tan(-x)-csc(360-x)
cos(-x)sec(x)sin(x)csc(-x)
tan(-x)^2-sin(-x)/sin(x)
tan(x)tan(x)+1
csc(x)^2-1
cot(2x)cot(2x)-csc(2x)/sin(2x)
2sec(x)/(6cos(x))
sec(0)+tan(30)cos(60)-csc(90)sin(120)cot(150)+tan(180)csc(210)sin(240)-cos(270)sec(300)+cot(330)
tan(x-1234567)sec(4781053+x)^2
tan(-1234567x)sec(4781053x)^2
sin(x)^9+cos(x)^7+csc(x)^5-cot(x)^3
cos(-33x-7.7)
sec(-.1-x)+tan(-2x-77)
tan(x)+sin(x)-cos(x)+tan(x)-sin(x)
cos(x)-sec(x)/tan(x)+tan(x)/sin(x)
cot(x)-cos(x)/sin(x)
3cos(x)+2/sec(x)-10sin(x)/(2tan(x))
tan(x+3)^11+sin(x+3)^8-cos(x+3)^5+5
sec(x)+sec(x)
csc(.1x)csc(-.1x)csc(x)
cot(x-7)cot(x-7)cot(x+173)cot(x-7)cot(x+173)cot(x-367)
cos(.0001x+1234567)
cot(45)+tan(225)-sin(210)+cos(-60)
sin(12345)cos(23456)tan(34567)sec(45678)csc(56789)cot(67890)
cos(1234x)+cot(1234)+tan(1234x)+sec(1234)+csc(1234)+sin(1234x)
sec(x)sec(x)sec(x)sec(x)sec(x)sec(x)
csc(x)cot(x)sec(x)csc(x)tan(x)sec(x)cot(x)csc(x)cot(x)cos(x)cos(x)cot(x)sin(x)sin(x)cot(x)
csc(2553273)+cot(1507348)-sec(5518930)+csc(5215523)+tan(3471985)-sec(4985147)
sin(20x)+cos(20x)-tan(20x)+sin(20x)-csc(20x)+cot(20x)-tan(20x)+csc(20x)
cot(100000)+cot(100000x)+cot(100000x)+cot(100000)
csc(5x+777)sin(5x+777)
csc(4.5x)

Note: This scenario is entirely fictional. In real life, cheating and helping others cheat is wrong and should never be done.

Ypnypn

Posted 2014-09-30T02:45:55.023

Reputation: 10 485

5I count no less than forty different identities and mathematical axioms that would be needed to simplify this. Even parsing one of the expressions and getting it into some kind of structured internal form would take a fair bit of code. Too rich for me. But maybe there are some here looking for this kind of a challenge. – COTO – 2014-09-30T04:23:44.723

@COTO you don't have to parse it. You can try to detect which problem it as and hardcode the answers in compressed form. It might even be shorter than parsing. – Ingo Bürk – 2014-09-30T04:51:14.400

@IngoBürk: After re-reading the OP, I would have to agree. "the program only needs to work on the expressions listed below" is pretty forgiving. – COTO – 2014-09-30T05:01:22.317

3if your printer cannot print any non-ASCII character, you need a better printer. – John Dvorak – 2014-09-30T06:56:27.027

Are we allowed to use sqrt? This seems like it will happen quite a bit and we can't use ^.5. – Ingo Bürk – 2014-09-30T09:48:04.493

3I just thougth WTF this guy even got UPVOTES? Then I noticed that it wasn't math.SE, soo... context matters=) – flawr – 2014-09-30T13:14:01.900

Also, how do we simplify expressions with an undefined value? csc(0) is not defined (in the complex plane) – Ingo Bürk – 2014-09-30T13:24:44.263

@IngoBürk No sqrt – Ypnypn – 2014-09-30T13:43:41.713

@IngoBürk I changed the offending values. (I understand it's usually a really bad idea to change the problem once posted, but in this case there was no choice.) – Ypnypn – 2014-09-30T13:46:54.113

@Ypnypn I think the change was a bad idea. I just got done with my answer. Luckily, it doesn't change any of my code and also doesn't allow for good simplifications. – Ingo Bürk – 2014-09-30T13:55:19.680

Are there any requirements for the precision of purely numerical answers? – Digital Trauma – 2014-09-30T16:55:19.583

@DigitalTrauma Infinite precision, e.g. 2/3 != 0.666666667; sin(45) != 0.707. – Ypnypn – 2014-09-30T18:27:10.010

1@Ypnypn Oh, ok, so for example we can't reduce sin(36000001) to .017452 – Digital Trauma – 2014-09-30T18:30:17.197

Answers

8

Python, 436 + 1909 = 2345

This must be one of the most inefficient solutions imaginable and mathematicians will probably cringe, but I've managed to throw something together that actually simplifies about half of the expressions without any hardcoding:

from math import*
import exrex,re
d=lambda f:lambda x:f(x*pi/180)
sin,cos,tan=d(sin),d(cos),d(tan)
i=lambda f:lambda x:1/f(x)
sec,csc,cot=i(cos),i(sin),i(tan)
t=lambda s:[round(eval(re.sub('([\d\).])([\(a-z])','\\1*\\2',s).replace('^','**')+'+0')*1e9)for x in[1,44]]
def f(I):
 try:return min((s for s in exrex.generate('(-?\d|\(1/\d\.\))?([+-]?(sin|cos|tan|cot|sec|csc)\(x\)(\^\d)?){0,4}')if s and t(s)==t(I)),key=len)
 except:return I

The output for the 100 test cases should be the following (where # marks expressions that were not simplified):

cos(x)
7+sin(x)
#
2+tan(x)^2cos(x)^2
(1/2.)cos(x)
sin(x)cos(x)^2
#
sin(x)^2tan(x)^7
1
#
#
sin(x)cos(x)
-1
-1
tan(x)^2
-cot(x)cos(x)
-cot(x)cos(x)^2
#
sin(x)
2sin(x)cos(x)
0
cos(x)^5
#
#
#
#
tan(x)^2
sin(x)^2
sin(x)cos(x)
tan(x)sec(x)^2
-1
7+cot(x)^2+csc(x)
0
#
#
#
0
0
3sin(x)-tan(x)
#
tan(x)^2
-tan(x)sec(x)
2sin(x)tan(x)
3
cot(x)
#
#
tan(x)^2
0
#
1
#
1
csc(x)^2
-1
sec(x)^2
1
1
cot(x)^2
-1-sec(x)^2
cot(x)^2+sec(x)^2
sec(x)^4csc(x)^2
2
cot(x)+sec(x)^5
#
sin(x)+tan(x)-csc(x)-sec(x)
#
#
tan(x)+csc(x)
-1
sec(x)^2
sec(x)^2
cot(x)^2
-1
(1/3.)sec(x)^2
#
#
#
#
#
#
2tan(x)-cos(x)
cos(x)-csc(x)+sec(x)
0
0
#
2sec(x)
#
#
#
3
#
#
sec(x)^6
cot(x)^4csc(x)
#
#
#
1
#

The idea is quite simple:

  • generate a huge amount of possible expressions
  • select those that yield the same result as the expression you want to simplify, comparing them for some (here two) x values
  • from the equivalent expressions return the shortest one

The problem is that there are quite a lot of possible expressions to check, so I limited it to a subset.

To be honest I was not patient enough to test the golfed code above. (Tell me if you think that's cheating.) Instead I used a much longer but more efficient rule to generate an even smaller subset of expressions that hopefully still contains all the desired simplifications. Should you want to try that, replace the regular expression in the second to last line of the code with the following (and be prepared for a few minutes of computation time):

'0|((-1|\(1/[23]\.\)|[1237])[+-]?)?(sin\(x\)(\^2)?)?-?(tan\(x\)(\^[27])?)?(cot\(x\)(\^[24])?)?[+-]?(cos\(x\)(\^[25])?)?(sec\(x\)(\^[2456])?)?(csc\(x\)(\^2)?)?'

The program also contains quite some overhead that was needed to make Python understand the mathematical expressions. This involved

  • redefining sin,cosand tan to take arguments in degrees instead of radiens (which is what I think the OP intended)
  • defining sec,csc and cot which are not part of the math package
  • inserting all the implied multiplication signs
  • replacing the exponentiation operator

Emil

Posted 2014-09-30T02:45:55.023

Reputation: 1 438

@Doorknob How is brute-forcing expressions and comparing two values any more of a "real solution" than the others? – Ingo Bürk – 2014-10-01T06:15:08.250

@Emil Since you only compare two different values for `x', have you somehow ensured that simplifications are actually correct? – Ingo Bürk – 2014-10-01T06:15:36.110

Giving it a quick look I can't find incorrect simplifications (impressive), but to my understanding 1/3.sec(x)^2 is not valid output. – Ingo Bürk – 2014-10-01T06:20:52.787

1@IngoBürk, all the answers were calculated by hand or with WolframAlpha first and I later compared these with the program's output. In two or three cases the program actually found simplifications that WolframAlpha did not output, but I could confirm that theses were correct too. But of course you're right, there could potentially be collisions. It's just that the nature of the functions in question make it quite unlikely that two distinct graphs should intersect at my two points within the used accuracy. I've seen collisions if I use just one point or if the two points are too close together. – Emil – 2014-10-01T06:52:35.903

Oh, I see, the two outputs involving fractions are indeed against the OP's specifications. The shortest option would be sec(x)^2/3but that was hard to implement in my regex without causing problems elsewhere. I think I'll just add parentheses. – Emil – 2014-10-01T06:58:21.067

1@Emil Alright. I really love this solution btw! – Ingo Bürk – 2014-10-01T07:53:41.303

6

CJam, 1 + 3000 = 3001

Just as the baseline solution to give people something to beat:

l

This reads STDIN onto the stack, whose contents are printed at the end of the program.

I'm sure this can be beaten, but I'm also sure that many optimisations can't be implemented in the characters that would be gained.

Martin Ender

Posted 2014-09-30T02:45:55.023

Reputation: 184 808

Was it stated anywhere how to calculate the score? I like your method. However, I would not consider the newlines, so that the base score would be 3000. – Emil – 2014-09-30T08:34:57.090

@Emil "Try to minimize the sum of the program’s length and the total length of all of the solutions." – I had to read it several times as well. – Ingo Bürk – 2014-09-30T09:00:19.637

I wonder why Martin didn't use Golfscript. No need to explicitly read the input there =D – Ingo Bürk – 2014-09-30T09:02:01.083

I don't understand. How is this answer and the below one anyhow related to the question, which asks about trigonometry and stuff – Optimizer – 2014-09-30T09:29:00.990

@Optimizer It is perfectly legal to just return the input as the "simplified" expression. – Ingo Bürk – 2014-09-30T09:45:19.630

2@IngoBürk Because I don't know GolfScript. :P – Martin Ender – 2014-09-30T12:36:29.553

Along similar lines, you can use a zero-length sed program – Digital Trauma – 2014-09-30T16:21:24.653

5

Javascript (438 + 2498 = 2936)

The object in the middle optionally contains simplified outputs based on the length of the input and the first character. Otherwise, the input is returned unmodified.

s='sin(x)';(p=prompt)({
    352:s+"^2cos(x)^3+2",
    307:"cos(x)/2",
    348:s+"8(1+cos(x)^2)",
    "81s":s+"^2tan(x)^7",
    "55s":"-sin(0.2-0.1x)^5",
    "39s":"2sec(2x+1)^2",
    "35c":"cos(4x)",
    "36-":0,
    173:s+"^2",
    "25s":0,
    294:s+"3-tan(x)",
    "27s":s+"2/cot(x)",
    "40c":"1+tan(x)^2+cot(x)^2",
    "48c":1,
    "41s":s+"+tan(x)-csc(x)-sec(x)",
    "26c":-1,
    "24t":"1+tan(x)^2",
    "96s":"2.5+1/cos(30)",
    "34t":"2tan(x)-cos(x)",
    353:0,
    "36s":"6sec(x)",
    "90s":"cot(x)^4csc(x)"
}[(i=p()).length+i[0]]||i)

The whitespace is just for decoration and not included in the character count.

It's a shame that adding all these solutions only saved me a few characters, but better than nothing. The simplification was done via wolframalpha – I'll just trust it.

Ingo Bürk

Posted 2014-09-30T02:45:55.023

Reputation: 2 674