Doğrusal Bir Denklem Çözme


12

Bu meydan okuma ama daha iyi bir spesifikasyon ile.

spec

Programınız tek bir değişken içeren doğrusal bir denklem alır xve değerini verir x.

Giriş / Ayrıştırma

  • Giriş yalnızca sayılar, işleçler, parantez ( ()) xve bir =işaret içerecektir (bu boşluk olmadığı anlamına gelir).
  • Parantez daima dengelenir.
  • Her zaman en az 1 olacak x. Bir xçok sayıda yer alabilir.
  • Tüm denklemlerin bir sonucu olacaktır.

Bu adımlar izlenerek bir sayı tanımlanabilir. Çok sayıda normal ifade tarafından tanımlanabilir: -?(\d+(\.\d+)?|\.\d+).


Normal ifade bilmiyorsanız: Bir rakam şu şekilde tanımlanır: 0-9

  1. Bu bir olabilir -It nım negatif başında
  2. Sonra bazı rakamlar olabilir . Eğer herhangi bir rakam değilse ondalık nokta olacaktır
  3. Ondalık basamak varsa, en az bir basamak onu izler

En büyük sayı / değer dilinizin yetenekleri tarafından tanımlanır.


Bir operatör şunlardan biridir: +-*/her zaman sayılar arasında veya parantez içinde görünür

bu (5)(5)basitlik uğruna geçerli bir girdi değildir.


Parantez içinde daima geçerli bir ifade (geçerli bir sayı ve / veya operatör kombinasyonu) bulunur. "Dengeli" parantez, her (birinin ilişkili bir kapanışı olacağı için tanımlanır)

Değerlendirme

  • İşlem sırası izlenmeli ve öncelikler (en yüksekten en düşüğe):
    • Parantez (önce en derin yuvalanmış olan)
    • Çarpma ve Bölme
    • Ekleme çıkarma
  • Aynı önceliğe sahip iki operatör oluşursa sola gitmeyi tercih etmelisiniz -> sağa

Çıktı

Sonucu bir şekilde çıkarmalısınız. Sadece sayı sonucu çıkarmazsanız, cevabınızda çıktının nasıl çıktılandığını netleştirin. Çıktı biçiminiz tutarlı olmalıdır. Çıktı ondalık olabilir, ancak her zaman mantıklı olacaktır, hassasiyet dilinizin hassasiyeti ile sınırlıdır. Yalnızca diliniz kayan noktalı aritmetiği desteklemiyorsa, onu desteklemenize gerek yoktur.

kurallar

  • Bu görevi önemsizleştiren yerleşik öğelere izin verilir, ancak[uses built-in] yanıtın başlığına açıkça eklemeniz gerekir . Bu, cevabınızı kazanmaktan muaf tutar
  • "Bu görevi önemsizleştiren yerleşik öğeler" şunlardan biridir:
    • Bir denklemi alan ve bir / değişkeninin değerini veren bir şey
    • Bir denklemi tamamen basitleştirecek bir şey
    • evalÖnemli miktarda ayrıştırma yapmak veya ilişkili bir işlev kullanmak . Kullanımı evalonlar için kullanılan ve eğer ilgili fonksiyonlar doğrusal denklemleri çözmek (girişine minimum modifikasyonla) izin verilmez.
    • Şüpheniz varsa, sadece bir yorum isteyin.
  • Denklemi ayrıştırmaya izin verilen yerleşikler

Örnekler

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

GEÇERSİZ Girişler:

(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
Yerleşiklerin gönderiminizi diskalifiye ettiğini söylersiniz, ancak bunu sadece denklem çözme ve ayrıştırma ve benzeri işlemleri yapmak için açıklığa kavuşturun. Farklı bir terim kullanmanın daha açık olacağını düşünüyorum, çünkü adlandırılmış herhangi bir işlemi yerleşik olarak düşünüyorum.
xnor

Cevapların ne kadar doğru olması gerekir?
Kusur

@MrPublic Programınız tek bir değişken içeren doğrusal bir denklem alacaktır ...
Luis Mendo

Ayrıca, JavaScript'ler evalzorluğu önemsizleştiriyor mu? Ayrıca, new Function(...)sayım biçimleri olur mu?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ ne için kullandığınıza bağlıdır. Ancak JavaScript kullandığınızı varsayarsak, bu meydan okumayı nasıl önemsizleştireceğini görmüyorum
Downgoat

Yanıtlar:


3

JavaScript ES6, 246 bayt

Hala bazı golf yapılacak, ama en azından bir çözüm!

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}

Kullanılacak işlevi n=>{n=n.split("=")...adlandırın.

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

Bu bir pivot yaklaşımı kullanır. (Algoritma denilen bu olup olmadığından emin değilim, sadece icat ettiğim bir isim.) Önce hangi yönün sıfırdan (yani denklemlerin iki tarafının eğimlerinin kesişeceği) arayacağını toplar ve değeri arar. Minimum fark noktası bulduğunda, o noktaya gider ve arama artışını azaltır. Bu, nihayetinde ihtiyacımız olan bir çözümün kesin sonucunu verir.


Bence Function new yerine eval + ES6 sözdizimini kullanarak iyi bir tıraş olabilirsiniz
Ven

2

JavaScript (Node.js) , 106 93 bayt

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

Çevrimiçi deneyin!

@Tsh sayesinde -13 bayt

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
}

Açıklama:

Bu çözüm, Newton'un kök bulma yöntemiyle çalışır . Kod sağ sol taraftan denklemin tarafı, böyle olduğunda o çıkarır f(x)=0, xbiz çözüyoruz değerine eşit olacaktır. Bu nedenle, bu yeni fonksiyonun kökünü bulduğumuzda, bu bizim arzulanan xdeğerimiz olacaktır. Daha sonra f'(x), fonksiyondaki iki nokta arasındaki eğimi bularak türevi bulur . Daha sonra, değerler sadece kökün bir yaklaşım için bildiren Newton yöntemi içine sokulur x, x=x-(f(x)/f'(x))(kodda, başlangıç olarak 0 kullanımı xdeğeri). Bu kökleri bulduğundan, xdeğerimizi bulur . Ve denklemin doğrusal olduğu garanti edildiğinden, yaklaşım tam olacaktır.



1

Mathcad, [yerleşik kullanır]

resim açıklamasını buraya girin

Mathcad'ın bu tür denklemleri çözmek için iki yerleşik yöntemi vardır:

  • Sembolik çözücü (solve anahtar sözcüğünü kullanır)
  • Bloğu Çöz (hem sayısal hem de sembolik modlarda çalışır). Bir Çözme Bloğu, Verilen anahtar kelimesiyle başlar, ilgilenilen koşulları tanımlayan bir dizi ifadeyi takip eder ve Bul (kesin bir çözüm bulan) veya MinErr (hedef ile arasındaki hatayı en aza indiren) herhangi bir çözüm).

Sembolik çözücü y = x ile oldukça mutlu ve x = y çözümünü döndürüyor.

Mathcad'i bilmeyenler için, aşağıdaki görüntü doğrudan WYSIWYGish Mathcad 15 çalışma kitabından alınmıştır. Yazıldıkları ifadelerin herhangi birinin değiştirilmesi Mathcad'ın cevabını yeniden değerlendirmesine ve ekranı buna göre güncellemesine neden olur.


Boşta kalan meraktan, neden inişler? Sadeliğinin kökünde olabileceğini kavrayabilirim, ancak özünde, yerleşik çözücüyü çağırmadan önce az miktarda girdi işleme ekleyen TI Temel çözümünden farklı değil gibi görünüyor. indirilmedi.
Stuart Bruff

1
Bu programın gerçek bayt sayısı nedir?
Jo King

Downvotes muhtemeldir çünkü çözümünüz önemsizdir - bkz. 'Önemsiz çözüm nedir?' meta.

0

Axiom, 214 bayt [yerleşik kullanır]

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)

Bazı hatalar için% i döndürülür, diğer hata türleri için işlev sistemden durdurulur, 1--2 gibi başka bir şey dil dışında görünür ... 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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.