แปลงจาก Infix Notation เป็น Prefix Notation


12

รับนิพจน์ทางคณิตศาสตร์ซึ่งอาจรวมถึงวงเล็บ ( ()), เลขชี้กำลัง ( ^), การหาร ( /) และการคูณ ( *), การเพิ่ม ( +) และการลบ ( -) (ตามลำดับการดำเนินการ) เช่น

a ^ (2 / 3) * 9 * 3 - 4 * 6

เอาท์พุทนิพจน์เดียวกันในสัญลักษณ์คำนำหน้า

(- (* (* (^ a (/ 2 3)) 9) 3) (* 4 6))

ช่องว่างเป็นตัวเลือกในการป้อนข้อมูลเช่นเดียวกับการส่งออก คุณอาจสันนิษฐานว่าผู้ประกอบการทั้งหมดมีความสัมพันธ์ทางด้านซ้ายและตัวเลขทั้งหมดในนิพจน์นั้นเป็นเลขจำนวนเต็มหลักเดียว (เช่น[0-9])

นี่คือความท้าทายของรหัสกอล์ฟดังนั้นทางออกที่สั้นที่สุดชนะ


1
+ และ - มีลำดับความสำคัญเท่ากันหรือ + สูงกว่า - หรือไม่ กล่าวคือเป็น3+4-5+6 = (((3+4)-5)+6)หรือ((3+4)-(5+6))?
Keith Randall

นอกจากนี้คุณยังไม่ได้แบ่งส่วนในรายการการดำเนินการของคุณ
PhiNotPi

วงเล็บเป็นตัวเลือกในการส่งออก?
Ali1S232

@KeithRandall *และ/มีความสำคัญเหมือนกันเช่นเดียวกับเอเอ็มดี+ -
ปีเตอร์โอลสัน

@Gajet ไม่พวกเขาไม่ได้
Peter Olson

คำตอบ:


13

ทับทิม 1.9 - 134

%w[** / * + -].map{|o|String.send(:define_method,o){|n|"(#{o=='**'??^:o} #{self} #{n})"}}
puts eval gets.gsub(/\w/,'?\0').gsub ?^,'**'

ชั่วร้ายสวย แต่ใช้งานได้:

$ echo 'a ^ (2 / 3) * 9 * 3 - 4 * 6' | ruby sol.rb
(- (* (* (^ a (/ 2 3)) 9) 3) (* 4 6))

3

Python 222 ตัวอักษร

class A:
 def __init__(s,x):s.v=x
for x in('pow^','mul*','div/','add+','sub-'):exec('A.__'+x[:3]+'__=lambda s,y:A("('+x[3]+'"+s.v+y.v+")")')
import re
print eval(re.sub('(\\w)','A("\\1")',raw_input().replace('^','**'))).v

คล้ายกับ Ruby one ยกเว้น Python ไม่อนุญาตให้คุณกำหนด global ops ใหม่เฉพาะ ops ของคลาส


2

Perl 6 (146 | 150)

วิธีที่ง่ายที่สุดในการทำเช่นนี้คือเพียงสลับรูทีนย่อยที่ใช้ตัวดำเนินการสำหรับตัวใหม่

sub infix:«+»   ($a,$b) { "(+ $a $b)" }
sub infix:«-»   ($a,$b) { "(- $a $b)" }
sub infix:«*»   ($a,$b) { "(* $a $b)" }
sub infix:['/'] ($a,$b) { "(/ $a $b)" } # stupid highlighter
sub infix:«**»  ($a,$b) { "(^ $a $b)" }

# currently there seems to be a bug that
# prevents this from modifying the parser correctly
# probably because there is already a different operator with this name
# which has nothing to do with exponentiation
my &infix:«^» := &[**];

say 'a' ** (2 / 3) * 9 * 3 - 4 * 6;
# (- (* (* (^ a (/ 2 3)) 9) 3) (* 4 6))␤

จำนวนไบต์ขั้นต่ำที่แน่นอนสำหรับการทำเช่นนี้คือ:

sub infix:<+>{"(+ $^a $^b)"}␤  #   29
sub infix:<->{"(- $^a $^b)"}␤  # + 29
sub infix:<*>{"(* $^a $^b)"}␤  # + 29
sub infix:<**>{"(^ $^a $^b)"}␤ # + 30
sub infix:</>{"(/ $^a $^b)"}␤  # + 29

146 ไบต์แม้ว่ามันจะเหมาะสมกว่าที่จะนับกราฟใน Perl 6

สิ่งนี้อนุมานว่า " เอาท์พุทนิพจน์เหมือนกันในรูปแบบของคำนำหน้า " สามารถอ้างถึงผลลัพธ์ของนิพจน์ได้โดยไม่จำเป็นต้องเป็นเอาต์พุตของโปรแกรม

คุณจะต้องเพิ่มsay ด้านหน้าของนิพจน์เพื่อให้โปรแกรมพิมพ์ลงใน STDOUT (150 ไบต์)


0

Unix TMG , 189 ไบต์

p:ignore(<< >>)parse(e);e:q(t,a);t:q(x,m);x:q(r,h);q:proc(x,y)x k:y/d x={<(>2 3 1<)>}b\k;r:o(!<<+-*/^()>>)|<(>e<)>;a:o(<<+->>);m:o(<<*/>>);h:o(<<^>>);o:proc(n)smark any(n)scopy;d:;b:bundle;

การแก้ปัญหาเกือบจะตรงจากคู่มือสำหรับภาษาด้วยการตีกอล์ฟพื้นฐานเท่านั้น

ขยาย:

prog:  ignore(<< >>) parse(expr);
expr:  q(term, addop);
term:  q(fact, mulop);
fact:  q(prim, expop);
q:     proc(x,y) x k: y/done x ={ <(> 2 3 1 <)> } b\k;
prim:  op(!<<+-*/^()>>) | <(> expr <)>;
addop: op(<<+->>);
mulop: op(<<*/>>);
expop: op(<<^>>);
op:    proc(n) smark any(n) scopy;
done:  ;
b:     bundle;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.