Mengevaluasi string ekspresi polinomial

18

Buat fungsi yang mengambil persamaan polinomial, nilai untuk xdan mengembalikan hasil operasi.

Contoh: diberikan 4x^2+2x-5dan x=3keluaran 37. Ini adalah hasil dari4(3)^2+2(3)-5

  • Asumsikan semua polinomial valid
  • Format polinom akan selalu coefficient(variable)^exponent => 4x^2kecuali:
    • Ketika eksponen 1itu akan terjadicoefficient(variable) => 4x
    • Ketika koefisien 1itu akan(variable)^exponent => x^2
  • Polinomial hanya satu variabel
  • Penggunaan perpustakaan eksternal dilarang
  • Koefisien dan input variabel dapat berupa angka positif dan negatif.

Uji kasus

  • ("3x^3-5x^2+2x-10", 5) => 250
  • ("10x^4-5x^3-10x^2+3x+50", 3) => 644
  • ("10x+20", 10) => 120
  • ("-20x^2+20x-50", -8) => -1490
  • ("9", 5) => 9
  • ("8x^2+5", 0) => 5

Memperbarui

  • Format polinom akan selalu coefficient(variable)^exponent => 4x^2kecuali:
    • Ketika eksponen 1itu akan terjadicoefficient(variable) => 4x
    • Ketika koefisien 1itu akan(variable)^exponent => x^2
  • Menghapus aturan eksponen negatif. Kesalahanku. Polinomial yang valid tidak mengandung eksponen negatif
  • Eksponen 0akan adilcoefficient
  • Menambahkan test case untuk input 0

Ini adalah , jadi jawaban tersingkat dalam byte menang.

Luis felipe De jesus Munoz
sumber
3
Seberapa fleksibel format input? Alih-alih 3x^3-5x^2+2x-10bisakah kita input 3*x^3-5*x^2+2*x-10? Atau [3 -5 2 -10]. [3 2 1 0]?
Luis Mendo
1
@Arnauld Ya ...
Luis felipe De jesus Munoz
4
Apa itu "perpustakaan eksternal" dan bagaimana adilnya, dibandingkan dengan bahasa yang "eval" sudah diterapkan sebagai fitur?
Olivier Grégoire
1
Maaf saya belum menggunakan pc saya sejak kemarin. Saya telah memperbarui tantangan dengan saran yang Anda berikan kepada saya. Silakan lihat dan buka kembali jika semuanya baik-baik saja.
Luis felipe De jesus Munoz

Jawaban:

12

JavaScript (ES7), 48 byte

Berdasarkan saran dari @RickHitchcock

Diharapkan Xdalam huruf besar. Mengambil input dalam sintaks currying (p)(X).

p=>X=>eval(p.replace(/[X^]/g,c=>c<{}?'*X':'**'))

Cobalah online!


JavaScript (ES7), 49 byte

Pendekatan yang sama dengan @DeadPossum . Mengambil input dalam sintaks currying (p)(x).

p=>x=>eval(p.split`x`.join`*x`.split`^`.join`**`)

Cobalah online!

Arnauld
sumber
1
Saya pikir Anda dapat menyimpan beberapa byte dengan menggunakan replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**'))
Rick Hitchcock
@RickHitchcock Saya tidak bisa menggunakan referensi fkecuali kecuali sudah termasuk dalam jumlah byte, dengan biaya 2 byte yang seharusnya disimpan. Saya suka metode ini. Mungkin ada cara untuk menyimpan satu atau dua byte dengan cara memperbaikinya.
Arnauld
2
@RickHitchcock Jika kita dapat menggunakan Xhuruf besar, maka kita bisa melakukannya a<{}?'*X':'**', menghemat satu byte. Karena itu pertanyaan saya kepada OP.
Arnauld
1
tidak bisa menangani xsendiri
l4m2
1
@ l4m2 Aturan tantangan telah diperbarui. : / Dulu 1xuntuk x.
Arnauld
8

Python 2 , 54 byte

-2 byte terima kasih kepada Jo King

-5 byte terima kasih kepada Arnauld

lambda p,x:eval(p.replace('^','**').replace('x','*x'))

Cobalah online!

Possum Mati
sumber
8

Python 3 , 53 50 48 byte

sunting : -5 bytes berkat Dennis!

lambda p,x:eval(p.translate({94:"**",120:"*x"}))

Cobalah online!

Digunakan translateuntuk menghindari replacepanggilan chaining ; Versi Python 3 translatekurang canggung dari versi pendahulunya.

etene
sumber
"*(%d)"%xbisa menjadi "*(x)".
Dennis
Terima kasih, saya tidak menemukan acara xdalam evallingkup saya ! Saya akan memperbarui.
etene
1
Sebenarnya, karena xbukan lagi representasi string, "*x"berfungsi juga.
Dennis
Bahkan lebih baik ! Terima kasih lagi.
etene
5

R , 44 byte

function(f,x)eval(parse(t=gsub("x","*x",f)))

Cobalah online!

Cukup mudah dengan R. Ganti nxdengan n*xdan kemudian evalyang parsed tali. xdigunakan karena ini adalah bagaimana kita menamai argumen kedua.

Fungsi eval bahkan bisa digunakan lebih langsung dengan argumen pertama diformat dengan benar, dan argumen formal lainnya ( y, z, dll) dapat dengan mudah ditambahkan:

R , 20 byte (tidak bersaing)

function(f,x)eval(f)

Cobalah online!

JayCe
sumber
4

Japt 2.0, 13 byte

OvUd^'*²'x"*V

Cobalah .

Penjelasan:

OvUd^'*²'x"*V
              U = Implicit first input
              V = Implicit second input

Ov            Eval:
  Ud            In U, replace:
    ^             "^" with:
     '*²            "**"
        'x        "x" with:
          "*V       "*V"
Oliver
sumber
3

JavaScript (Node.js) , 113 108 byte

_=>x=>_.match(/-?(?:[x\d]+|\^?)+/g).reduce((a,b)=>b.split`x`[0]*(~b.indexOf`x`?x**(b.split`^`[1]||1):1)+a,0)

Cobalah online!

Terima kasih kepada @Arnauld


Karena solusi JS terbaik sejauh ini oleh @Arnauld (49 bytes) telah diposting dan digunakan eval, saya memutuskan untuk menggunakan Regex dan menguranginya.

Cukup panjang dibandingkan dengan miliknya.

Penjelasan:

A =>                            // lambda function accepting argument 1 
    x =>                        // argument number 2 (currying syntax used)
        A.match(                // this matches all instance of what comes next 
                                // and converts to array
       /[-]?(?:[x\d]+|\^?)+/g)  // regexp for -ve sign , variable number and ^ sign 
            .reduce((a, b) =>   // reduce the array to single (take 2 params a,b)
                b.split `x`     // split b at instances of `x` 
                        [0]     // and select the first instance 
                * (b.indexOf`x` // multiply that by value of index of x in b 
                    > 0 ?       // if it is greater than 0 then 
                x **            // multiplication will be with x raised to power
               (l = b.split `^` // set variable split b at every `x` 
                   [1]||1       // choose first index otherwise set to one
                )               // this is what x is raised to the power 
                : 1)            // in the case x is not present multiply by 1
                + a,            //  add value of `a` to that value 
        0)                      // in case no reduce is possible set value to 0

Muhammad Salman
sumber
Ini saat ini gagal pada kasus uji terakhir (harus 0,25). Anda dapat menyimpan beberapa byte dengan menggunakan -alih- alih [-], ~b.indexOf`x` alih-alih b.indexOf`x`>0dan menghapus l=yang tidak digunakan. (Tapi ini tidak memperbaiki bug.)
Arnauld
@Arnauld: Terima kasih. Tidak tahu mengapa ia melakukan itu, akan melihat apa masalahnya
Muhammad Salman
Nah, masalahnya adalah bahwa perpecahan regex Anda 1x^-2pada -.
Arnauld
3

05AB1E , 16 19 byte

„*(I')J'xs:'^„**:.E

+3 byte sebagai perbaikan bug untuk input negatif x.

.E ( Jalankan sebagai kode Batch ) telah diganti dengan Jalankan sebagai Pythoneval dalam komit terbaru dari @Adnan , tetapi versi ini belum TIO. @ Mr.Xcoder mengujinya pada 05AB1E lokal (versi terbaru) untuk memverifikasi itu berfungsi.
Lihat versi ini tanpa .Emelihat bagaimana itu mengubah string ekspresi.

Penjelasan:

„*I')J'xs:    # Replace all "x" with "*(n)" (where `n` is the input-integer)
              #  i.e. 5 and 3x^3-5x^2+2x-10 → 3*(5)^3-5*(5)^2-2*(5)-10
'^„**:        # Replace all "^" with "**"
              #  i.e. 3*(5)^3-5*(5)^2-2*(5)-10 → 3*(5)**3-5*(5)**2-2*(5)-10
.E            # Evaluate as Python-eval
              #  i.e. 3*(5)**3-5*(5)**2-2*(5)-10 → 250

Alternatif 25 28 byte program yang bekerja pada versi TIO saat ini:

„*(I')J'xs:'^„**:“…¢(“s')J.e

Cobalah online.

Penjelasan:

„*(I')J'xs:'^„**:    # Same as explained above
“…¢(“                # Literal string "print("
     s               # Swap both
      ')             # Literal character ")"
        J            # Join everything together
                     #  i.e. 3*(5)**3-5*(5)**2-2*(5)-10 → print(3*(5)**3-5*(5)**2-2*(5)-10)
.e                   # Run as Python code
                     #  i.e. print(3*(5)**3-5*(5)**2-2*(5)-10) → 250

“…¢(“adalah string print(, karena:

  • dan memulai dan mengakhiri string yang dikompresi
  • …¢sama dengan 0426karena melihat indeks dalam file info.txt , di mana memiliki indeks 4, dan ¢memiliki indeks 26.
  • Indeks 0426ini kemudian digunakan dalam file kamus , di mana baris 427 (indeks 426) adalah kata yang diambilnya, yang printdalam hal ini.
  • Tidak (memiliki indeks dalam file info.txt, jadi ia ditafsirkan apa adanya.
Kevin Cruijssen
sumber
2

JavaScript (Node.js) , 143 byte

Saya tahu ada jawaban yang lebih baik tetapi saya ingin melakukannya tanpa menggunakan eval

(_,x)=>_.match(/[+-]?(?:[a-z0-9.]+|\^-?)+/gi).reduce((a,b)=>~~(b.split('x')[0])*(b.indexOf('x')>0?Math.pow(x,(l=(b.split('^')[1]))?l:1):1)+a,0)

Cobalah online!

Luis felipe De jesus Munoz
sumber
Regex Anda tidak perlu [a-z0-9.]melakukannya? Satu-satunya huruf yang dapat muncul adalah x. Adakah alasannya .? Anda tidak perlu menangani koefisien atau eksponen non-integer.
Peter Cordes
2

Physica , 35 byte

->e;x:Eval@Replace[e;"x";f"*({x})"]

Cobalah online!

Tuan Xcoder
sumber
2

Jelly , 21 byte

ṣ”^j⁾**ṣ”xjØ(j”*;Ʋ}ŒV

Cobalah online!

Erik the Outgolfer
sumber
Karena prioritas operator, ini tidak berhasil ("-20x^2+20x-50", -8).
Dennis
@ Dennis Disesuaikan.
Erik the Outgolfer
2

Java 8, 150 149 148 byte

n->s->new javax.script.ScriptEngineManager().getEngineByName("JS").eval(s.replace("x","*"+n).replaceAll((s="(\\-?\\d+)")+"\\^"+s,"Math.pow($1,$2)"))

Tidak yakin apakah mungkin memiliki fungsi lambda kari yang melempar Pengecualian. Jika ya, 1 byte dapat disimpan dengan mengubah (s,n)->ke n->s->. -1 byte terima kasih kepada @ OlivierGrégoire karena menunjukkan kepada saya bagaimana melakukan ini.

Cobalah online.

Penjelasan:

n->s->     // Method with integer and String parameters and Object return-type
  new javax.script.ScriptEngineManager().getEngineByName("JS")
            //  Use a JavaScript engine
   .eval(s  //  And eval the input
      .replace("x","*"+n)
            //   After all 'x' has been replaced with '*n'
            //   (where `n` is the input-integer)
      .replaceAll((s="(\\-?\\d+)")+"\\^"+s,"Math.pow($1,$2)"))
            //   And all `A^B` have have been replaced with `Math.pow(A,B)`
            //   (where both `A` and `B` are integers)

Sayangnya eval JavaScript tidak mendukung **, jadi saya harus menggunakan lagi ganti untuk mengubahnya menjadi Math.powsebaliknya ..

Kevin Cruijssen
sumber
JavaScript mendukung **(ES7 +), mengapa ini tidak mendukungnya?
Muhammad Salman
Juga tidak ada eval di java. Itu tidak benar?
Muhammad Salman
@MuhammadSalman Tidak, Java tidak punya eval. Dan saya pikir ini built-in JavaScript-eval saya dapat menggunakan dengan ScriptEngineManagerbelum diperbarui di Java JDK selama bertahun-tahun, sehingga tidak mendukung ES7+..
Kevin Cruijssen
Man, java sucks, no eval why? Oke mengapa belum diperbarui?
Muhammad Salman
@MuhammadSalman Saya tidak tahu .. Anda harus bertanya kepada pencipta Jawa pertanyaan itu. ;)
Kevin Cruijssen
2

TI-Basic, 6 byte

Prompt X:expr(Ans

Ekspresi diambil sebagai argumen dan X dimasukkan selama runtime. Atau 8 byte tanpa expr:

Prompt X,u:u

Di sini kedua argumen dimasukkan saat runtime.

Timtech
sumber
2

Oktaf , 47 38 37 byte

Menyimpan banyak byte dengan mengambil input kedua sebagai string, bukan angka.

@(x,c)eval(strrep(x,'x',['*(',c,41]))

Cobalah online!

Penjelasan:

Cukup lurus ke depan: Ganti xdengan (c), di mana cinput kedua, dan evaluasi. Parese diperlukan karena dalam Oktaf -8^2 == -64.

Stewie Griffin
sumber
1

Ruby , 43 byte

->s,x{eval s.gsub /[x^]/,?x=>"*x",?^=>"**"}

Cobalah online!

GB
sumber
Pendekatan yang bagus dengan penggantian hash, tetapi dua gsubs lurus bahkan lebih pendek
Kirill L.
1

Perl 5 -pl , 35 byte

s/\^/**/g;$q=<>;s/x/*($q)/g;$_=eval

Cobalah online!

Xcali
sumber
1

Ruby , 43 41 byte

->p,x{eval p.gsub('^','**').gsub'x','*x'}

Cobalah online!

Disimpan dua byte berkat @ Mr.Xcoder


Karena belum ada jawaban Ruby belum saya tambahkan. Nvm ada satu yang menggunakan pendekatan yang berbeda

Penjelasan:

->p,x{                    # lambda function that takes two arguments p and x
    eval(                 # eval 
        p.gsub(           # replace all instance of 
            '^' , '**'    # `^` with `**` (use for raised to power of)
        )                 # end gsub
        .gsub(            # start another replace all
            'x' , '*x'    # replace all instances of `x` with `*x`
        )                 # end the replace function
    )                     # end eval function
}                         # end lambda function
Muhammad Salman
sumber
1

Excel, 36 + 2 byte, Tidak bersaing

Mengevaluasi bidang Teks sebagai rumus tidak lurus di Excel. Ada yang disembunyikan=EVALUATE() fungsi , yang bisa dipanggil dengan mendefinisikan Nama.

Di Excel 2007, Rumus> Tetapkan Nama. Tentukan Nama yang dipanggil E, dengan Mengacu pada:

=EVALUATE(SUBSTITUTE(A1,"x","*"&B1))

Kemudian, dengan masukan Formula di A1, xnilai B1, memasuki =Edi C1pengembalian hasil yang diharapkan.

Wernisch
sumber