Kipple을 해석하십시오!


12

소개

Kipple 은 2003 년 3 월 Rune Berg가 발명 한 스택 기반의 난해한 프로그래밍 언어입니다.

Kipple에는 27 개의 스택, 4 개의 연산자 및 제어 구조가 있습니다.

스택

스택은 이름이 지정됩니다 a- z및 32 비트 부호있는 정수가 포함되어 있습니다. @숫자를보다 편리하게 출력 할 수 있도록 특수 스택이 있습니다 . 숫자를로 푸시하면 @실제로 해당 숫자의 ASCII 값이 대신 푸시됩니다. 예를 들어 12를 @로 설정하면 49를 누른 다음 50을 @대신 누릅니다 .

i프로그램이 실행되기 전에 입력이 입력 스택으로 푸시 됩니다. 인터프리터는 i실행 전에 저장할 값을 묻습니다 . 실행이 완료되면 출력 스택의 모든 항목 o이 팝업되어 ASCII 문자로 출력됩니다. 이것이 Kipple의 유일한 IO 메커니즘이므로 Kipple 프로그램과 상호 작용할 수 없습니다.

연산자

피연산자는 스택 식별자 또는 부호있는 32 비트 정수입니다.

푸시 : >또는<

구문 : Operand>StackIndentifier또는StackIndentifier<Operand

Push 연산자는 피연산자를 왼쪽으로 가져 와서 지정된 스택으로 푸시합니다. 예를 들어, 12>a값 12를 stack에 푸시합니다 a. a>bstack에서 최상위 값을 팝하고 stack a에 밀어 넣습니다 b. 빈 스택을 터지는 것은 항상 0이 반환 a<b에 해당합니다 b>a. a<b>c최상부로부터 팝 값 b과 푸쉬 모두 ca.

더하다: +

통사론: StackIndentifier+Operand

Add 연산자는 스택에서 최상위 항목과 피연산자의 합계를 스택으로 푸시합니다. 피연산자가 스택 인 경우 값이 해당 피연산자에서 팝됩니다. 예를 들어 stack의 최상위 값 a이 1이면 a+23을 밀어 넣습니다. a비어 있으면 a+22를 밀어 넣습니다. 스택의 최상위의 값이있는 경우 ab1, 2이고, 다음 a+b스택으로부터 값 2 나옵니다 b및 스택으로 푸시 3 a.

덜다: -

통사론: StackIndentifier-Operand

빼기 연산자는 더하기 대신 빼는 것을 제외하고는 추가 연산자와 똑같이 작동합니다.

명확한: ?

통사론: StackIndentifier?

최상위 항목이 0이면 Clear 연산자가 스택을 비 웁니다.

통역사는 운영자 옆에없는 것을 무시하므로 다음 프로그램이 작동 a+2 this will be ignored c<i합니다. 그러나 주석을 추가하는 올바른 방법은 #문자 를 사용하는 것입니다. a #와 줄 끝 문자 사이의 모든 것은 실행 전에 제거됩니다. ASCII 문자 # 10은 Kipple에서 줄 끝으로 정의됩니다.

피연산자는 두 연산자가 공유 할 수 있습니다 (예 : a>b c>b c?로 작성) a>b<c?.

프로그램 1>a<2 a+a은 (아래에서 위로) a값 을 포함 [1 4]하지 않습니다 [1 3]. -운영자도 마찬가지입니다 .

컨트롤 구조

Kipple에는 하나의 제어 구조가 있습니다 : 루프.

통사론: (StackIndentifier code )

지정된 스택이 비어 있지 않으면 일치하는 괄호 안의 코드가 반복됩니다. 루프는 다른 루프를 포함 할 수 있습니다. 예를 들어, 순서가 반대로 되더라도 stack (a a>b)의 모든 값을 stack a위로 옮깁니다 . 기능적으로 동일하지만 더 우아한 방법은 입니다.b(a>b)

100>@ (@>o)

출력됩니다 100

33>o 100>o 108>o 114>o 111>o 87>o 32>o 111>o 108>o 108>o 101>o 72>o

인쇄 "Hello World!"됩니다. o스택이 출력 될 때 스택 맨 위에서 맨 아래로 문자가 튀어 나오기 시작합니다.

#prime.k by Jannis Harder
u<200
#change 200


k<2>m
u-2
(u-1 u>t u>z u<t
  (k>e e+0 e>r)
  (e>k)
  m+1
  m>t
  m>z
  m<t
  t<0>z? t?
  1>g
  (r>b
    m+0 m>a
    b+0 b>w
    (a-1 
      b+0 b>j
      j?
      1>s
      (j<0>s j?)
      s?
      (s<0 w+0 w>b s?)
      a>t
      a>z
      t>a
      b-1
      b>t
      b>z
      t>b
      z<0>t? z?
    a?)
    b?
    1>p
    (b<0 b? 0>p)
    p?
    (p 0>r? 0>p? 0>g)
  )
  g?
  (g m+0 m>k 0>g?)
u?)
(k>@
  10>o
  (@>o)
)

이것은 소수 생성기이지만 작동 방식을 잘 모르겠습니다.

규칙

  • Kipple을 해석하는 프로그램 / 기능을 작성해야합니다. 이 프로그램 / 기능은 소스 파일을 통해 Kipple 프로그램을 얻거나 사용자로부터 직접 STDIN을 통해 얻을 수 있습니다. STDIN을 사용할 수없는 경우 키보드 입력에서 가져 와서 인쇄 할 수없는 특정 문자를 입력 할 때까지 계속 입력해야합니다. 예를 들어, 인터프리터가 x86 기계 코드로 작성된 경우 키보드에서 문자로 Kipple 프로그램 문자를 가져 와서 esc인쇄 가능한 문자를 생성하지 않는 다른 키를 누를 때까지 계속합니다 .

  • 구문 오류 또는 스택 오버플로와 같은 오류가있는 경우, 예를 들어 0 대신 10을 반환하거나 인터프리터 / 컴파일러가 생성 한 오류 메시지 인 BUT NOT PRINTING ERROR MESSAGES 와 같은 방식으로 오류를 인식해야합니다 .

  • 코드 골프에 대한 다른 규칙은이 도전에 적용됩니다.

  • Kipple의 샘플 아카이브 에있는 몇 가지 예제를 사용하여 코드를 테스트합니다.

이것은 입니다. 바이트 단위의 최단 코드가 이깁니다. 행운을 빕니다!


Kipple에는 선택적 연산자가 "있지만 사양의 일부가 아니며 공식 통역사의 추가 기능입니다. 여기에서는 언급하지 않았으므로 제출시 지원되지 않아도됩니다.

스펙의 어떤 부분에 의문이 있다면, Java로 작성된 공식 인터프리터를 사용 하여 검사 할 수 있습니다 . 컴파일 된 프로그램과 소스 코드가 포함 된 zip 파일을 다운로드합니다. GPL에 따라 라이센스가 부여됩니다.


1
우리가 부호있는 32 비트 정수를 사용하거나 우리가 호스트 구현의 자연 정수 유형으로 갈 수 있나요? (가장 중요한 경우는 부호없는 32 비트 정수, 부호있는 또는 부호없는 8 비트 정수 및 임의 정밀도 정수일 수 있습니다.)
Martin Ender

글쎄, 내가 esotric 위키에서 찾은 것입니다. 예, 통역사가 해당 기능을 기반으로하는 다른 kipple 프로그램과 호환되지 않을 수 있으므로

오류 발생시 동작에 대해 더 구체적으로 설명 할 수 있습니까? 따라서 잘못된 답변을 반환하거나 오류를 표시 할 수 있지만 오류를 인쇄 할 수 없습니까?
Alex A.

@Alex A. 예. 프로그램의 출력으로 간주 될 수 있기 때문에 에러 메시지와 동일한 출력을 가질 수있는 kipple 프로그램을 만들 수 있습니다. 또한 오류 메시지를 인쇄하는 기능 / 문이없는 "저렴한"(더 적은 문자 사용)입니다.

3
소스 프로그램에서 어떤 공백이 발생할 수 있습니까? istdin에서 소스 프로그램을 가져 오면 어떻게 입력을 요청할 수 있습니까?
orlp

답변:


6

C, 709702 바이트

바이트 점수는 줄 바꿈 (제거 가능)이 제거되었지만 읽기 쉽도록 줄 바꿈으로 여기에 게시합니다.

#define R return
#define C ;break;case
c[999]={};*P=c;*S[28];M[99999]={};t;*T;
u(s,v){S[s]+=28;*S[s]=v;
if(s>26){for(t=v/10;t;t/=10)S[s]+=28;T=S[s];do{*T=48+v%10;T-=28;}while(v/=10);}}
o(s){t=S[s]-M>27;S[s]-=28*t;R S[s][28]*t;}
I(s){R s<65?27:s-97;}
O(int*p){if(!isdigit(*p))R o(I(*p));
for(;isdigit(p[-1]);--p);for(t=0;isdigit(*p);t*=10,t+=*p++-48);R t;}

main(i,a){for(i=0;i<28;++i)S[i]=M+i;
for(;~(*++P=getchar()););P=c+1;
for(;;){i=I(P[-1]);switch(*P++){
case 35:for(;*P++!=10;)
C'<':u(i,O(P))
C'>':u(I(*P),O(P-2))
C'+':u(i,*S[i]+O(P))
C'-':u(i,*S[i]-O(P))
C'?':if(!*S[i])S[i]=M+i
C'(':for(i=1,T=P;i;++T)i+=(*T==40)-(*T==41);if(S[I(*P)]-M<28)P=T;else u(26,P-c)
C')':P=c+o(26)-1
C-1:for(;i=o(14);)putchar(i); R 0;}}}

와 컴파일 gcc -w golf.c( -w당신의 정신 건강에 대한 경고를 침묵).

iasdin이 stdin에서 코드를 가져 오는 경우 입력 방법에 대한 내 질문에 아직 응답하지 않았으므로 입력을 제외한 모든 것을 지원합니다 . 구문 오류는보고하지 않습니다.


나는 주요 게시물의 의견에서 "i"스택에 대한 귀하의 질문에 답변했습니다.

어떻게 kipple 프로그램을 읽는가? 명령 인수를 통해? 어떻게 사용해야합니까?

@GLASSIC stdin의 프로그램을 예상합니다.
orlp

언제까지 ? excution을 시작하는 방법?

@GLASSIC stdin에서 프로그램을 전달하십시오. 예 ./a.out < prime.k.
orlp

3

루비, 718 바이트 (현재 비경쟁)

나는 매우 피곤하다

파일은 명령 행 인수로로드되고 STDIN을 통해 입력이 전송됩니다. 또는 i레지스터에 입력이 필요하지 않은 경우 파일을 STDIN으로 파이프하십시오 .

사양과 관련하여 약간의 혼동으로 인해 현재 버전이 a<b>c올바르게 처리 되지 않으므로 수정 될 때까지 경쟁 하지 않습니다 .

a<b>c지금 수정되었습니다. 그러나 소수 함수를 실행할 때 여전히 잘못된 결과를 반환하므로 여전히 경쟁이 아닌 답변으로 남아 있습니다.

(f=$<.read.gsub(/#.*?\n|\s[^+-<>#()?]*\s/m,' ').tr ?@,?`
t=Array.new(27){[]}
t[9]=STDIN.read.bytes
k=s=2**32-1
r=->c{c=c[0];c[0]==?(?(s[c[1..-2]]while[]!=t[c[1].ord-96]):(c=c.sub(/^(.)<(\D)>(.)/){$1+"<#{t[$2.ord-96].pop||0}>"+$3}.sub(/(\d+|.)(\W)(\d+|.)?/){_,x,y,z=*$~
a=x.ord-96
b=(z||?|).ord-96
q=->i,j=z{j[/\d/]?j.to_i: (t[i]||[]).pop||0}
l=t[a]
y<?-?(x==z ?l[-1]*=2:l<<(l.pop||0)+q[b]
l[-1]-=k while l[-1]>k/2):y<?.?(x==z ?l[-1]=0:l<<(l.pop||0)-q[b]
l[-1]+=k while l[-1]<-k/2-1):y<?>?t[a]+=a<1?q[b].to_s.bytes: [q[b]]:y<???
(t[b]+=b<1?q[a,x].to_s.bytes: [q[a,x]]): l[-1]==0?t[a]=[]:0
z||x}while c !~/^(\d+|.)$/)}
s=->c{(z=c.scan(/(\((\g<1>|\s)+\)|[^()\s]+)/m)).map &r}
s[f]
$><<t[15].reverse.map(&:chr)*'')rescue 0

어쨌든 +1. 피보나치 프로그램을 사용해 보셨습니까?
edc65

@ edc65 Fibbonacci 시퀀스 프로그램도 잘못된 것을 인쇄합니다 : 0 1 1 2 4 8 16...스펙 오류인지 궁금합니다
Value Ink

아니요, 피보나치 프로그램은 a+0
엉망

소수에 대한 문제는 중첩 된 제어 구조를 처리하지 못한다는 것입니다.하지만 루비에 대해 많이 알지 못합니다. 추측이 맞습니다.

이 프로그램은 /(\((\g<1>|\s)+\)|[^()\s]+)/m토큰과 토큰 그룹을 분할하는 데 사용 되는 재귀 정규식 일치로 인해 중첩 된 Parens 세트를 올바르게 처리해야합니다 . ( regex101에서 테스트하십시오 ). 아마도 내 파싱의 나머지 부분에서 오류 일지 모르지만 어디에 있는지 모르겠습니다.
밸류 잉크
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.