Memecahkan Persamaan Linear

12

Tantangan ini tetapi dengan spek yang lebih baik.

Spec

Program Anda akan mengambil persamaan linear yang berisi variabel tunggal xdan menghasilkan nilai x.

Input / Parsing

  • Input hanya akan berisi angka, operator, tanda kurung ( ()) x, dan =tanda (ini berarti tidak ada spasi).
  • Parenthesis akan selalu seimbang.
  • Akan selalu ada setidaknya 1 x. Suatu xdapat didahului dengan suatu angka.
  • Semua persamaan pasti memiliki satu hasil.

Sebuah nomor dapat didefinisikan dengan mengikuti langkah-langkah ini. Sejumlah dapat didefinisikan oleh regex: -?(\d+(\.\d+)?|\.\d+).


Jika Anda tidak berbicara regex: Digit didefinisikan sebagai 0-9

  1. Mungkin memiliki -di awal itu menandakan negatif
  2. Maka mungkin ada beberapa digit. Jika tidak ada digit akan ada titik desimal
  3. Jika ada titik desimal, setidaknya satu digit akan mengikutinya

Angka / nilai terbesar akan ditentukan oleh kemampuan bahasa Anda.


Sebuah Operator adalah salah satu dari: +-*/, mereka akan selalu muncul antara angka, dan atau kurung

ini berarti (5)(5)bukan input yang valid demi kesederhanaan.


Parenthesis akan selalu berisi ekspresi yang valid (kombinasi angka dan / atau operator yang valid) di dalamnya. Tanda kurung "Seimbang" didefinisikan karena setiap (akan memiliki penutupan terkait)

Evaluasi

  • Urutan operasi harus diikuti dan prioritasnya adalah (tertinggi ke terendah):
    • Parenthesis (bersarang paling dalam)
    • Perkalian & Divisi
    • Penambahan & Pengurangan
  • Jika dua operator dengan presedensi yang sama terjadi, Anda sebaiknya memilih ke kiri -> kanan

Keluaran

Anda harus menampilkan hasilnya dengan cara tertentu. Jika Anda tidak menampilkan hasil angka saja, jelaskan jawaban Anda bagaimana output itu dihasilkan. Format output Anda harus konsisten. Output mungkin berupa desimal, tetapi akan selalu rasional, ketelitiannya terbatas pada ketepatan bahasa Anda. Hanya jika bahasa Anda tidak mendukung aritmatika floating point, Anda tidak perlu mendukungnya.

Aturan

  • Built-in meremehkan tugas ini diizinkan tetapi , Anda harus menambahkan [uses built-in]dengan jelas ke header jawaban. Ini mengecualikan jawaban Anda dari kemenangan
  • "Built-in meremehkan tugas ini" adalah salah satu dari:
    • Sesuatu yang mengambil persamaan dan mengeluarkan nilai untuk variabel
    • Sesuatu yang sepenuhnya akan menyederhanakan persamaan
    • Menggunakan evalatau fungsi terkait untuk melakukan parsing dalam jumlah yang signifikan. Penggunaan evaldan fungsi terkait tidak diizinkan jika digunakan untuk (dengan modifikasi minimal pada input) menyelesaikan persamaan linear.
    • Jika Anda ragu, tanyakan saja dalam komentar.
  • Built-in yang mem-parsing persamaan diperbolehkan

Contohnya

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

Input tidak valid :

(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
sumber
8
Anda mengatakan bahwa built-in mendiskualifikasi kiriman Anda, tetapi mengklarifikasi ini untuk merujuk hanya pada operasi yang melakukan pemecahan persamaan dan parsing dan sejenisnya. Saya pikir akan lebih jelas untuk menggunakan istilah yang berbeda, karena saya menganggap setiap operasi bernama sebagai built-in.
xnor
Seberapa akurat jawaban itu?
flawr
@MrPublic Program Anda akan mengambil persamaan linear yang berisi variabel tunggal ...
Luis Mendo
Juga, apakah JavaScript evaldianggap meremehkan tantangan? Juga, akankah bentuk new Function(...)penghitungan?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ tergantung untuk apa Anda menggunakannya. Tetapi dengan asumsi Anda menggunakan JavaScript, saya tidak melihat bagaimana hal itu akan meremehkan tantangan jadi yakin
Downgoat

Jawaban:

3

JavaScript ES6, 246 byte

Masih ada beberapa golf yang harus dilakukan, tetapi setidaknya itu solusi!

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}

Beri nama fungsi n=>{n=n.split("=")...untuk menggunakannya.

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

Ini menggunakan pendekatan pivot. (Saya tidak yakin apakah ini yang disebut algoritme, hanya nama yang saya temukan.) Pertama-tama, mengumpulkan arah mana yang akan dicari dari nol (yaitu, ke mana kemiringan dua sisi persamaan akan berpotongan) dan mencari nilainya. Setelah menemukan titik perbedaan minimal, ia pergi ke titik itu dan mengurangi kenaikan pencarian. Ini akhirnya menghasilkan sebagai solusi tepat yang kita butuhkan.

Conor O'Brien
sumber
Saya pikir Anda bisa mencukur sedikit dengan menggunakan sintaks eval + ES6 alih-alih Function baru
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))

Cobalah online!

-13 byte terima kasih kepada @tsh

Tidak Disatukan:

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
}

Penjelasan:

Solusi ini bekerja dengan metode Newton untuk menemukan akar. Kode mengurangi sisi kanan persamaan dari sisi kiri, sehingga ketika f(x)=0, xakan sama dengan nilai yang kita pecahkan. Karena itu, ketika kita menemukan akar dari fungsi baru ini, itu akan menjadi xnilai yang kita inginkan . Kemudian ia menemukan turunan f'(x)dengan menemukan kemiringan antara dua titik pada fungsi. Kemudian, nilai-nilai hanya dimasukkan ke dalam metode Newton yang menyatakan untuk perkiraan akar x, x=x-(f(x)/f'(x))(dalam kode, kita menggunakan 0 sebagai xnilai awal ). Karena ini menemukan akarnya, ia menemukan xnilai kita . Dan karena persamaan dijamin linier, perkiraannya akan tepat.

Logern
sumber
93 bytes
tsh
1

Mathcad, [menggunakan bawaan]

masukkan deskripsi gambar di sini

Mathcad memiliki dua metode bawaan untuk menyelesaikan persamaan tersebut:

  • Pemecah simbolis (menggunakan pemecahan kata kunci)
  • Memecahkan Blok (yang berfungsi dalam mode numerik dan simbolik). Blok Penyelesaian dimulai dengan kata kunci Diberikan, mengikuti serangkaian ekspresi yang menentukan kondisi yang diminati, dan ditutup oleh salah satu kata kunci penyelesaian, seperti Temukan (yang menemukan solusi tepat) atau MinErr (yang meminimalkan kesalahan antara target dan solusi apa saja).

Pemecah simbolis cukup senang dengan y = x dan mengembalikan solusi x = y.

Bagi mereka yang tidak terbiasa dengan Mathcad, gambar di bawah ini diambil langsung dari buku kerja WYSIWYGish Mathcad 15. Mengubah salah satu ekspresi di mana mereka ditulis akan menyebabkan Mathcad mengevaluasi kembali jawabannya dan memperbarui tampilan yang sesuai.

Stuart Bruff
sumber
Karena penasaran, mengapa harus downvotes? Saya dapat memahami bahwa kesederhanaannya mungkin merupakan akar dari itu, tetapi tampaknya pada dasarnya tidak berbeda dari solusi TI Basic, yang hanya menambahkan sejumlah kecil pemrosesan input sebelum memanggil solver built-in dan belum tidak diturunkan.
Stuart Bruff
1
Berapa jumlah byte sebenarnya dari program ini?
Jo King
Downvotes kemungkinan karena solusi Anda sepele - lihat 'Apa itu solusi sepele?' pada meta.
0

Aksioma, 214 byte [menggunakan 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)

Untuk beberapa kesalahan akan mengembalikan% i, untuk jenis kesalahan lainnya fungsi tersebut dihentikan dari sistem, sesuatu yang lain seperti 1-2 tampaknya keluar dari bahasa ... tes:

(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
sumber