20
2
Trigonometry has LOTS of identities. So many that you can expand most functions into sines and cosines of a few values. The task here is to do that in the fewest bytes possible.
Identity list
Well, the ones we're using here.
sin(-x)=-sin(x)
sin(π)=0
cos(-x)=cos(x)
cos(π)=-1
sin(a+b)=sin(a)*cos(b)+sin(b)*cos(a)
cos(a+b)=cos(a)cos(b)-sin(a)sin(b)
For the sake of golfing, I've omitted the identities that can be derived from these. You are free to encode double-angles and such but it may cost you bytes.
Input
- You should take in an expression as a string with an arbitrary number of terms consisting of a coefficient and some sine and cosine functions, each with an exponent and an arbitrary number of arguments.
- Coefficients will always be nonzero integers.
- Each argument will be a coefficient, followed by either a single latin letter or pi.
- You can decide whether to take in pi as
pi
orπ
. Either way remember that you're scored in bytes, not characters.
Output
Output the same expression, but…
- All trig functions are either
sin
orcos
. - All arguments of trig functions are single variables, with no coefficients.
- All like terms are combined.
- Terms with a coefficient of 0 are removed.
- All factors in the same term that are the same function of the same variable are condensed into a single function with an exponent.
Note: Leading +
signs are allowed, but not required. a+-b
is allowed, and equivalent to a-b
. If there are no terms with nonzero coefficients, then output either 0
or an empty string.
Worked Example
We'll start with sin(-3x)+sin^3(x)
. The obvious first thing to do would be to deal with the sign using the parity identity, leaving -sin(3x)
. Next I can expand 3x
into x+2x
, and apply the sine additive identity recursively:
-(sin(x)cos(2x)+cos(x)sin(2x))+sin^3(x)
-(sin(x)cos(2x)+cos(x)(sin(x)cos(x)+sin(x)cos(x)))+sin^3(x)
Next, some distributive property and like terms:
-sin(x)cos(2x)-2cos^2(x)sin(x)+sin^3(x)
Now, I expand the cos(2x)
and apply the same reduction:
-sin(x)(cos(x)cos(x)-sin(x)sin(x))-2cos^2(x)sin(x)+sin^3(x)
-sin(x)cos^2(x)+sin^3(x)-2cos^2(x)sin(x)+sin^3(x)
2sin^3(x)-3sin(x)cos^2(x)
And now, it's finished!
Test Cases
In addition to the following, all of the individual identities (above) are test cases. Correct ordering is neither defined nor required.
cos(2x)+3sin^2(x) => cos^2(x)+2sin^2(x)
sin(-4x) => 4sin^3(x)cos(x)-4sin(x)cos^3(x)
cos(a+2b-c+3π) => 2sin(a)sin(b)cos(b)cos(c)-sin(a)sin(c)cos^2(b)+sin(a)sin(c)sin^2(b)-cos(a)cos^2(b)cos(c)+cos(a)sin^2(b)cos(c)-2cos(a)sin(b)cos(b)sin(c)
sin(x+674868986π)+sin(x+883658433π) => 0 (empty string works too)
sin(x+674868986π)+sin(x+883658434π) => 2sin(x)
…and may the shortest program in bytes win.
May we output (for example)
sin(x)^3
rather thansin^3(x)
? Can we take pi asPI
as well? – Giuseppe – 2018-04-06T17:01:01.5502
This looks very close to a dup of https://codegolf.stackexchange.com/questions/38341/help-me-with-trigonometry
– Digital Trauma – 2018-04-06T17:11:52.3731@DigitalTrauma that seems to be about printing a specific answer set, not a generalized and specified input-processing challenge. – Nissa – 2018-04-06T17:24:15.790
@Giuseppe sure, whatever format is best. – Nissa – 2018-04-06T17:25:02.087
I presume it's okay to have a constant (i.e. not a coefficient of sin or cos) in the output, since it's possible to deduce sin^2 + cos^2 = 1 only using the identities given? – JungHwan Min – 2018-04-06T17:45:21.897
@JungHwanMin how so? (Though you will encounter constants, like cos(π).) – Nissa – 2018-04-06T17:48:53.953
1
cos(0) = cos(pi+(-pi)) = cos(pi)cos(-pi) - sin(pi)sin(-pi) = cos(pi)cos(pi) - 0 = (-1)^2 = 1
. So,1 = cos(0) = cos(x+(-x)) = cos(x)cos(-x) - sin(x)sin(-x) = cos(x)cos(x) + sin(x)sin(x) = cos^2(x) + sin^2(x)
. – JungHwan Min – 2018-04-06T17:51:00.410Is it fine to simplify
sin^2 + cos^2
to1
? – JungHwan Min – 2018-04-06T17:59:03.963@JungHwanMin yeah, that's fine, but it's not strictly required. As long as the output has no like terms or factors and is fully expanded, it's fine. – Nissa – 2018-04-06T18:07:53.007
@JungHwanMin It must be, as it stems from applying the last identity with
b=-a
and then the first and third – Luis Mendo – 2018-04-06T18:08:07.773"Coefficients and will always be nonzero integers" must be missing a word (or has a word too many). Sorry, should have caught this in sandbox. – Peter Taylor – 2018-04-06T23:08:31.630
@PeterTaylor it's never too late to fix a typo! – Nissa – 2018-04-06T23:29:28.030
Are built-ins allowed? (I am thinking of doing this in Mathematica, with TrigExpand) – NoOneIsHere – 2018-04-07T00:05:25.920
1@NoOneIsHere yes, but I won't upvote it because it's zero-effort. – Nissa – 2018-04-07T01:16:15.580
This looked very easy to me before I actually read it. – Manish Kundu – 2018-04-07T07:41:16.243
@JungHwanMin Wow. I predicted that it may be possible to deduce sin²x+cos²x=1 while it was in the sandbox, but could not prove it. Now it's indeed true. – user202729 – 2018-04-07T11:23:33.337
"You should take in an expression as a string"<- Is this a strict requirement? For eg. Julia has an
Expr
type for expressions, can the input be ofExpr
type? Also, will the operation between terms in the expression always be addition? Issin(-3x)-sin^3(x)
a possible input? – sundar - Reinstate Monica – 2018-06-16T14:37:34.667@sundar yes, that would be a possible input. – Nissa – 2018-06-16T22:35:18.370