Risolvi un'equazione lineare


12

Questa sfida ma con una specifica migliore.

Spec

Il tuo programma prenderà un'equazione lineare contenente una singola variabile xe genererà il valore di x.

Input / Analisi

  • L'input conterrà solo numeri, operatori, parentesi ( ()) xe un =segno (questo significa nessuno spazio).
  • Le parentesi saranno sempre bilanciate.
  • Ci sarà sempre almeno 1 x. Un xpuò essere preceduto da un numero.
  • Tutte le equazioni avranno esattamente un risultato.

È possibile definire un numero seguendo questi passaggi. Un numero può essere definita dalla regex: -?(\d+(\.\d+)?|\.\d+).


Se non parli regex: una cifra è definita come 0-9

  1. Potrebbe avere -all'inizio un significato negativo
  2. Quindi potrebbero esserci delle cifre. Se non sono presenti cifre, ci sarà un punto decimale
  3. Se esiste un punto decimale, almeno una cifra lo seguirà

Il più grande sarà un numero / valore è definito dalle capacità della tua lingua.


Un operatore è uno dei seguenti: +-*/appariranno sempre tra numeri e / o parentesi

questo significa che (5)(5)non è un input valido per motivi di semplicità.


Le parentesi conterranno sempre un'espressione valida (una combinazione valida di numeri e / o operatori) al loro interno. La parentesi "bilanciata" è definita in quanto ad ogni (verrà associata una chiusura)

Valutazione

  • È necessario seguire l'ordine delle operazioni e le precedenti sono (dal più alto al più basso):
    • Parentesi (prima il più profondamente annidato)
    • Moltiplicazione e divisione
    • Addizione e sottrazione
  • Se si verificano due operatori con la stessa precedenza, dovresti preferire andare a sinistra -> a destra

Produzione

Dovresti produrre il risultato in qualche modo. Se non si genera solo il risultato numerico, chiarire nella risposta come viene emesso l'output. Il formato di output deve essere coerente. L'output può essere un decimale, ma sarà sempre razionale, la precisione è limitata alla precisione della tua lingua. Solo se la tua lingua non supporta l'aritmetica in virgola mobile, non è necessario supportarla.

Regole

  • Gli incorporamenti che banalizzano questa attività sono consentiti , ma è necessario aggiungere [uses built-in]chiaramente l'intestazione della risposta. Questo esonera la tua risposta dalla vincita
  • Un "built-in che banalizza questo compito" è uno dei seguenti:
    • Qualcosa che accetta un'equazione e genera il valore per a / la variabile
    • Qualcosa che semplificherà completamente un'equazione
    • Utilizzo evalo una funzione correlata per eseguire una quantità significativa dell'analisi. L'uso evale le funzioni correlate non sono consentite se sono abituati a (con una modifica minima all'input) risolvere equazioni lineari.
    • In caso di dubbi, basta chiedere in un commento.
  • Sono consentiti built-in che analizzano l'equazione

Esempi

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

Ingressi non validi :

(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

8
Dici che gli incorporamenti squalificano il tuo invio, ma chiariscilo per fare riferimento solo alle operazioni che risolvono e analizzano l'equazione e simili. Penso che sarebbe più chiaro usare un termine diverso, dal momento che penso a qualsiasi operazione denominata come integrata.
xnor

Quanto devono essere precise le risposte?
flawr

@MrPublic Il tuo programma prenderà un'equazione lineare contenente una singola variabile ...
Luis Mendo

Inoltre, JavaScript evalconta come banalizzare la sfida? Inoltre, le forme di new Function(...)conteggio?
Conor O'Brien,

@ CᴏɴᴏʀO'Bʀɪᴇɴ dipende da cosa lo usi. Ma supponendo che tu stia utilizzando JavaScript, non vedo come banalizzerà la sfida così sicuro
Downgoat,

Risposte:


3

JavaScript ES6, 246 byte

Ancora del golf da fare, ma almeno è una soluzione!

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}

Assegna un nome alla funzione n=>{n=n.split("=")...per 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
    };
}

Questo utilizza un approccio pivot. (Non sono sicuro se questo è ciò che viene chiamato l'algoritmo, solo un nome che ho inventato.) In primo luogo raccoglie quale direzione cercare da zero (cioè, in che modo si intersecano le pendenze dei due lati delle equazioni) e cerca il valore. Una volta che trova un punto di minima differenza, va a quel punto e diminuisce l'incremento di ricerca. Questo alla fine produce esattamente la soluzione di cui abbiamo bisogno.


Penso che potresti raderti un po 'usando la sintassi eval + ES6 invece di Function new
Ven

2

JavaScript (Node.js) , 106 93 byte

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

Provalo online!

-13 byte grazie a @tsh

Ungolfed:

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
}

spiegazione:

Questa soluzione funziona con il metodo di Newton per trovare le radici. Il codice sottrae il lato destro dell'equazione dal lato sinistro, in modo tale che quando f(x)=0, xsarà uguale al valore che stiamo risolvendo. Pertanto, quando troviamo la radice di questa nuova funzione, sarà il nostro xvalore desiderato . Quindi trova la derivata f'(x)trovando la pendenza tra due punti sulla funzione. Quindi, i valori vengono semplicemente inseriti nel metodo di Newton che afferma per un'approssimazione della radice x, x=x-(f(x)/f'(x))(nel codice, usiamo 0 come xvalore iniziale ). Dal momento che questo trova le radici, trova il nostro xvalore. E poiché si garantisce che l'equazione sia lineare, l'approssimazione sarà esatta.



1

Mathcad, [usa il built-in]

inserisci qui la descrizione dell'immagine

Mathcad ha due metodi integrati per risolvere tali equazioni:

  • Risolutore simbolico (usa la parola chiave risolve)
  • Risolvi blocco (che funziona sia in modalità numerica che simbolica). Un blocco di risoluzione inizia con la parola chiave Dato, seguito da una serie di espressioni che definiscono le condizioni di interesse e chiuso da una delle parole chiave di risoluzione, come Trova (che trova una soluzione esatta) o MinErr (che minimizza l'errore tra il target e qualsiasi soluzione).

Il risolutore simbolico è abbastanza soddisfatto di y = x e restituisce la soluzione x = y.

Per coloro che non hanno familiarità con Mathcad, l'immagine seguente è presa direttamente dalla cartella di lavoro di WYSIWYGish Mathcad 15. La modifica di una delle espressioni in cui sono scritte farà sì che Mathcad rivaluti la sua risposta e aggiorni il display di conseguenza.


Per curiosità oziosa, perché i voti negativi? Posso capire che la sua semplicità può essere alla radice, ma in sostanza sembra non essere diversa dalla soluzione TI Basic, che aggiunge semplicemente una piccola quantità di elaborazione dell'input prima di chiamare il solutore integrato e tuttavia non è stato sottoposto a downgrade.
Stuart Bruff,

1
Qual è il numero effettivo di byte di questo programma?
Jo King,

I downvotes sono probabilmente dovuti al fatto che la tua soluzione è banale: vedi "Cos'è una soluzione banale?" su meta.

0

Axiom, 214 byte [usa il built-in]

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)

Per alcuni errori restituire% i, per altri tipi di errori la funzione viene arrestata dal sistema, qualcos'altro come 1--2 sembra fuori lingua ... test:

(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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.