Arco aproximado

9

El objetivo es simple: generar una solución real distinta de cero xpara la ecuación sin(x) = -mx, dada la entrada m, en la menor cantidad de bytes.

Especificaciones:

  • Su respuesta debe ser correcta a 3 cifras significativas.
  • Puede generar cualquier solución real que no sea la solución trivial x=0. Puede suponer que mes tal que existe al menos una solución. También puedes asumir m!=0.

Una solución de Python obviamente subóptima que usa descenso de gradiente :

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

Casos de prueba

-0.25 -> ±2.4746
-0.1  -> ±2.8523 or ±7.0682 or ±8.4232
 0.2  -> ±4.1046 or ±4.9063 
theideasmith
fuente
1
El mejor enfoque aquí es imprimir un valor fijo, aunque debe especificar cuántos decimales se requieren. Sugeriría incluir un parámetro de entrada, como aresolver sin(x)=-ax. Por favor, no diga "realmente tiene que calcularlo", ya que requisitos como ese son demasiado vagos para funcionar.
xnor
Además, x=0es una solución trivial. Debe especificar qué solución desea.
xnor
Necesita algunos límites en m para garantizar una solución distinta de cero.
xnor
m=0tiene soluciones ( x=kπpara enteros k). Los valores mque no tienen soluciones reales no triviales son aquellos que están demasiado lejos 0.
Peter Taylor
1
¿Está buscando solo soluciones de valor real o también se permiten soluciones de valor complejo?
millas

Respuestas:

1

ised : 32 28 bytes

Usando la iteración de Newton a partir de π:

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

Se pasa el argumento $1, que se puede tomar de un archivo, así:

ised --l inputfile.txt 'code'

Un poco menos estable, pero versión más corta:

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

A veces arroja advertencias de límite de iteración, pero la precisión parece buena teniendo en cuenta las condiciones.

Versión Unicode (mismo bytecount):

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

A partir de 4 corta otro byte y parece converger a los mismos valores

{λ{x-tanx}/{1+$1/cosx}}∙4
Orión
fuente
8

Haskell, 34 bytes

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

Cuenta xdesde 0 por 0.001 hasta sin(x)< -m*x.

Ejemplos de salida

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
fuente
¿Qué hay de m=-0.1?
Peter Taylor
@PeterTaylor Tenga en cuenta si es necesario, pero da 2.853, lo que parece correcto.
xnor
Por supuesto, ambas son funciones extrañas, por lo que si hay una solución, hay una solución positiva. Doh
Peter Taylor
¿Por qué responderías un desafío que sabes que no está claro?
Mego
2

Mathematica, 28 bytes

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

Busca una raíz numérica desde la suposición inicial x=1. Casos de prueba:

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

fuente
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;}

sin golf:

#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
fuente
1

MATL , 17 bytes

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

Esto utiliza la búsqueda lineal en el eje real positivo, por lo que es lento. Todos los casos de prueba finalizan en 1 minuto en el compilador en línea.

Pruébalo en línea!

Explicación

`         % 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
fuente
1

C ++ 11, 92 91 bytes

-1 byte para usar #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
fuente
0

Python 2, 81 78 bytes

Iteración de punto fijo

Como lambda recursiva

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

Como bucle (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
fuente
0

Mathematica, 52 bytes

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

Función anónima. Toma un número como entrada y devuelve una lista de números como salida. Solo se usa NSolvepara resolver la ecuación aproximada.

LegionMammal978
fuente
Si reemplaza Sin@x==-x#con Sinc@x==-#puede eliminar~DeleteCases~0.
0

Axioma, 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)

resultados

(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
fuente
0

Haskell, 50 bytes

Acabo de aprender sobre el método de newton en mi clase calc, así que aquí entra haskellusando el método de newton.

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

theideasmith
fuente