9
\$\begingroup\$

The goal is simple: Output a nonzero real solution x to the equation sin(x) = -mx, given input m, in the fewest number of bytes.

Specifications:

  • Your answer must be correct to 3 significant figures.
  • You may output any real solution other than the trivial solution x=0. You can assume m is such that at least one solution exists. You may also assume m!=0.

An obviously suboptimal python solution using gradient descent:

from math import *
from random import *
a=x=0.001
m = 5.
def dE(x):return 2*(sin(x)+m*x+1)*(cos(x)+m)
for i in xrange(1000): x-=dE(x)*a
print x

Test cases

-0.25 -> ±2.4746
-0.1  -> ±2.8523 or ±7.0682 or ±8.4232
 0.2  -> ±4.1046 or ±4.9063 
\$\endgroup\$
  • 1
    \$\begingroup\$ The best approach here is to print a fixed value, though you should specify how many decimal places are required. I'd suggest including an input parameter, like a to solve sin(x)=-ax. Please don't say "you have to actually compute it", since requirements like that are too vague to work. \$\endgroup\$ – xnor Oct 27 '16 at 5:09
  • \$\begingroup\$ Also, x=0 is a trivial solution. You should specify which solution you want. \$\endgroup\$ – xnor Oct 27 '16 at 5:10
  • \$\begingroup\$ You need some bounds on m to guarantee a nonzero solution. \$\endgroup\$ – xnor Oct 27 '16 at 5:23
  • \$\begingroup\$ m=0 has solutions (x=kπ for integer k). The values of m which don't have non-trivial real solutions are those which are too far from 0. \$\endgroup\$ – Peter Taylor Oct 27 '16 at 5:54
  • 1
    \$\begingroup\$ Are you looking for only real-valued solutions or are complex-valued solutions allowed too? \$\endgroup\$ – miles Oct 27 '16 at 6:03

10 Answers 10

1
\$\begingroup\$

ised: 32 28 bytes

Using Newton's iteration starting from π:

{:x-{sinx+$1*x}/{cosx+$1}:}:::pi

The argument is passed in $1, which can be taken from a file, like this:

ised --l inputfile.txt 'code'

A bit less stable, but shorter version:

{:{x-tanx}/{1+$1/cosx}:}:::pi

Sometimes it throws iteration limit warnings but the accuracy seems fine considering the conditions.

Unicode version (same bytecount):

{λ{x-tanx}/{1+$1/cosx}}∙π

Starting from 4 cuts another byte and seems to converge to the same values

{λ{x-tanx}/{1+$1/cosx}}∙4
\$\endgroup\$
8
\$\begingroup\$

Haskell, 34 bytes

f m=until(\x->sin x< -m*x)(+1e-3)0

Counts x up from 0 by 0.001 until sin(x)< -m*x.

Ouput examples

f -0.2 ->   2.595999999999825
f -0.1 ->   2.852999999999797
f  0.0 ->   3.141999999999765
f  0.1 ->   3.4999999999997256
f  0.2 ->   4.1049999999997056
\$\endgroup\$
  • \$\begingroup\$ What about m=-0.1? \$\endgroup\$ – Peter Taylor Oct 27 '16 at 5:55
  • \$\begingroup\$ @PeterTaylor Note sure if it's required, but it gives 2.853, which looks right. \$\endgroup\$ – xnor Oct 27 '16 at 6:00
  • \$\begingroup\$ Of course, they're both odd functions so if there's a solution there's a positive solution. Doh. \$\endgroup\$ – Peter Taylor Oct 27 '16 at 6:05
  • \$\begingroup\$ Why would you answer a challenge that you know is unclear? \$\endgroup\$ – Mego Oct 27 '16 at 6:19
2
\$\begingroup\$

Mathematica, 28 bytes

x/.FindRoot[Sinc@x+#,{x,1}]&

Searches for a numerical root from the initial guess x=1. Test cases:

% /@ {-0.25, -0.1, 0.2}
(* {2.47458, 2.85234, 4.10462} *)
\$\endgroup\$
1
\$\begingroup\$

C, 99 bytes

#include<math.h>
float f(float m){float x=1,y;do{x=(y=sin(x)+m*x)+x;}while(fabs(y)>1e-4);return x;}

ungolfed:

#include<math.h>
float f(float m){
 float x=1,y;
 do{x=(y=sin(x)+m*x)+x;}while(fabs(y)>1e-4);
 return x;
}
\$\endgroup\$
1
\$\begingroup\$

MATL, 17 bytes

`@2e3/tY,wG_*>}4M

This uses linear search on the positive real axis, so it is slow. All test cases end within 1 minute in the online compiler.

Try it online!

Explanation

`         % Do...while
  @       %   Push iteration index, starting at 1
  2e3/    %   Divide by 2000
  t       %   Duplicate
  Y,      %   Sine
  w       %   Swap
  G_*     %   Multiply by minus the input
  >       %   Does the sine exceed that? If so, next iteration
}         % Finally (execute after last iteration, before exiting loop)
   4M     %   Push input of sine function again
          % Implicit end
          % Implicit display
\$\endgroup\$
1
\$\begingroup\$

C++ 11, 92 91 bytes

-1 byte for using #import

#import<cmath>
using F=float;F f(F m,F x=1){F y=sin(x)+m*x;return fabs(y)>1e-4?f(m,x+y):x;}
\$\endgroup\$
0
\$\begingroup\$

Python 2, 81 78 bytes

Fixpoint iteration

As recursive lambda

from math import*
f=lambda m,x=1:abs(sin(x)+m*x)>1e-4and f(m,sin(x)+m*x+x)or x

As loop (81 bytes):

from math import*
m=input()
x=1
while abs(sin(x)+m*x)>1e-4:x=sin(x)+m*x+x
print x
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 52 bytes

NSolve[Sin@x==-x#,x,Reals][[;;,1,2]]~DeleteCases~0.&

Anonymous function. Takes a number as input, and returns a list of numbers as output. Just uses NSolve to solve the approximate equation.

\$\endgroup\$
  • \$\begingroup\$ If you replace Sin@x==-x# with Sinc@x==-# you can do away with ~DeleteCases~0. \$\endgroup\$ – lastresort Oct 27 '16 at 13:29
0
\$\begingroup\$

Axiom, 364 bytes

bisezione(f,a,b)==(fa:=f(a);fb:=f(b);a>b or fa*fb>0=>"fail";e:=1/(10**(digits()-3));x1:=a;v:=x2:=b;i:=1;y:=f(v);if(abs(y)>e)then repeat(t:=(x2-x1)/2.0;v:=x1+t;y:=f(v);i:=i+1;if i>999 or t<=e or abs(y)<e then break;if fb*y<0 then(x1:=v;fa:=y)else if fa*y<0 then(x2:=v;fb:=y)else break);i>999 or abs(y)>e=>"fail";v)
macro g(m) == bisezione(x+->(sin(x)+m*x), 0.1, 4.3)

ungolf

bisezione(f,a,b)==
    fa:=f(a);fb:=f(b)
    a>b or fa*fb>0=>"fail"
    e:=1/(10**(digits()-3))
    x1:=a;v:=x2:=b;i:=1;y:=f(v)
    if(abs(y)>e) then
      repeat
        t:=(x2-x1)/2.0;v:=x1+t;y:=f(v);i:=i+1
        if i>999 or t<=e or abs(y)<e then break
        if      fb*y<0 then(x1:=v;fa:=y)
        else if fa*y<0 then(x2:=v;fb:=y)
        else break
    i>999 or abs(y)>e=>"fail"
    v

macro g(m) == bisezione(x+->(sin(x)+m*x), 0.1, 4.3)

results

(3) -> g(0.2)
   AXIOM will attempt to step through and interpret the code.
   (3)  4.1046198505 579058527
                                                              Type: Float
(4) -> g(-0.1)
   (4)  2.8523418944 500916556
                                                              Type: Float
(5) -> g(-0.25)
   (5)  2.4745767873 698290098
                                                              Type: Float
\$\endgroup\$
0
\$\begingroup\$

Haskell, 50 bytes

I just learned about newton's method in my calc class, so here goes in haskell using newton's method.

f m=foldl(\x _->x-(sin x+m*x)/(cos x+m))0[1..10]

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