Minsky 레지스터 머신 시뮬레이션 (II)


11

이것은 Minsky Register Machine (I) 의 확장입니다 . 나는 거기에 모든 설명을 반복하지 않을 것이므로 먼저 문제 설명을 읽으십시오.

(I) 부분의 문법은 가능한 한 단순했지만 프로그램이 다소 길어졌습니다. 이 사이트는 코드 골프 사이트이기 때문에 골프 문법이 아닌가?

높은 수준에서 원래 문법의 변경 사항은 다음과 같습니다.

  • 첫 번째 줄의 레이블은 선택 사항입니다
  • 두 개의 인접한 식별자를 분리해야하는 경우를 제외하고 공백은 선택 사항입니다.
  • 상태를 인라인 할 수 있습니다. 모호하지 않은 구문 분석을 보장하기 위해 감소 연산의 첫 번째 상태가 인라인 상태 인 경우 괄호로 묶어야합니다. 이것은 모든 프로그램이 하나의 라이너로 골프를 칠 수 있음을 의미합니다.

예를 들어, 원래 테스트 사례에서 우리는 다음을 수행했습니다.

b + = a, t = 0

init : t - init d0
d0 : a - d1 a0
d1 : b + d2
d2 : t + d0
a0 : t - a1 "Ok"
a1 : a + a0
a=3 b=4

골프 문법에서는 다음과 같이 단축 될 수 있습니다.

init:t-init d
d:a-(b+t+d)a
a:t-(a+a)"Ok"
a=3 b=4

또는:

init:t-init d:a-(b+t+d)a:t-(a+a)"Ok"
a=3 b=4

"프로그램"라인에 대한 새로운 BNF (데이터 인 마지막 라인과 반대)는 다음과 같습니다.

program    ::= first_line (newline line)*
first_line ::= cmd
line       ::= named_cmd
state      ::= state_name
             | cmd
             | '"' message '"'
delim_state::= '(' cmd ')'
             | '"' message '"'
cmd        ::= raw_cmd
             | named_cmd
named_cmd  ::= state_name ' '* ':' ' '* raw_cmd
raw_cmd    ::= inc_cmd
             | dec_cmd
inc_cmd    ::= reg_name ' '* '+' ' '* state
dec_cmd    ::= reg_name ' '* '-' ' '* delim_state ' '* state
             | reg_name ' '* '-' ' '* state_name ' '* delim_state
             | reg_name ' '* '-' ' '* state_name ' '+ state
state_name ::= identifier
reg_name   ::= identifier

식별자와 메시지는 이전 도전과 같이 유연합니다.


이전 도전 과제의 모든 테스트 사례가 여전히 적용 가능합니다. 또한, 다음 골프 조세 푸스 솔루션은 대부분의 문법을 연습해야합니다.

in:k-(r+t+in)in2:t-(k+in2)r-(i+n-0"ERROR n is 0")"ERROR k is 0"
0:n-(i+2:k-(r+t+2)5:t-(k+5)7:i-(r-(t+7)c:t-(i+r+c)i+0)a:t-(i+a)7)"Ok"
n=40 k=3

예상 출력 :

Ok
i=40 k=3 n=0 r=27 t=0

그리고 나는 이것이 나머지 경우를 다룬다 고 생각합니다.

k+k-"nop""assert false"
k=3

예상 출력 :

nop
k=3

모든 프로그램에 의미있는 의미가 있다고 가정 할 수 있습니다. 특히, 그들은 적어도 하나의 상태를 가질 것이고 상태를 재정의하지 않을 것입니다. 그러나 이전과 같이 상태를 정의하기 전에 사용할 수 있습니다.

스코어링은 코드 골프의 변형입니다. 자체 포함 된 프로그램을 작성할 수 있으며 UTF-8 인코딩 후 프로그램 길이를 바이트 단위로 표시합니다. 또는 코드 재사용이 우수하기 때문에 파트 (I)를 n1바이트 단위로 구현 한 경우 파트 (II) 프로그램을 파트 (I) 프로그램으로 변환하여 원본으로 파이프 할 수있는 프로그램을 작성할 수 있습니다. 그러면 점수가 변환 프로그램의 길이에 플러스가 ceil(n1 / 2)됩니다.

NB 변환을 선택한 경우 익명 상태가 명명 된 상태와 충돌하지 않도록 익명 상태의 이름을 생성해야합니다.

답변:


6

Haskell, 552 499 493 자

import Control.Monad.RWS
import Data.Map
main=interact$z.lines
z x=let(s:_,w)=evalRWS(mapM(q.t)x)w[]in s.f.i.t$last x 
p=get>>=q
q(l:":":x)=x%do a<-p;tell$f[(l,a)];r a
q(v:"+":x)=x%fmap(.a v 1)p
q(v:"-":x)=x%liftM2(d v)p p
q(('"':s):x)=x%r(\w->unlines[init s,do(v,x)<-assocs w;v++'=':show x++" "])
q(n:x)|n<"*"=x%p|1<3=x%asks(!n)
d v p n w|member v w&&w!v>0=p$a v(-1)w|1<3=n w
t[]=[];t x=lex x>>= \(y,x)->y:t x
i(v:_:x:t)=(v,read x):i t;i[]=[]
x%m=put x>>m;r=return;a=insertWith(+);f=fromList

전체 재 작성을 어느 정도 수행했습니다. CPS를 RWS 모나드로 대체하여 아직 구문 분석하지 않은 상태 (게으름을 위해!)와 다른 조정을 검색하기 위해 자체 출력을 읽습니다.

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