模拟Minsky套准机(II)


11

这是“ 模拟Minsky注册机(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

“ program”行(相对于最后一行,即data)的新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编码后的字节数计为程序的长度。另外,由于代码重用是一件好事,因此,如果您已实现了以n1字节为单位的部分(I),则可以编写一个程序,将部分(II)程序转换为部分(I)程序,以准备通过管道传递至原始程序。然后,您的分数将是转换程序的长度加ceil(n1 / 2)

注意:如果您选择转换,则需要以匿名方式生成名称,以确保它们不会与命​​名状态冲突。

Answers:


6

哈斯克尔,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

进行了或多或少的完全重写。用RWS monad替换了CPS,该RWS monad读取自己的输出以查找尚未解析的状态(是的,这很懒惰!),以及其他一些调整。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.