Ungefähre Arcsinc

9

Das Ziel ist einfach: Geben Sie eine reale Lösung ungleich Null xfür die Gleichung sin(x) = -mxbei gegebener Eingabe min der geringsten Anzahl von Bytes aus.

Spezifikationen:

  • Ihre Antwort muss auf 3 signifikante Zahlen korrekt sein.
  • Sie können jede andere echte Lösung als die triviale Lösung ausgeben x=0. Sie können davon ausgehen m, dass mindestens eine Lösung vorhanden ist. Sie können auch annehmen m!=0.

Eine offensichtlich suboptimale Python-Lösung mit Gradientenabstieg :

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

Testfälle

-0.25 -> ±2.4746
-0.1  -> ±2.8523 or ±7.0682 or ±8.4232
 0.2  -> ±4.1046 or ±4.9063 
theideasmith
quelle
1
Der beste Ansatz besteht darin, einen festen Wert zu drucken. Sie sollten jedoch angeben, wie viele Dezimalstellen erforderlich sind. Ich würde vorschlagen, einen Eingabeparameter einzuschließen, ader gelöst werden soll sin(x)=-ax. Bitte sagen Sie nicht "Sie müssen es tatsächlich berechnen", da solche Anforderungen zu vage sind, um zu funktionieren.
xnor
Auch x=0ist eine triviale Lösung. Sie sollten angeben, welche Lösung Sie möchten.
xnor
Sie benötigen einige Grenzen für m, um eine Lösung ungleich Null zu gewährleisten.
xnor
m=0hat Lösungen ( x=kπfür Ganzzahl k). Die Werte, für mdie es keine nicht trivialen realen Lösungen gibt, sind diejenigen, die zu weit entfernt sind 0.
Peter Taylor
1
Suchen Sie nur echte Lösungen oder sind auch komplexe Lösungen zulässig?
Meilen

Antworten:

1

ised : 32 28 Bytes

Verwenden der Newtonschen Iteration ab π:

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

Das Argument wird übergeben $1, das wie folgt aus einer Datei entnommen werden kann:

ised --l inputfile.txt 'code'

Etwas weniger stabil, aber kürzere Version:

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

Manchmal werden Iterationslimit-Warnungen ausgegeben, aber die Genauigkeit scheint unter Berücksichtigung der Bedingungen in Ordnung zu sein.

Unicode-Version (gleiche Bytezahl):

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

Ausgehend von 4 wird ein weiteres Byte abgeschnitten und scheint zu denselben Werten zu konvergieren

{λ{x-tanx}/{1+$1/cosx}}∙4
Orion
quelle
8

Haskell, 34 Bytes

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

Zählt xvon 0 um 0,001 bis sin(x)< -m*x.

Ausgabebeispiele

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
xnor
quelle
Was ist mit m=-0.1?
Peter Taylor
@PeterTaylor Beachten Sie sicher, ob es erforderlich ist, aber es gibt 2.853, was richtig aussieht.
xnor
Natürlich sind beide seltsame Funktionen. Wenn es also eine Lösung gibt, gibt es eine positive Lösung. Doh.
Peter Taylor
Warum würden Sie eine Herausforderung beantworten, von der Sie wissen, dass sie unklar ist?
Mego
2

Mathematica, 28 Bytes

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

Sucht nach einer numerischen Wurzel aus der anfänglichen Vermutung x=1. Testfälle:

% /@ {-0.25, -0.1, 0.2}
(* {2.47458, 2.85234, 4.10462} *)

quelle
1

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;
}
Karl Napf
quelle
1

MATL , 17 Bytes

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

Dies verwendet eine lineare Suche auf der positiven realen Achse, daher ist sie langsam. Alle Testfälle enden innerhalb von 1 Minute im Online-Compiler.

Probieren Sie es online aus!

Erläuterung

`         % 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
Luis Mendo
quelle
1

C ++ 11, 92 91 Bytes

-1 Byte für die Verwendung #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;}
Karl Napf
quelle
0

Python 2, 81 78 Bytes

Fixpunktiteration

Als rekursives 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

Als Schleife (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
Karl Napf
quelle
0

Mathematica, 52 Bytes

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

Anonyme Funktion. Nimmt eine Zahl als Eingabe und gibt eine Liste von Zahlen als Ausgabe zurück. Wird nur verwendet NSolve, um die ungefähre Gleichung zu lösen.

LegionMammal978
quelle
Wenn Sie ersetzen Sin@x==-x#mit Sinc@x==-#können Sie abschaffen~DeleteCases~0.
0

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)

Ergebnisse

(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
RosLuP
quelle
0

Haskell, 50 Bytes

Ich habe gerade in meiner Calc-Klasse etwas über die Newton-Methode gelernt, daher wird hier haskelldie Newton-Methode verwendet.

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

theideasmith
quelle