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


19

면책 조항 : 아니오, 이것은 문자열을 뒤집는 농담 도전이 아닙니다.

직무

뺄셈 ( -) 만 지원하는 연산이 하나 있습니다 .

또한 지원할 원자는 0 ( 0)과 1 ( 1) 두 개뿐입니다 .

여기서, 프리픽스 표기 -AB후위 표기법에 상당 AB-, AB식이다.

작업은 접두사 표기법의 표현식을 접두사 표기법의 표현식으로 (재귀 적으로) 변환하는 것입니다.

정의

접두사 표기법의 표현식은 다음 문법으로 생성됩니다.

S > -SS
S > 0
S > 1

접미사 표기법의 표현식은 다음 문법으로 생성됩니다.

S > SS-
S > 0
S > 1

Prefix notation:  --01-0-01
Parentheses:      -(-01)(-0(-01))
Convert:          (01-)(0(01-)-)-
Postfix notation: 01-001---

규칙과 자유

  • 일관된 한 작업 및 원자 이름을 다른 문자로 바꿀 수 있습니다.
  • 입력 형식은 출력 형식과 일치해야합니다 (입력이 접두사 표기법이고 출력이 접미사 표기법이라는 사실은 제외).

테스트 케이스

Input       Output
1           1
0           0
-01         01-
-10         10-
--01-0-01   01-001---

Dada에 대한 크레딧을 테스트합니다 .


1
몇 가지 테스트 사례를 추가 할 수 있습니까?
얽히고 설킨

@Shaggy 어떤 테스트 케이스를 원하십니까?
Leaky Nun

@LeakyNun 최신 버전의 답변에서했던 것처럼 입력 및 출력을 반복자로 가져가는 것이 좋습니까?
L3viathan

@ L3viathan 나는 그렇게 생각합니다 ...
Leaky Nun

답변:


12

brainfuck , 32 바이트

,[[->++++<<+>]>[[-]<<[.[-]<]]>,]

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

@코드 포인트 (64)가 편리하기 때문에 작업으로 사용 했습니다. U3 * 85 + 1 = 256 = 0을 사용하여 동일한 바이트 수로도 가능합니다.

설명

테이프는 스택으로 사용됩니다. 메인 루프의 각 반복에서 데이터 포인터는 스택 맨 위에서 두 개의 셀을 시작합니다.

,[                Take input and start main loop
  [->++++<<+>]    Push input, and compute 4*input
  >[              If 4*input is nonzero (and thus input is not @):
    [-]<<           Zero out this cell and move to top of stack
    [.[-]<]         Pop from stack and output until \0 is reached
  ]
  >,              Move pointer into the correct position.  If input was @, the earlier > pushed \0 onto the stack.
]

6

망막 , 37 30 29 바이트

M!`-*.
+m`^-(.*)¶(\d.*)
$1$2-

온라인으로 사용해보십시오! 용어가 항상 숫자로 시작된다는 것을 인식하여 7 바이트를 절약했습니다. 따라서 -더 이상 마지막으로 일치를 제한 할 필요가 없습니다 (이전에는 두 용어가 뒤 따르는 것이 유일한 것이 었습니다). -자신의 줄 에 s를 넣지 않고 1 바이트를 절약 했습니다. 예를 들어, -01이된다 -0¶1다음으로 대체된다 01-. 내가 가지고있는 지금, 만약 --010예를 --0¶1¶0다음 나는 내부를 변경하려면 -0¶101-나는 장착 할 수 있도록 -01-¶0함께 01-0-하지만 문제가 실제로하지 않는 두의 -의 I 삭제, 같은 라인의 시작 부분에 하나를 제거 그래서 테스트하기가 더 쉽습니다.


나는 이것이 당신의 것이라고 생각 합니다 :)
Leo

@Leo합니까는 예를 들면, 일반적으로 작동하지 -0-0-00하게한다 0000---.
Neil

네 말이 맞아 미안해 다른 아이디어가 있지만 실제로는 달라서 새로운 답변으로 게시하겠습니다
Leo

1
@Leo 나는 이제 내 무언가를 찾았다.
Neil

1
@Leo 최신 골프와 함께 우리는 묶여 있습니다!
Neil

6

하스켈 , 62 59 바이트

f(x:r)|x>'-'=([x],r)|(a,(b,c))<-f<$>f r=(a++b++"-",c)
fst.f

온라인으로 사용해보십시오! 사용법 : fst.f $ "--01-0-01". 01문자보다 큰 임의의 문자 수 있습니다 -.

편집 : Zgarb 덕분에 -3 바이트!

이 함수 f는 하나의 표현식을 재귀 적으로 구문 분석하고 유효한 접두사 표현식을 작성할 수있는 간단한 문법에 따라 접미사 표기법과 나머지 문자열로이 표현식의 튜플을 반환합니다.

<exp> ::= - <exp> <exp> | 0 | 1

a입력 문자열 의 첫 번째 문자 가보다 크면 -원자 표현식에 있고 문자 a와 나머지 입력 문자열 이 포함 된 문자열의 튜플을 반환 합니다.

를 찾으면 -두 표현식을 구문 분석해야합니다. 이것은 (a,x)<-f r첫 번째 표현식을 얻은 a다음 나머지 문자열을 x다시 구문 분석 (b,c)<-f x하여 두 번째 표현식 b과 최종 나머지 문자열 을 얻는 것 c입니다. 튜플에서는 튜플의 두 번째 요소 인 함수 2보다 3 바이트 더 짧아 (a,(b,c))<-f<$>f r지기 때문에 정확히이 <$>작업을 수행합니다 (a,x)<-f r,(b,c)<-f x. 표현식과 나머지 문자열을 모두 얻은 후 표현식이 연결되고 "-"가 추가됩니다 (a++b++"-",c).


1
사례를 결합하여 3 바이트를 절약 할 수 있습니다.f(x:r)|x>'-'=([x],r)|(a,(b,c))<-f<$>f r=(a++b++"-",c)
Zgarb

@Zgarb 감사합니다! 어떤 이유로 든 f(x:r)|x<'0',(a,(b,c))<-f<$>f r=(a++b++"-",c)|1<3=([x],r)두 바이트가 결합 된 버전을 찾을 때만 고려했습니다 . 바이트가 더 깁니다.
Laikoni

5

하스켈, 54 바이트

v f""=""
v f(a:s)=last(v.v:[id|a>'-'])((a:).f)s
h=v h

이 함수 v는 문자열과 함수를 가져 와서 초기 하위 표현식을 재배 열한 다음 모든 것이 재 배열 될 때까지 나머지 문자열에 함수를 적용합니다. 호출 스택과 함수 인수는 함께 구문 분석되는 표현식을 추적합니다. 이 함수 h는 챌린지에 응답하며, v더미 첫 번째 인수로 자체 호출됩니다.


1
와! (1) 53 세에 불과하므로 최종 개행을 세지 않아도됩니다. (2) 두 번째 v f l=l로 움직이면 첫 번째 줄을 줄일 수 있습니다 .
Ørjan Johansen

1
하나 이상의 전체 표현식을 구문 분석해야한다고 생각하지 않으므로 anonymous 함수를 사용하여 바이트를 절약 할 수 있습니다 v id.
Ørjan Johansen 1

1
실제로 첫 번째 줄은 유효한 입력에서 호출되지 않으므로 그냥 삭제할 수 있습니다.
Ørjan Johansen 1

1
가드로 분할하면 last트릭을 1 바이트 씩 이기는 것 같습니다 .
Ørjan Johansen

4

펄 5 , 57 바이트

sub f{"@_"=~s/x((?0)|.)((?0)|.)/my$n=$2;f($1).f($n).x/re}

내가 사용하는 x대신 연산자로 -합니다 (TryItOnline 링크 울부 짖는 소리를 참조).

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

설명 :
/x((?0)|.)((?0)|.)/ 반복적으로 전체 표현식을 일치 x시킵니다. 시작 부분에 a 다음에 표현식 (?0)(재귀 호출) 또는 원자 ( .) 다음에 다른 표현식 또는 원자가옵니다.
그런 다음 두 번째 표현식 / 원자 ( my$n=$2;) 를 저장해야 합니다. 그렇지 않으면 재귀 호출이 재정의하기 때문입니다.
함수가 재귀 제 식 (호출되고 f($1)다음에 제) f($n), 및이 x끝에 추가된다 ( .x).


4

파이썬 3 117 112 105 100 98 76 62 61 59 바이트

def p(s):x=next(s);yield from[x]*(x>"-")or[*p(s),*p(s),"-"]

변경 로그:

  • 가능한 경우 줄 바꿈 제거 (-5 바이트)
  • 전체 함수 대신 람다 (-7 바이트, @Dada 덕분에)
  • 그 외의 것 없음 (-5 바이트, @Leaky Nun 덕분에)
  • 지나치게 열성적인 골프 실행 취소 (-2 바이트, @Leaky Nun 덕분에)
  • 대신 전체 목록에서 작업 (-22 바이트)
  • 실제로 반복자 대신 작업을 해 봅시다 (-14 바이트)
  • 변경 !=>(-1 바이트 @ovs '제안 복사)
  • 게으른 평가 속임수 (-2 바이트, @ovs 감사)

다음과 같이 사용하십시오.

>>> list(p(iter("--01-0-01")))
['0', '1', '-', '0', '0', '1', '-', '-', '-']


2
lambda x:p(x)[0]아마도 당신의 f기능을 대체 할 수 있습니다.
Dada

1
당신은 필요하지 않습니다 else.
Leaky Nun

1
d="-"실제로 바이트를 저장 합니까 ?
Leaky Nun

1
def p(s):x=next(s);yield from[x]*(x>"-")or[*p(s),*p(s),"-"]59 바이트
ovs

3

Pyth, 20 바이트

L+&-hbTsyM.-Btbytbhb

이것은 y문자열을 매개 변수로 기대 하는 함수 를 만듭니다 .

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

설명:

이 함수 y는 첫 번째 접두사 표현식을 구문 분석하고 접미사 표현식으로 변환합니다. 따라서 호출 된 경우 y"10"에만 반환됩니다 1.

L+&-hbTsyM.-Btbytbhb
L                      define a function y(b), that returns:
   -hbT                   remove the chars "10" from the first char b
                          (T=10, and - will convert a number to a string)
  &                       if this gives the empty string (a falsy value)
 +                hb         then append b[0] to it and return it
                             (so this will parse a digit 0 or 1 from the string)
  &                       otherwise (the first char is a -)
               ytb           parse the first prefix expression from b[1:]
                             (recursive call)
          .-Btb              remove this parsed expression bifurcated from b[1:]
                             this gives a tuple [b[1:], b[1:] without first expr]
        yM                   parse and convert an expression from each one
       s                     join the results
 +                hb         and append the b[0] (the minus) to it and return

2

망막 , 34 31 29 바이트


;
-;
¶
+`¶(.+);(.+)
$1$2-
;

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

;노드를 나타내는 데 사용되며 처음에는 단일 숫자로 구성되고 이미 구문 분석 된 항목으로 커집니다. 우리 -가 함께 .+구문 분석되지 않은 것을 잡을 수 있도록 개행 으로 바뀝니다 -.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.