괄호 안에 붙은 접두사


16

Quylthulg 는 Chris Pressey가 panfix 라고 부르는 것을 사용하여 접두사 표기법의 문제를 해결하려고 시도하는 언어입니다 .

postfix와 같이 panfix는 기본 연산자 우선 순위를 무시하기 위해 괄호와 같은 비전 개념을 배치 할 필요가 없습니다. 동시에 panfix를 사용하면 용어를 접두사와 같은 순서와 방식으로 지정할 수 있습니다.


접두사 또는 접미사의 모호함과 함께 접두사 표기법의 편의성을 어떻게 얻습니까? 물론 세 가지를 모두 사용하십시오!

=y=+*3*x*+1+=

더 공식적으로하자 +운영자, 그리고 ab표현합니다. 그런 다음 (a+b)유효한 (괄호로 묶은) 접두어 표현식입니다. 해당 표현식의 panfix 표현은입니다 +a+b+. 여기서 juxtaposition은 연결을 나타냅니다.

목표는 panfix 문자열을 가져 와서 완전히 괄호로 묶은 infix로 변환하는 것입니다.

(y=((3*x)+1))

간단하게하기 위해 다음과 같이 변경합니다.

  • 운영자는 두 개의 고유 한 문자 (당신이 중 하나를 선택할 수 있지만 여기에 내가 사용합니다 구성 될 수 *+).
  • 다른 고유 문자로 구성된 하나의 리터럴 만 있습니다 (여러 가지 중에서 선택할 수 있지만 여기서는을 사용합니다 _).
  • 입력은 올바른 형식의 팬픽 스 표현입니다.

들어 복잡성 , 우리는 다음과 같이 변경을 할 수 있습니다 :

  • 연산자는 문자가 아닌 의 문자 로 구성 될 수 있습니다 .

문자열의 나머지 부분을 보지 않고 주어진 연산자 문자열의 하위 문자열이 어떻게 분할되는지를 결정할 수 없기 때문에 도전이 더 까다로워집니다.

다음은 @ user202729가 제공 한 챌린지에 대한 참조 구현 입니다.

테스트 사례

format: input -> output
+*+_*+_*+++_+*+_*+_*+++ -> ((_*+_)+(_+(_*+_)))
**++*+***++_+_++_+*++*+***_*++*+*****_**_*_*** -> ((((_+_)+_)*++*+***_)*(_*(_*_)))
***_**_***_* -> ((_**_)*_)
+_+_+ -> (_+_)
*+*+++**+***+++++_*+*+++**+***+++++_*+*+++**+***+++++ -> (_*+*+++**+***+++++_)
*++++*+*_*_*+*+++****+_++****+_++****++*+*+++_*+++ -> (((_*_)+*+(_++****+_))*+++_)
+**+_*+_*+*_*+*_*+*_+*_+**+ -> (((_*+_)*_)+(_*(_+*_)))
+**+++++_+++++_+++++*_*+*+_++++++_+++++_+++++++* -> (((_+++++_)*_)+*(_+(_+++++_)))
+*+*+_+*+_+*+*_*+*_*+*+_+*+_+*+*+ -> (((_+*+_)*_)+(_*(_+*+_)))
**_**_**_*_****_* -> ((_*(_*(_*_)))*_)

이 프로그램 을 사용 하여이 과제에 대한 문자열을 생성했습니다 (panfix로 변환하는 것은 쉽지 않지만 반전은 아닙니다)




6
권장 테스트 사례 : **_**_**_*_****_*. 내가 테스트 한 답변이 모두 실패했습니다.
Nitrodon

1
출력에 여분의 공간이 (_ + _)있습니까?
Ton Hospel

2
@TonHospel 물론입니다.
Esolanging Fruit

답변:


6

프롤로그 (SWI) , 194163 바이트

이 팁 을 사용하여 무려 31 바이트를 0 에서 저장했습니다 !

[C|T]/O/R:-C\=x,(T/P/R,concat(C,P,O);O=C,R=T).
[x|R]-x-R.
L-X-R:-L/O/A,A-Y-B,B/O/C,C-Z-D,D/O/R,atomics_to_string(['(',Y,O,Z,')'],X).
X^P:-string_chars(X,L),L-P-[].

연산자 ^는 왼쪽 인수에 팬픽 스 표현식이 포함 된 문자열을 가져오고 오른쪽 인수를 해당 괄호 안에있는 표현식이 포함 된 문자열로 설정합니다. x대신 리터럴로 사용합니다 _.

온라인으로 사용해보십시오!

설명

Prolog는 선언적 언어이므로, 우리는 단지 panfix와 괄호로 묶은 표현 사이의 관계를 설명해야합니다.

설명은이 약간 ungolfed 버전을 사용합니다.

oper([C|T],O,R) :- C\=x, oper(T,P,R), concat(C,P,O).
oper([C|T],C,T).

expr([x|R],x,R).
expr(L,X,R) :- oper(L,O,A), expr(A,Y,B), oper(B,O,C), expr(C,Z,D), oper(D,O,R),
               atomics_to_string(['(',Y,O,Z,')'],X).

parenthesize(X,P) :- string_chars(X,L), expr(L,P,[]).

우리의 주요 프로덕션은 parenthesize, 팬픽 스 표현식 X을 문자열로 취하고 해당 괄호로 묶은 접두사 표현식 을 문자열로 보냅니다 P. 그것은 사용하는 string_chars문자 목록에 입력 된 문자열로 변환 한 후 단순히로 전달합니다 expr.

expr문자 목록을 가져 와서 L찾은 첫 번째 팬픽 스 표현식을 구문 분석 L하고 괄호로 묶은 동등한 X문자와 나머지 문자 목록을 보냅니다 R. 가능한 두 가지 종류의 표현이 있습니다.

  • 의 첫 번째 문자 Lx이면 표현식은 x이고 나머지는 x.
  • 그렇지 않으면 연산자를 구문 분석 O하십시오 ( oper아래 참조). 표현식을 파싱 Y; O다시 파싱 ; 다른 표현을 파싱 Z; O세 번째로 파싱 합니다. 나머지는의 세 번째 인스턴스 이후의 모든 것입니다 O. 발현은 접합의 결과 Y, OZ문자열로 괄호에 둘러싸인.

oper첫 번째 문자가 C있고 나머지 문자가있는 문자 목록을 가져옵니다 T. 연산자를 분석하고 (즉, 하나 이상의 연산자 문자의 실행) 연산자 O와 나머지 문자 목록을 보냅니다 R. 연산자를 구성하려면 문자 C가 아닌 다른 문자 여야합니다 x. 또한

  • 운영자는 P에서 구문 분석해야 T나머지는, R; 이 경우 O의 연결이다 C하고 P; 또는,
  • O단일 문자입니다 C. 이 경우에는 R입니다 T.

효과적인 예

+*+x+x++*x+*예를 들어 입력 을 보자 .

  • 의 표현식을 구문 분석하려고합니다 +*+x+x++*x+*. 로 시작하지 않으므로 x연산자를 처음부터 구문 분석합니다.
  • oper최대한 큰 연산자를 구문 분석하므로 시도해보십시오 +*+.
    • 다음으로에서 식을 구문 분석합니다 x+x++*x+*. 이 있어야합니다 x.
    • 이제 우리는 같은 연산자를 구문 분석하려고 +*+부터 +x++*x+*. 그러나 이것은 실패합니다 .
  • 그래서 우리는 역 추적하고 +*대신 연산자 를 파싱하려고 시도 합니다.
    • 의 표현식을 구문 분석합니다 +x+x++*x+*. 로 시작하지 않으므로 x연산자를 구문 분석해야합니다.
    • 유일한 가능성은 +입니다.
    • 이제에서 하위 표현식을 구문 분석하십시오 x+x++*x+*. 이 있어야합니다 x.
    • 이제 +에서 다시 구문 분석 하십시오 +x++*x+*.
    • 이제에서 다른 하위 표현식을 구문 분석하십시오 x++*x+*. 이 있어야합니다 x.
    • 마지막으로에서 +다시 구문 분석 하십시오 ++*x+*.
    • 표현식이 구문 분석되었습니다. 우리는 문자열을 반환합니다 (x+x).
  • 이전 재귀 수준으로 돌아가서에서 연산자를 +*다시 구문 분석합니다 +*x+*.
  • 이제에서 다른 하위 표현식을 구문 분석하십시오 x+*. 이 있어야합니다 x.
  • 마지막으로에서 +*다시 구문 분석 하십시오 +*.
  • 표현식이 구문 분석되었습니다. 우리는 문자열을 반환합니다 ((x+x)+*x).

남은 문자가 더 이상 없으므로 표현식을 성공적으로 번역했습니다.


4

Perl, 78 60 58 57 50 바이트

포함 +1을 위해p

용도 1에 대한 +2대한 *(또는 실제로 어떤 연산자에 대한 자리 작품)

perl -pe 's/\b((\d+)((?1)|_)\2((?3))\2)\b/($3 $2 $4)/&&redo' <<< 22_22_22_2_2222_2

주어진 예제와 비교하여 편리한 테스트를 위해 이것을 사용하여 번역 및 공간 제거를 수행 할 수 있습니다.

perl -pe 'y/+*/12/;s/\b((\d+)((?1)|_)\2((?3))\2)\b/($3 $2 $4)/&&redo;y/ //d;y/12/+*/' <<< "**_**_**_*_****_*"

3

청소 , 200 192 189 바이트

import StdEnv,Text
f"_"=["_"]
f l=["("+a+p+b+")"\\p<-[l%(0,i)\\i<-[0..indexOf"_"l]|endsWith(l%(0,i))l],t<-[tl(init(split p l))],n<-indexList t,a<-f(join p(take n t))&b<-f(join p(drop n t))]

온라인으로 사용해보십시오!

함수 f를 가져 와서 결과가 포함 String된 싱글 톤 [String]을 반환하도록 정의합니다 .

깔끔한 것들 :

  • 정규식을 사용하지 않습니다
  • 연산자를 제외한 모든 문자와 작동_

3

레티 나 0.8.2 , 138 바이트

.+
($&)
+`\((\d+)(_|((?<i>(?<i>\d+))|_(?<-i>\k<i>)+)+(?(i)(?!)))\1(_|((?<i>(?<i>\d+))|_(?<-i>\k<i>)+)+(?(i)(?!)))\1\)
(($2)$1($4))
\(_\)
_

온라인으로 사용해보십시오! 링크에는 더 빠른 테스트 사례가 포함됩니다. 설명 : 정규식 엔진은 역 추적을 사용하여 문자열을 토큰으로 분할 한 다음 i밸런싱 그룹 에서 푸시 또는 팝합니다 . 첫 번째 변수 전에 시작시 항상 최소 한 명의 작업자가 푸시되었습니다. 변수 다음에 하나 이상의 연산자가 팝업되어 푸시 된 연산자 실행 또는 다른 변수가 유효합니다. 운영자가 올바르게 팝업되도록 그룹에 이중으로 푸시됩니다. 예:

Input           Stack
Push *          * *
Push *++*+***   * * *++*+*** *++*+***
Push +          * * *++*+*** *++*+*** + +
Push +          * * *++*+*** *++*+*** + + + +
Variable _
Pop +           * * *++*+*** *++*+*** + + +
Variable _
Pop +           * * *++*+*** *++*+*** + +
Pop +           * * *++*+*** *++*+*** +
Variable _
Pop +           * * *++*+*** *++*+***
Pop *++*+***    * * *++*+***
Variable _
Pop *++*+***    * *
Pop *           *
Push *          * * *
Variable _
Pop *           * *
Push *          * * * *
Variable _
Pop *           * * *
Variable _
Pop *           * *
Pop *           *
Pop *

불행히도 결과를 괄호로 묶기 위해 결과를 캡처하는 데 도움이되지 않으므로 외부 연산자를 수동으로 일치시킵니다. 대괄호는 외부에 추가되므로 첫 번째 단계는 전체 표현식을 대괄호로 묶고 마지막 단계는 변수로 전파 된 것을 제거합니다.


1
이것도 실패합니다 **_**_**_*_****_*.
user202729

@ user202729 지금 일하고 있습니까?
Neil

@Neil 지금 작동하고 있습니다.
OUurous

1

하스켈 , 167166 바이트

head.e
e('_':r)=["_",r]
e(x:r)=[x]%r
e _=[]
o%t@(c:r)|[x,u]<-e t,n<-length o,[y,v]<-e$drop n u,all((==o).take n)[u,v]=['(':x++o++y++")",drop n v]|p<-o++[c]=p%r
o%_=[]

온라인으로 사용해보십시오! 사용법 예 : head.e "**_**_**_*_****_*"yields ((_*(_*(_*_)))*_). 제외한 모든 문자 _는 연산자로 해석되며 _자체는 식별자를 나타냅니다.


0

파이썬 3, 226 바이트

from re import*
P=r'([*+]+)'+r'(\(.+?\)|_)\1'*2;R=lambda i,J=lambda i,o:i[:o]+sub(P,lambda o:'('+o[2]+o[1]+o[3]+')',i[o:],1),s=search:s(P,i)and R([J(i,o)for o in range(len(i))if s(P,J(i,o))or J(i,o)[0]+J(i,o)[-1]=='()'][0])or i

이라는 익명 함수를 정의합니다 R.

온라인으로 사용해보십시오!


_*+; 이외의 다른 문자를 사용할 수 있습니다 . 그것들은 예제에서 사용 된 것입니다. 이것을 사용하여 정규 표현식을 골프화 할 수 있습니다 (예 : \d대신 에 사용 [*+]).
Esolanging Fruit
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.