접두사 표기법에서 접두사 표기법으로 변환


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 */같은 수행의 경우 우선 순위가 동일 +AMD -.
피터 올슨

@Gajet 아니요, 그렇지 않습니다.
피터 올슨

답변:


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

파이썬, 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

루비와 비슷하지만 파이썬을 사용하면 전역 작전을 재정의 할 수 없으며 클래스의 작전 만 재정의 할 수 있습니다.


2

펄 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

유닉스 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.