Chuyển đổi từ ký hiệu Infix sang ký hiệu tiền tố


12

Cho một biểu thức số học, có thể bao gồm dấu ngoặc đơn ( ()), số mũ ( ^), phép chia ( /) và phép nhân ( *), phép cộng ( +) và phép trừ ( -) (theo thứ tự hoạt động đó), chẳng hạn như

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

xuất biểu thức tương tự trong ký hiệu tiền tố.

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

Không gian là tùy chọn trong đầu vào cũng như đầu ra. Bạn có thể giả sử rằng tất cả các toán tử là liên kết trái và tất cả các số trong biểu thức là số nguyên một chữ số (nghĩa là [0-9]).

Đây là một thử thách golf mã, vì vậy giải pháp ngắn nhất sẽ thắng.


1
Là + và - cùng mức ưu tiên, hoặc là + cao hơn -? Tức là 3+4-5+6 = (((3+4)-5)+6)hay ((3+4)-(5+6))?
Keith Randall

Ngoài ra, bạn còn lại phân chia trong danh sách hoạt động của bạn.
PhiNotPi

là dấu ngoặc đơn tùy chọn trong đầu ra?
Ali1S 232

@KeithRandall */có cùng quyền ưu tiên, cũng như +amd -.
Peter Olson

@Gajet Không, họ không.
Peter Olson

Câu trả lời:


13

Hồng ngọc 1.9 - 134

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

Khá ác, nhưng nó hoạt động:

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

3

Python, 222 ký tự

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

Tương tự như Ruby, ngoại trừ Python không cho phép bạn xác định lại các op toàn cầu, chỉ các op của một lớp.


2

Perl 6 (146 | 150)

Cách dễ nhất để làm điều này là chỉ trao đổi các chương trình con triển khai các toán tử cho các toán tử mới.

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

Lượng byte tối thiểu tuyệt đối để thực hiện theo cách này là:

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 byte, mặc dù nó có ý nghĩa hơn để đếm đồ thị trong Perl 6.

Điều này giả định rằng " đầu ra cùng một biểu thức trong ký hiệu tiền tố " chỉ có thể đề cập đến kết quả của biểu thức, không nhất thiết là đầu ra của chương trình.

Bạn sẽ phải thêm say vào trước biểu thức để có được chương trình in nó thành STDOUT. (150 byte)


0

Unix TMG , 189 byte

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;

Giải pháp gần như trực tiếp từ hướng dẫn sử dụng cho ngôn ngữ, chỉ với việc chơi golf cơ bản.

Mở rộng:

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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.