ประเมินสตริงการแสดงออกพหุนาม


18

สร้างฟังก์ชั่นที่รับสมการพหุนามซึ่งเป็นค่าxและส่งคืนผลลัพธ์ของการดำเนินการ

ตัวอย่าง: ได้รับ4x^2+2x-5และการส่งออกx=3 37นี่คือผลลัพธ์ของ4(3)^2+2(3)-5

  • สมมติว่าชื่อพหุนามทั้งหมดถูกต้อง
  • รูปแบบพหุนามจะถูกcoefficient(variable)^exponent => 4x^2ยกเว้นเสมอ:
    • เมื่อเลขชี้กำลัง1มันจะเป็นcoefficient(variable) => 4x
    • เมื่อค่าสัมประสิทธิ์1มันจะเป็น(variable)^exponent => x^2
  • พหุนามเป็นตัวแปรเดียวเท่านั้น
  • ห้ามใช้ไลบรารีภายนอก
  • สัมประสิทธิ์และตัวแปรที่ป้อนสามารถเป็นตัวเลขบวกและลบได้

กรณีทดสอบ

  • ("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

ปรับปรุง

  • รูปแบบพหุนามจะถูกcoefficient(variable)^exponent => 4x^2ยกเว้นเสมอ:
    • เมื่อเลขชี้กำลัง1มันจะเป็นcoefficient(variable) => 4x
    • เมื่อค่าสัมประสิทธิ์1มันจะเป็น(variable)^exponent => x^2
  • ลบกฎของเลขชี้กำลังเป็นค่าลบ ความผิดพลาดของฉัน. พหุนามที่ถูกต้องไม่มีเลขชี้กำลังเป็นลบ
  • เลขชี้กำลังของ0จะเป็นเพียงแค่coefficient
  • เพิ่มกรณีทดสอบสำหรับ input 0

นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ


3
รูปแบบอินพุตมีความยืดหยุ่นเพียงใด แทนการ3x^3-5x^2+2x-10ป้อนข้อมูลที่เราสามารถ3*x^3-5*x^2+2*x-10? หรือ[3 -5 2 -10]. [3 2 1 0] ?
Luis Mendo

1
@Arnauld ใช่ ...
Luis felipe De jesus Munoz

4
"ห้องสมุดภายนอก" คืออะไรและมีความยุติธรรมอย่างไรเมื่อเทียบกับภาษาที่มีการนำ "eval" มาใช้เป็นคุณสมบัติแล้ว
Olivier Grégoire

1
ฉันขอโทษฉันไม่ได้ใช้พีซีตั้งแต่เมื่อวาน ฉันได้อัปเดตการท้าทายพร้อมคำแนะนำที่คุณให้ไว้ โปรดดูและเปิดใหม่หากทุกอย่างโอเค
Luis felipe De jesus Munoz

คำตอบ:


12

JavaScript (ES7), 48 ไบต์

ตามข้อเสนอแนะจาก @RickHitchcock

คาดว่าจะเป็นXตัวพิมพ์ใหญ่ (p)(X)จะเข้าในไวยากรณ์ currying

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

ลองออนไลน์!


JavaScript (ES7), 49 ไบต์

วิธีการเช่นเดียวกับ@DeadPossum (p)(x)จะเข้าในไวยากรณ์ currying

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

ลองออนไลน์!


1
ฉันคิดว่าคุณสามารถบันทึกสองสามไบต์โดยใช้replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**'))
Rick Hitchcock

@RickHitchcock ฉันไม่สามารถใช้การอ้างอิงถึงได้fเว้นแต่จะรวมอยู่ในจำนวนไบต์ด้วยค่าใช้จ่าย 2 ไบต์ที่ควรจะได้รับการบันทึก ฉันชอบวิธีนี้แม้ว่า อาจมีวิธีการบันทึกหนึ่งหรือสองไบต์
Arnauld

2
@ RickHitchcock ถ้าเราสามารถใช้Xตัวพิมพ์ใหญ่ได้เราสามารถทำได้a<{}?'*X':'**'โดยการบันทึกไบต์ ดังนั้นคำถามของฉันไปที่ OP
Arnauld

1
ไม่สามารถจัดการxคนเดียว
l4m2

1
@ l4m2 กฎการท้าทายถูกอัปเดตแล้ว : / จะใช้เป็นที่สำหรับ1x x
Arnauld


8

Python 3 , 53 50 48 ไบต์

แก้ไข : -5 ไบต์ขอบคุณ Dennis!

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

ลองออนไลน์!

ใช้translateเพื่อหลีกเลี่ยงการโยงreplaceสาย เวอร์ชันของ Python 3 translateมีความเชื่องช้าน้อยกว่ารุ่นก่อน


"*(%d)"%x"*(x)"จะกลายเป็น
Dennis

ขอบคุณฉันไม่คิดว่าเหตุการณ์xอยู่ในevalขอบเขตของฉัน! ฉันจะอัปเดต
etene

1
ที่จริงแล้วเนื่องจากxไม่มีการแสดงสตริงอีกต่อไปจึงใช้"*x"งานได้ดี
Dennis

ดียิ่งขึ้น! ขอบคุณอีกครั้ง.
etene

5

R , 44 ไบต์

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

ลองออนไลน์!

ตรงไปตรงมาเป็นธรรมกับอาร์แทนที่nxด้วยn*xแล้วd สตริง ถูกใช้เช่นนี้เป็นวิธีที่เราตั้งชื่ออาร์กิวเมนต์ที่สองevalparsex

ฟังก์ชั่น EVAL ยังสามารถนำมาใช้โดยตรงกับอาร์กิวเมนต์แรกในรูปแบบที่ถูกต้องและข้อโต้แย้งอย่างเป็นทางการอื่น ๆ ( y, zฯลฯ ) อาจจะเพิ่มได้อย่างง่ายดาย:

R , 20 ไบต์ (ไม่ใช่การแข่งขัน)

function(f,x)eval(f)

ลองออนไลน์!




3

JavaScript (Node.js) , 113 108 ไบต์

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

ลองออนไลน์!

ขอบคุณ @Arnauld


เนื่องจากวิธีการแก้ปัญหา JS ที่ดีที่สุดจนถึงตอนนี้ @Arnauld (49 bytes) ได้ถูกโพสต์ไปแล้วและมันใช้evalฉันตัดสินใจใช้ Regex และลดแทน

ค่อนข้างยาวเมื่อเทียบกับเขา

คำอธิบาย:

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


ปัจจุบันนี้ล้มเหลวในกรณีทดสอบล่าสุด (ควรเป็น 0.25) คุณสามารถบันทึกไม่กี่ไบต์โดยใช้-แทน[-], ~b.indexOf`x` แทนb.indexOf`x`>0และลบl=ที่ไม่ได้ใช้ (แต่นี่ไม่ได้แก้ไขข้อผิดพลาด)
Arnauld

@Annauld: ขอบคุณ ไม่รู้เลยว่าทำไมมันถึงเป็นเช่นนั้นจะเห็นว่าปัญหาคืออะไร
Muhammad Salman

ดีปัญหาคือแยก regex ของคุณบน1x^-2 -
Arnauld

3

05AB1E , 16 19 ไบต์

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

3 xไบต์เป็นข้อผิดพลาดแก้ไขสำหรับการป้อนข้อมูลเชิงลบ

.E( Run as Batch code ) ถูกแทนที่ด้วยRun as Pythonevalในการกระทำล่าสุดของ@Adnanแต่เวอร์ชันนี้ยังไม่เปิดใช้ TIO @ Mr.Xcoderทดสอบบนเครื่องท้องถิ่นของเขา (เวอร์ชั่นล่าสุด) 05AB1E เพื่อตรวจสอบว่ามันใช้งานได้
ดูรุ่นนี้โดยไม่ต้อง.Eดูว่ามันแปลงสตริงการแสดงออก

คำอธิบาย:

„*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

โปรแกรมทางเลือก25 28 ไบต์ที่ทำงานกับเวอร์ชันปัจจุบันของ TIO:

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

ลองออนไลน์

คำอธิบาย:

„*(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

“…¢(“เป็นสตริงprint(เพราะ:

  • และเริ่มและสิ้นสุดสตริงที่บีบอัด
  • …¢เท่ากับ0426เพราะดูดัชนีในไฟล์ info.txtโดยที่มีดัชนี 4 และ¢มีดัชนี 26
  • ดัชนีนี้0426จะถูกใช้ในไฟล์พจนานุกรมโดยที่บรรทัดที่ 427 (ดัชนี 426) คือคำที่เรียกซึ่งprintในกรณีนี้
  • (ไม่ได้มีดัชนีในแฟ้ม info.txt จึงตีความตามที่เป็นอยู่

2

JavaScript (Node.js) , 143 ไบต์

ฉันรู้ว่ามีคำตอบที่ดีกว่า แต่ฉันต้องการทำโดยไม่ใช้ 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)

ลองออนไลน์!


regex ของคุณไม่ต้องการ[a-z0-9.]หรือไม่ xตัวอักษรตัวเดียวที่สามารถปรากฏเป็น ทำไม.? คุณไม่จำเป็นต้องจัดการค่าสัมประสิทธิ์หรือเลขชี้กำลังที่ไม่ใช่จำนวนเต็ม
Peter Cordes



2

Java 8, 150 149 148 ไบต์

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

ไม่แน่ใจว่าเป็นไปได้หรือไม่ที่จะมีฟังก์ชั่นแลมบ์ดาที่ทำให้เกิดข้อยกเว้น ถ้าเป็นเช่นนั้น 1 ไบต์จะสามารถบันทึกการเปลี่ยนแปลง(s,n)->เป็นn->s->ไป-1 ไบต์ขอบคุณ@ OlivierGrégoireที่แสดงให้ฉันเห็นถึงวิธีการทำ

ลองออนไลน์

คำอธิบาย:

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)

น่าเสียดายที่ JavaScript Eval ไม่รองรับ**ดังนั้นฉันต้องใช้การแทนที่ที่นานกว่าเพื่อแปลงเป็นMath.powแทน ..


JavaScript รองรับ**(ES7 +) ทำไมถึงไม่รองรับ
มูฮัมหมัดซาลมาน

นอกจากนี้ยังไม่มี eval ใน java มันไม่ถูกต้องใช่ไหม
มูฮัมหมัดซาลมาน

@MuhammadSalman Nope, Java evalไม่มี และฉันคิดว่านี่ builtin JavaScript-EVAL ฉันสามารถใช้กับScriptEngineManagerยังไม่ได้รับการปรับปรุงใน Java JDK สำหรับปีดังนั้นมันไม่สนับสนุนES7+..
เควิน Cruijssen

ผู้ชาย, จาวาดูด, ไม่มีเหตุผลทำไม? โอเคทำไมมันไม่ได้รับการอัพเดต?
มูฮัมหมัดซาลมาน

@MuhammadSalman ฉันไม่ชอบ .. คุณจะต้องถามผู้สร้างของ Java คำถามนั้น ;)
Kevin Cruijssen

2

TI-Basic, 6 ไบต์

Prompt X:expr(Ans

นิพจน์ถูกนำมาเป็นอาร์กิวเมนต์และ X ถูกป้อนระหว่างรันไทม์ อีก 8 ไบต์ที่ไม่มีexpr:

Prompt X,u:u

อาร์กิวเมนต์ทั้งสองนี้ถูกป้อนที่รันไทม์


2

ระดับแปดเสียง , 47 38 37 bytes

บันทึกจำนวนมากไบต์โดยการป้อนข้อมูลที่สองเป็นสตริงแทนตัวเลข

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

ลองออนไลน์!

คำอธิบาย:

ตรงไปข้างหน้าอย่างเป็นธรรม: แทนที่xด้วยโดย(c)ที่cเป็นอินพุตที่สองและประเมิน paretheses เพราะความจำเป็นใน -8^2 == -64Octave




1

ทับทิม , 43 41 ไบต์

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

ลองออนไลน์!

บันทึกสองไบต์ด้วย @ Mr.Xcoder


เนื่องจากยังไม่มีคำตอบทับทิมฉันจึงเพิ่มคำตอบลงไป Nvm มีอีกวิธีหนึ่งที่ใช้วิธีการที่แตกต่างกัน

คำอธิบาย:

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


1

Excel, 36 + 2 ไบต์, ไม่มีการแข่งขัน

การประเมินเขตข้อมูลข้อความเป็นสูตรไม่ได้ส่งต่อใน Excel มี=EVALUATE()ฟังก์ชั่นที่ซ่อนอยู่ซึ่งสามารถเรียกได้โดยการกำหนดชื่อ

ใน Excel 2007 สูตร> กำหนดชื่อ กำหนดชื่อที่ถูกเรียกEโดยอ้างถึง:

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

จากนั้นมีการป้อนข้อมูลในสูตรA1, xค่าในการB1เข้ามา=EในC1ผลตอบแทนที่คาดว่าจะได้ผล


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.