Resolver una ecuación lineal

12

Este desafío pero con una mejor especificación.

Especificaciones

Su programa tomará una ecuación lineal que contiene una sola variable xy generará el valor de x.

Entrada / análisis

  • La entrada solo contendrá números, operadores, paréntesis ( ()) xy un =signo (esto significa que no hay espacios en blanco).
  • Los paréntesis siempre serán equilibrados.
  • Siempre habrá al menos 1 x. Un xpuede estar precedido por un número.
  • Todas las ecuaciones tendrán exactamente un resultado.

Se puede definir un número siguiendo estos pasos. Un número se puede definir por la expresión regular: -?(\d+(\.\d+)?|\.\d+).


Si no habla regex: un dígito se define como 0-9

  1. Puede tener un -al principio que significa negativo
  2. Entonces puede haber algunos dígitos. Si no son dígitos, habrá un punto decimal
  3. Si existe un punto decimal, al menos un dígito lo seguirá

El mayor número / valor será definido por las capacidades de su idioma.


Un operador es cualquiera de: +-*/siempre aparecerán entre números o paréntesis

Esto significa (5)(5)que no es una entrada válida en aras de la simplicidad.


El paréntesis siempre contendrá una expresión válida (una combinación válida de números y / u operadores) dentro de ellos. El paréntesis "equilibrado" se define como cada uno (tendrá un cierre asociado)

Evaluación

  • Se debe seguir el orden de las operaciones y las precedentes son (de mayor a menor):
    • Paréntesis (el más anidado primero)
    • Multiplicación y división
    • Suma resta
  • Si se producen dos operadores con la misma precedencia, debe preferir ir a la izquierda -> derecha

Salida

Debe generar el resultado de alguna manera. Si no emite solo el resultado numérico, aclare en su respuesta cómo se emite la salida. Su formato de salida debe ser consistente. La salida puede ser un decimal, pero siempre será racional, la precisión se limita a la precisión de su idioma. Solo si su idioma no es compatible con la aritmética de coma flotante, no es necesario que lo sea.

Reglas

  • Se permiten los elementos integrados que trivializan esta tarea , pero debe agregar [uses built-in]claramente al encabezado de la respuesta. Esto exime su respuesta de ganar
  • Un "Incorporado trivializando esta tarea" es cualquiera de:
    • Algo que toma una ecuación y genera el valor para una / la variable
    • Algo que simplificará completamente una ecuación.
    • Usar evalo una función relacionada para realizar una cantidad significativa del análisis. El uso evaly las funciones relacionadas no se permiten si se utilizan para (con una modificación mínima a la entrada) resolver ecuaciones lineales.
    • Si tiene dudas, solo pregunte en un comentario.
  • Se permiten los elementos integrados que analizan la ecuación.

Ejemplos

3+4=x
7

4+x=5
1

3+3*3=x
12

3x-4=7+2x
11

3--1=x
4

3*(2+4x)=7x-4
-2

1.2+2.3x=5.8
2

10=4x
2.5

Entradas inválidas :

(5)(4)=x  no operator between (5) and (4)
5(x+3)=2  no operator 5 and (...)
x=y       the only variable is x
4=3       there is no x
x+3=x-7   no solution
x=x       infinite solutions
+5=x      + is not an unary operator. -5=x would be valid though
1/(x-3)=5 Nonlinear
3/x       Nonlinear
Downgoat
fuente
8
Usted dice que las incorporaciones descalifican su presentación, pero aclara esto para referirse solo a operaciones que resuelven ecuaciones, analizan y similares. Creo que sería más claro usar un término diferente, ya que pienso en cualquier operación con nombre como una función incorporada.
xnor
¿Qué tan precisas deben ser las respuestas?
flawr
@MrPublic Su programa tomará una ecuación lineal que contiene una sola variable ...
Luis Mendo
Además, ¿cuenta JavaScript para evaltrivializar el desafío? Además, ¿las formas de new Function(...)conteo?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ depende de para qué lo use. Pero suponiendo que esté usando JavaScript, no veo cómo va a trivializar el desafío tan seguro
Downgoat

Respuestas:

3

JavaScript ES6, 246 bytes

Todavía queda algo de golf, ¡pero al menos es una solución!

C=a=>new Function("x","return "+a.replace(/(\d)x/g,"$1*x"));n=>{n=n.split("=");t=Math.abs,r=C(n[0]),c=C(n[1]),a=0,i=r(a)-c(a);a++;v=r(a)-c(a);o=t(i)<t(v)?-1:1;for(u=1/0;r(a)!==c(a);)a+=o,e=t(r(a)-c(a)),e>u&&(u=1/0,o/=10),u=Math.min(e,u);return a}

Nombra la función n=>{n=n.split("=")...para usarla.

Hyper-ungolfed:

function solveLinear(equation){
    equation = equation.split("=");
    var abs = Math.abs;
    var LHS = convertToFunction(equation[0]), RHS = convertToFunction(equation[1]);
    var pivot = 0;
    var dir;
    var dir1 = LHS(pivot) - RHS(pivot);
    pivot++;
    var dir2 = LHS(pivot) - RHS(pivot);
    if(abs(dir1)<abs(dir2)) dir = -1;
    else dir = 1;
    var dif, minDif = Infinity;
    while(LHS(pivot) !== RHS(pivot)){
        pivot += dir;
        dif = abs(LHS(pivot) - RHS(pivot));
        if(dif > minDif){
            minDif = Infinity;
            dir /= 10;
        }
        minDif = Math.min(dif, minDif);
        console.log(pivot,dir,dif,minDif);
    }
    return {
        x: pivot,
        LHS: LHS,
        RHS: RHS
    };
}

Esto utiliza un enfoque de pivote. (No estoy seguro de si así se llama el algoritmo, solo un nombre que inventé). Primero recoge en qué dirección buscar desde cero (es decir, de qué manera se intersectarán las pendientes de los dos lados de las ecuaciones) y busca el valor Una vez que encuentra un punto de mínima diferencia, va a ese punto y disminuye el incremento de búsqueda. Esto finalmente da como resultado una solución precisa que necesitamos.

Conor O'Brien
fuente
Creo que podría afeitarse un poco utilizando la sintaxis eval + ES6 en lugar de Function new
Ven
2

JavaScript (Node.js) , 106 93 bytes

a=>eval(`f=x=>${a[R='replace'](/(\d)x/g,"$1*x")[R]("=","-(")[R](/-/g,"+-")})`)(0)/(f(0)-f(1))

Pruébalo en línea!

-13 bytes gracias a @tsh

Sin golf:

var h=a=>{
  a=a.replace(/(\d)x/g,"$1*x").replace("=","-(").replace("--","- -"); //get into an eval-able form
  var f=x=>eval(a+")");
  var df=(f(1)-f(0))/(1-0) //derivative or slope of the function
  var x=0;
  return x-(f(x)/df); //newton's method
}

Explicación:

Esta solución funciona con el método de Newton para encontrar raíces. El código resta el lado derecho de la ecuación del lado izquierdo, de manera que cuando f(x)=0, xserá igual al valor que estamos despejando. Por lo tanto, cuando encontremos la raíz de esta nueva función, será nuestro xvalor deseado . Luego encuentra la derivada f'(x)al encontrar la pendiente entre dos puntos de la función. A continuación, los valores se inserta simplemente en el método de Newton que establece una aproximación de la raíz x, x=x-(f(x)/f'(x))(en el código, se utiliza como un 0 inicial de xvalor). Como esto encuentra las raíces, encuentra nuestro xvalor. Y como se garantiza que la ecuación sea lineal, la aproximación será exacta.

Logern
fuente
93 bytes
tsh
1

Mathcad, [utiliza incorporado]

ingrese la descripción de la imagen aquí

Mathcad tiene dos métodos integrados para resolver tales ecuaciones:

  • Solucionador simbólico (utiliza la palabra clave resolver)
  • Resolver bloque (que funciona tanto en modo numérico como simbólico). Un bloque de resolución comienza con la palabra clave Given, seguido de un conjunto de expresiones que definen las condiciones de interés y cerrado por una de las palabras clave de resolución, como Find (que encuentra una solución exacta) o MinErr (que minimiza el error entre el objetivo y alguna solución).

El solucionador simbólico está bastante contento con y = x y devuelve la solución x = y.

Para aquellos que no están familiarizados con Mathcad, la imagen a continuación se toma directamente del libro de trabajo WYSIWYGish Mathcad 15. Cambiar cualquiera de las expresiones donde están escritas hará que Mathcad reevalúe su respuesta y actualice la pantalla en consecuencia.

Stuart Bruff
fuente
Por curiosidad ociosa, ¿por qué los votos negativos? Puedo entender que su simplicidad puede estar en la raíz de esto, pero en esencia parece no ser diferente de la solución TI Basic, que simplemente agrega una pequeña cantidad de procesamiento de entrada antes de llamar al solucionador incorporado y, sin embargo, eso no fue rechazado.
Stuart Bruff
1
¿Cuál es el recuento de bytes real de este programa?
Jo King el
Los votos negativos son probables porque su solución es trivial: consulte "¿Qué es una solución trivial?" en meta.
0

Axiom, 214 bytes [utiliza incorporado]

q(t:EQ POLY FLOAT):Any==(a:=[variables(lhs t),variables(rhs t)];a.1~=[x]and a.1~=[]=>%i;a.2~=[x]and a.2~=[]=>%i;a.1=[]and a.2=[]=>%i;a.1=[x]and degree(lhs t,x)>1=>%i;a.2=[x]and degree(rhs t,x)>1=>%i;rhs solve(t).1)

Para algún error devolvería% i, para otro tipo de errores la función se detiene del sistema, algo más como 1--2 parece estar fuera del lenguaje ... prueba:

(72) -> q(x+3=9)
   (72)  6.0
                                  Type: Complex Fraction Polynomial Float
(73) -> q(3+4=x)
   (73)  7.0
                                  Type: Complex Fraction Polynomial Float
(74) -> q(4+x=5)
   (74)  1.0
                                  Type: Complex Fraction Polynomial Float
(75) -> q(3+3*3=x)
   (75)  12.0
                                  Type: Complex Fraction Polynomial Float
(76) -> q(3*x-4=7+2*x)
   (76)  11.0
                                  Type: Complex Fraction Polynomial Float
(77) -> q(3--1=x)
  Line   1: q(3--1=x)
           .AB
  Error  A: Missing mate.
  Error  B: syntax error at top level
  Error  B: Possibly missing a )
   3 error(s) parsing
(77) -> q(3*(2+4*x)=7*x-4)
   (77)  - 2.0
                                  Type: Complex Fraction Polynomial Float
(78) -> q(1.2+2.3*x=5.8)
   (78)  2.0
                                  Type: Complex Fraction Polynomial Float
(79) -> q(10=4*x)
   (79)  2.5
                                  Type: Complex Fraction Polynomial Float
(80) -> q((5)(4)=x)
   Cannot find a definition or applicable library operation named 5
      with argument type(s)
                           PositiveInteger

  Perhaps you should use "@" to indicate the required return type,
  or "$" to specify which version of the function you need.
(80) -> q(5(x+3)=2 )
   (80)  %i
                                                    Type: Complex Integer
(81) -> q(x=y)
   (81)  %i
                                                    Type: Complex Integer
(82) -> q(4=3)
   (82)  %i
                                                    Type: Complex Integer
(83) -> q(x+3=x-7)
   >> Error detected within library code:
   inconsistent equation
protected-symbol-warn called with (NIL)
(83) -> q(x=x)
   >> Error detected within library code:
   equation is always satisfied
protected-symbol-warn called with (NIL)
RosLuP
fuente