模拟Minsky套准机(I)


26

形式主义有很多,因此尽管您可能会发现其他有用的资料,但我希望对此加以足够明确的说明,以免不必要。

RM由有限状态机和有限数量的命名寄存器组成,每个命名寄存器都包含一个非负整数。为了便于文本输入,此任务要求还命名状态。

状态分为三种:增量和减量,它们都引用一个特定的寄存器。然后终止 递增状态递增其寄存器并将控制权传递给其后继者。递减状态有两个后继者:如果其寄存器为非零,则递减状态并将控制权传递给第一个后继者;否则(即寄存器为零),它将控制权简单地传递给第二个后继者。

对于“ niceness”作为一种编程语言,终止状态需要打印一个硬编码的字符串(因此您可以指示异常终止)。

输入来自标准输入。输入格式包括每个状态一行,然后是初始寄存器内容。第一行是初始状态。状态行的BNF为:

line       ::= inc_line
             | dec_line
inc_line   ::= label ' : ' reg_name ' + ' state_name
dec_line   ::= label ' : ' reg_name ' - ' state_name ' ' state_name
state_name ::= label
             | '"' message '"'
label      ::= identifier
reg_name   ::= identifier

标识符和消息的定义具有一定的灵活性。您的程序必须接受一个非空的字母数字字符串作为标识符,但是如果您愿意,它可以接受更通用的字符串(例如,如果您的语言支持带下划线的标识符,那么使用起来就更容易了)。同样,对于消息,您必须接受一个非空的字母数字和空格字符串,但是您可以接受更复杂的字符串,如果需要,可以使用转义的换行符和双引号字符。

输入的最后一行给出了初始寄存器的值,它是一个以空格分隔的ID = int分配列表,该列表必须为非空。不需要初始化程序中所有已命名的寄存器:未初始化的任何寄存器都假定为0。

您的程序应读取输入并模拟RM。当它到达终止状态时,它应该发出消息,换行符,然后发出所有寄存器的值(以任何方便,人类可读的格式和任何顺序)。

注意:形式上,寄存器应保存无界整数。但是,如果您希望假设没有寄存器的值会超过2 ^ 30。

一些简单的例子

a + = b,a = 0
s0 : a - s1 "Ok"
s1 : b + s0
a=3 b=4

预期成绩:

Ok
a=0 b=7
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

预期成绩:

Ok
a=3 b=7 t=0
难以解析的机器的测试用例
s0 : t - s0 s1
s1 : t + "t is 1"
t=17

预期成绩:

t is 1
t=1

s0 : t - "t is nonzero" "t is zero"
t=1

预期成绩:

t is nonzero
t=0

一个更复杂的例子

摘自DailyWTF的Josephus问题代码挑战。输入是n(士兵人数)和k(前进),而r中的输出是幸存者的位置(零索引)。

init0 : k - init1 init3
init1 : r + init2
init2 : t + init0
init3 : t - init4 init5
init4 : k + init3
init5 : r - init6 "ERROR k is 0"
init6 : i + init7
init7 : n - loop0 "ERROR n is 0"
loop0 : n - loop1 "Ok"
loop1 : i + loop2
loop2 : k - loop3 loop5
loop3 : r + loop4
loop4 : t + loop2
loop5 : t - loop6 loop7
loop6 : k + loop5
loop7 : i - loop8 loopa
loop8 : r - loop9 loopc
loop9 : t + loop7
loopa : t - loopb loop7
loopb : i + loopa
loopc : t - loopd loopf
loopd : i + loope
loope : r + loopc
loopf : i + loop0
n=40 k=3

预期成绩:

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

该程序作为图片,对于那些视觉思考的人来说,发现掌握语法很有帮助: 约瑟夫问题RM

如果您喜欢这种高尔夫,请看一下续集


输入来自标准输入,文件还是其他地方?
凯文·布朗

@Bass,来自stdin。
彼得·泰勒

您应该添加一些难以解决问题的测试用例:1)带空格的消息,2)等号的消息,3)inc_line中的消息,4)dec_line的第一种状态的消息,5)空格中的消息例3 4
MtnViewMark

语法有一个错误:dec_line中的两个state_name条目之间必须有一个文字空间。还不清楚您是否要要求人们在输入中的令牌之间接受多个空格。
MtnViewMark 2011年

2
@Peter:+1是一个真正的多肉代码高尔夫球,在规范和回旋余地之间取得了很好的平衡!这里的大多数问题都太少了。
MtnViewMark 2011年

Answers:


10

佩尔166

@p=<>;/=/,$_{$`}=$' for split$",pop@p;$o='\w+';(map{($r
,$o,$,,$b)=$'=~/".*?"|\S+/g if/^$o :/}@p),$_=$o=($_{$r}
+=','cmp$o)<0?do{$_{$r}=0;$b}:$,until/"/;say for eval,%_

用运行perl -M5.010 file

它的开始有很大的不同,但是恐怕它会在很多领域与Ruby解决方案融合。似乎Ruby的优势是“没有信号”和Perl的“更好的正则表达式集成”。

如果您不阅读Perl,可以从内部了解一些细节:

  • @p=<>:阅读整个机器说明以 @p
  • /=/,$_{$`}=$' for split$",pop@p:对于最后一个机器描述行forsplit$")中的每个()分配()@p,找到等号(/=/),然后将值分配$'给hask %_$`
  • $o='\w+':初始状态将是第一个匹配Perl正则表达式“单词字符”的状态
  • until/"/:循环直到我们到达终止状态:
    • map{($r,$o,$,,$b)=$'=~/".*?"|\S+/g if/^$o :/}@p:在机器描述中循环@p:当我们在线匹配当前状态(if/^$o :/)时,/".*?"|\S+/g将其余行标记为()$'变量($r,$o,$,,$b)。技巧:$o如果最初用于标签名称,然后用于运算符,则使用相同的变量。标签一旦匹配,操作员就会覆盖它,并且由于标签(不能(合理地)命名为+或-),因此不再匹配。
    • $_=$o=($_{$r}+=','cmp$o)<0?do{$_{$r}=0;$b}:$,
      - $_{$r}向上或向下调整目标寄存器(ASCII魔术:','cmp'+'为1,而','cmp'-'为-1);
      -如果结果为负(<0?,只能发生-)
      -然后停留在0($_{$r}=0)并返回第二个标签$b
      -否则返回第一个(可能是唯一的)标签$,
    • 顺便说一句,它$,代替了$a它,因此可以粘贴到下一个令牌,而until中间没有空格。
  • say for eval,%_:转储报告(eval)和中的寄存器内容%_

您实际上并不需要冒号/^$o :/。仅插入符就足以确保您仅查看标签。
Lowjacker 2011年

@Lowjacker我不需要它来确定我在正确的标签上,但是我需要将其保留在外面$'。这是正则表达式中的一个字符,$c,从外部考虑则是三个字符。或者,对标记化正则表达式进行一些更大的更改。
JB

10

Python + C,466个字符

只是为了好玩,一个Python程序将RM程序编译为C,然后编译并运行C。

import sys,os,shlex
G=shlex.shlex(sys.stdin).get_token
A=B=''
C='_:'
V={}
J=lambda x:'goto '+x+';'if'"'!=x[0]else'{puts('+x+');goto _;}'
while 1:
 L,c=G(),G()
 if''==c:break
 if':'==c:
  v,d=G(),G()
  V[v]=1;B+=L+c+v+d+d+';'
  if'+'==d:B+=J(G())
  else:B+='if('+v+'>=0)'+J(G())+'else{'+v+'=0;'+J(G())+'}'
 else:A+=L+c+G()+';'
for v in V:C+='printf("'+v+'=%d\\n",'+v+');'
open('C.c','w').write('int '+','.join(V)+';main(){'+A+B+C+'}')
os.system('gcc -w C.c;./a.out')

3
如果寄存器具有类似的名字这样可不行main',“ if”,等等
Nabb

1
@Nabb:Buzzkill。我留给读者在适当的地方添加下划线前缀。
基思·兰德尔

6

Haskell,444个字符

(w%f)(u@(s,v):z)|s==w=(s,f+v):z|t=u:(w%f)z
(w%f)[]=[(w,f)]
p#(a:z)|j==a=w p++[j]&z|t=(p++[a])#z;p#[]=w p
p&(a:z)|j==a=p:""#z|t=(p++[a])&z
c x=q(m!!0)$map((\(s,_:n)->(s,read n)).break(=='=')).w$last x where
 m=map(""#)$init x
 q[_,_,r,"+",s]d=n s$r%1$d
 q[_,_,r,_,s,z]d|maybe t(==0)(lookup r d)=n z d|t=n s$r%(-1)$d
 n('"':s)d=unlines[s,d>>=(\(r,v)->r++'=':shows v" ")]
 n s d=q(filter((==s).head)m!!0)d
main=interact$c.lines
t=1<3;j='"';w=words

伙计,那很难!正确处理带有空格的消息的成本超过70个字符。输出格式更加“易于阅读”,并且与示例匹配需要花费另外25英镑。


  • 编辑:(498-> 482)各种小内衬,以及@FUZxxl的一些建议
  • 编辑:(482-> 453)使用寄存器的实际数字切换回去;应用了许多高尔夫技巧
  • 编辑:(453-> 444)内联输出格式和初始值解析

我不了解Haskell,所以我无法解读所有语法,但是我可以解读得足够多,以至于您正在使用列表作为寄存器内容。我必须说我很惊讶,它比使用整数短。
彼得·泰勒

将本地绑定放在where以分号分隔的单行中可以节省6个字符。而且我想您可以q通过将详细的if-then-else更改为模式保护器来节省一些字符。
FUZxxl 2011年

并且:盲目的假设,第三个值"-"在的定义中,q而使用下划线代替。
FUZxxl

我想,您可以通过将第8行更改为来保存另一个字符q[_,_,r,_,s,z]d|maybe t(==0)$lookup r d=n z d|t=n s$r%(-1)$d。但是无论如何,这个程序非常出色。
2011年

通过利用lexPrelude,可以大大缩短解析代码。例如,类似的东西f[]=[];f s=lex s>>= \(t,r)->t:f r会在正确处理带引号的字符串时将一行拆分为标记。
hammar 2011年

6

红宝石1.9,214 212 211 198 195 192 181 175 173 175

*s,k=*$<
a,=s
b=Hash.new 0
eval k.gsub /(\w+)=/,';b["\1"]='
loop{x,y,r,o,t,f=a.scan /".*?"|\S+/
l=(b[r]-=o<=>?,)<0?(b[r]=0;f):t
l[?"]&&puts(eval(l),b)&exit
a,=s.grep /^#{l} /}

我希望这不会在彼此的标签前缀上失败。有什么想法吗?
JB

除示例外,我似乎无法使其与其他任何情况一起使用。有什么不对这个?
JB

我认为现在已修复。
Lowjacker 2011年

嗯,好多了。谢谢。
JB

3

德尔斐(646)

在拆分字符串和内容方面,Delphi并没有提供太多帮助。幸运的是,我们确实有通用集合,这确实有所帮助,但这仍然是一个比较笨拙的解决方案:

uses SysUtils,Generics.Collections;type P=array[0..99]of string;Y=TDictionary<string,P>;Z=TDictionary<string,Int32>;var t:Y;l,i:string;j,k:Int32;q:P;u:Z;v:TPair<string,Int32>;begin t:=Y.Create;repeat if i=''then i:=q[0];t.Add(q[0],q);ReadLn(l);for j:=0to 6do begin k:=Pos(' ',l+' ');q[j]:=Copy(l,1,k-1);Delete(l,1,k)end;until q[1]<>':';u:=Z.Create;j:=0;repeat k:=Pos('=',q[j]);u.Add(Copy(q[j],1,k-1),StrToInt(Copy(q[j],k+1,99)));Inc(j)until q[j]='';repeat q:=t[i];i:=q[4];u.TryGetValue(q[2],j);if q[3]='+'then Inc(j)else if j=0then i:=q[5]else Dec(j);u.AddOrSetValue(q[2],j)until i[1]='"';WriteLn(i);for v in u do Write(v.Key,'=',v.Value,' ')end.

这是缩进和注释的版本:

uses SysUtils,Generics.Collections;
type
  // P is a declaration line, offsets:
  // 0 = label
  // 1 = ':'
  // 2 = register
  // 3 = operation ('-' or '+')
  // 4 = 1st state (or message)
  // 5 = 2nd state (or message)
  P=array[0..99]of string;
  // T is a dictionary of all state lines :
  Y=TDictionary<string,P>;
  // Z is a dictionary of all registers :
  Z=TDictionary<string,Int32>;
var
  t:Y;
  l,
  i:string;
  j,
  k:Int32;
  q:P;
  u:Z;
  v:TPair<string,Int32>;
begin
  // Read all input lines :
  t:=Y.Create;
  repeat
    // Put all lines into a record
    if i=''then i:=q[0];
    t.Add(q[0],q);
    // Split up each input line on spaces :
    ReadLn(l);
    for j:=0to 6do
    begin
      k:=Pos(' ',l+' ');
      q[j]:=Copy(l,1,k-1);
      Delete(l,1,k)
    end;
    // Stop when there are no more state transitions :
  until q[1]<>':';
  // Scan initial registers :
  u:=Z.Create;
  j:=0;
  repeat
    k:=Pos('=',q[j]);
    // Add each name=value pair to a dictionary :
    u.Add(Copy(q[j],1,k-1),StrToInt(Copy(q[j],k+1,99)));
    Inc(j)
  until q[j]='';
  // Execute the state machine :
  repeat
    q:=t[i];
    i:=q[4];
    u.TryGetValue(q[2],j);
    if q[3]='+'then
      Inc(j)
    else
      if j=0then
        i:=q[5]
      else
        Dec(j);
    u.AddOrSetValue(q[2],j)
  until i[1]='"';
  WriteLn(i);
  for v in u do
    Write(v.Key,'=',v.Value,' ')
end.

1

PHP,446 441 402 398 395 389 371 370 366字符

<?$t=trim;$e=explode;while($l=$t(fgets(STDIN))){if(strpos($l,"=")){foreach($e(" ",$l)as$b){list($k,$c)=$e("=",$b);$v[$k]=$c;}break;}list($k,$d)=$e(":",$l);$r[$z=$t($k)]=$t($d);$c=$c?:$z;}while($d=$e(" ",$r[$c],4)){$c=$v[$a=$d[0]]||!$d[3]?$d[2]:$d[3];if(!$r[$c]){eval("echo $c.'\n';");foreach($v as$k=>$c)echo$k."=".$c." ";die;}if(!$d[3]&&++$v[$a]||$v[$a]&&--$v[$a]);}

不打高尔夫球


<?php

$register = array();
$values = array();

while($line = trim(fgets(STDIN))){

    if(strpos($line, "=")){

        // Set each value and then continue to the calculations

        foreach(explode(" ", $line) as $var){
            list($key, $val) = explode("=", $var);

            $values[$key] = $val;
        }

        break;
    }

    list($key, $data) = explode(":", $line);

    // Add data to the register

    $register[$z = trim($key)] = trim($data);

    // Set the first register

    $current = $current?:$z;
}

while($data = explode(" ", $register[$current], 4)){

    // Determine next register and current register

    $current = $values[$target = $data[0]] || !$data[3]? $data[2] : $data[3];

    // Will return true if the register does not exist (Messages wont have a register)

    if(!$register[$current]){

        // No need to strip the quotes this way

        eval("echo$current.'\n';");

        // Print all values in the right formatting

        foreach($values as $key => $val)
            echo $key."=".$val." ";

        die();
    }

    // Only subtraction has a third index
    // Only positive values return true

    // If there is no third index, then increase the value
    // If there is a third index, increment the decrease the value if it is positive

    // Uses PHP's short-circuit operators

    if(!$data[3] && ++$values[$target] || $values[$target] && --$values[$target]);
}

变更日志


446-> 441:支持第一种状态的字符串,并进行一些轻微压缩
441-> 402:尽可能多地压缩if / else和赋值语句
402-> 398:函数名称可用作常量,可用作字符串
398-> 395:使用短路运算符
395-> 389:不需要else部分
389-> 371:无需使用array_key_exists()
371-> 370:删除了不需要的空间
370-> 366:删除了两个不需要的空间的foreach


1

Groovy,338

m={s=r=[:];z=[:]
it.eachLine{e->((e==~/\w+=.*/)?{(e=~/((\w+)=(\d+))+/).each{r[it[2]]=it[3] as int}}:{f=(e=~/(\w+) : (.*)/)[0];s=s?:f[1];z[f[1]]=f[2];})()}
while(s[0]!='"'){p=(z[s]=~/(\w+) (.) (\w+|(?:".*?")) ?(.*)?/)[0];s=p[3];a=r[p[1]]?:0;r[p[1]]=p[2]=='-'?a?a-1:{s=p[4];0}():a+1}
println s[1..-2]+"\n"+r.collect{k,v->"$k=$v"}.join(' ')}


['''s0 : a - s1 "Ok"
s1 : b + s0
a=3 b=4''':'''Ok
a=0 b=7''',
'''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''':'''Ok
a=3 b=7 t=0''',
'''s0 : t - s0 s1
s1 : t + "t is 1"
t=17''':'''t is 1
t=1''',
'''s0 : t - "t is nonzero" "t is zero"
t=1''':'''t is nonzero
t=0''',
'''init0 : k - init1 init3
init1 : r + init2
init2 : t + init0
init3 : t - init4 init5
init4 : k + init3
init5 : r - init6 "ERROR k is 0"
init6 : i + init7
init7 : n - loop0 "ERROR n is 0"
loop0 : n - loop1 "Ok"
loop1 : i + loop2
loop2 : k - loop3 loop5
loop3 : r + loop4
loop4 : t + loop2
loop5 : t - loop6 loop7
loop6 : k + loop5
loop7 : i - loop8 loopa
loop8 : r - loop9 loopc
loop9 : t + loop7
loopa : t - loopb loop7
loopb : i + loopa
loopc : t - loopd loopf
loopd : i + loope
loope : r + loopc
loopf : i + loop0
n=40 k=3''':'''Ok
i=40 k=3 n=0 r=27 t=0'''].collect {input,expectedOutput->
    def actualOutput = m(input)
    actualOutput == expectedOutput
}

1
我对此进行了测试,但似乎没有向stdout输出任何内容。我需要添加什么才能查看结果?(根据规范说明,输出中寄存器的顺序无关紧要,因此您可以从中保存7个字符.sort()
Peter Taylor

@Peter感谢您的提示-我必须添加8个字符println-啊!
Armand

1

Clojure(344个字符)

对于“可读性”有一些换行符:

(let[i(apply str(butlast(slurp *in*)))]
(loop[s(read-string i)p(->> i(replace(zipmap":\n=""[] "))(apply str)(format"{%s}")read-string)]
(let[c(p s)](cond(string? s)(println s"\n"(filter #(number?(% 1))p))
(=(c 1)'-)(let[z(=(get p(c 0)0)0)](recur(c(if z 3 2))(if z p(update-in p[(c 0)]dec))))
1(recur(c 2)(update-in p[(c 0)]#(if %(inc %)1)))))))

1

附言()() (852) (718)

对于这次真实。执行所有测试用例。仍然需要RM程序立即进入程序流。

编辑:更多分解,减少过程名称。

errordict/undefined{& " * 34 eq{.()= !{& " .(=). load " .( ).}forall ^()=
stop}{^ ^ " 0 @ : 0}ifelse}put<</^{pop}/&{dup}/:{def}/#{exch}/*{& 0
get}/.{print}/~{1 index}/"{=string cvs}/`{cvn # ^ #}/+={~ load add :}/++{1
~ length 1 sub getinterval}/S{/I where{^}{/I ~ cvx :}ifelse}/D{/? # :/_ #
cvlit :}/+{D S({//_ 1 +=//?})$ ^ :}/-{/| # : D S({//_ load 0 ne{//_ -1
+=//?}{//|}ifelse})$ ^ :}/![]/@{~/! #[# cvn ! aload length & 1 add #
roll]:}/;{(=)search ^ # ^ # cvi @ :}/${* 32 eq{++}if * 34 eq{& ++(")search
^ length 2 add 4 3 roll # 0 # getinterval cvx `}{token ^
#}ifelse}>>begin{currentfile =string readline ^( : )search{`( + )search{`
$ ^ +}{( - )search ^ ` $ $ ^ -}ifelse}{( ){search{;}{; I}ifelse}loop}ifelse}loop

缩进并注释附加程序。

%!
%Minsky Register Machine Simulation
errordict/undefined{ %replace the handler for the /undefined error
    & " * 34 eq{ % if, after conversion to string, it begins with '"',
        .()= !{ % print it, print newline, iterate through the register list
            & " .(=). load " .( ). % print regname=value
        }forall ^()= stop % print newline, END PROGRAM
    }{ % if it doesn't begin with '"', it's an uninitialized register
        ^ ^ " 0 @ : 0 %initialize register to zero, return zero
    }ifelse
}put
<<
/^{pop}
/&{dup}
/:{def} % cf FORTH
/#{exch}
/*{& 0 get} % cf C
/.{print} % cf BF

% these fragments were repeated several times
/~{1 index}
/"{=string cvs} % convert to string
/`{cvn # ^ #} % convert to name, exch, pop, exch
/+={~ load add :} % add a value to a variable
/++{1 ~ length 1 sub getinterval} % increment a "string pointer"

/S{/I where{^}{/I ~ cvx :}ifelse} %setINIT define initial state unless already done
/D{/? # :/_ # cvlit :} %sr define state and register for generated procedure
/+{D S({//_ 1 +=//?})$ ^ :} % generate an increment state and define
/-{/| # : D S({//_ load 0 ne{//_ -1 +=//?}{//|}ifelse})$ ^ :} % decrement state
/![] %REGS list of registers
/@{~/! #[# cvn ! aload length & 1 add # roll]:} %addreg append to REGS
/;{(=)search ^ # ^ # cvi @ :} %regline process a register assignment
/${ %tpe extract the next token or "string"
    * 32 eq{++}if %skip ahead if space
    * 34 eq{ %if quote, find the end-quote and snag both
        & ++(")search ^ length 2 add 4 3 roll # 0 # getinterval cvx `
    }{
        token ^ # %not a quote: pull a token, exch, pop
    }ifelse
}
>>begin

{
    currentfile =string readline ^
    ( : )search{ % if it's a state line
        `( + )search{ % if it's an increment
            ` $ ^ + %parse it
        }{
            ( - )search ^ ` $ $ ^ - %it's a decrement. Parse it
        }ifelse
    }{ % not a state, do register assignments, and call initial state
        ( ){search{;}{; I}ifelse}loop %Look Ma, no `exit`!
    }ifelse
}loop
init0 : k - init1 init3
init1 : r + init2
init2 : t + init0
init3 : t - init4 init5
init4 : k + init3
init5 : r - init6 "ERROR k is 0"
init6 : i + init7
init7 : n - loop0 "ERROR n is 0"
loop0 : n - loop1 "Ok"
loop1 : i + loop2
loop2 : k - loop3 loop5
loop3 : r + loop4
loop4 : t + loop2
loop5 : t - loop6 loop7
loop6 : k + loop5
loop7 : i - loop8 loopa
loop8 : r - loop9 loopc
loop9 : t + loop7
loopa : t - loopb loop7
loopb : i + loopa
loopc : t - loopd loopf
loopd : i + loope
loope : r + loopc
loopf : i + loop0
n=40 k=3

自从我编写任何PostScript以来已经有一段时间了,但是您是否正在使用名称定义函数regline?您不能通过称呼诸如此类的东西来节省很多R吗?
彼得·泰勒

当然是。但是,由于所有这些定义与状态并在同一词典中注册名称并存,因此还存在潜在的问题。因此,我一直在尝试寻找具有某些助记符值的标点符号(所以我仍然可以阅读它:)。我也希望能找到更多的算法上的简化方法,所以我不想花太多的精力来换新的眼睛。
luser droog 2012年

1

AWK-447

BEGIN{FS=":"}NF<2{split($1,x," ");for(y in x){split(x[y],q,"=");
g[q[1]]=int(q[2])}}NF>1{w=$1;l=$2;gsub(/ /,"",w);if(!a)a=w;for(i=0;;)
{sub(/^ +/,"",l);if(l=="")break;if(substr(l,1,1)=="\""){l=substr(l,2);
z=index(l,"\"")}else{z=index(l," ");z||z=length(l)+1}d[w,i++]=
substr(l,1,z-1);l=substr(l,z+1)}}END{for(;;){if(!((a,0)in d))break;h=d[a,0];
if(d[a,1]~/+/){g[h]++;a=d[a,2]}else{a=g[h]?d[a,2]:d[a,3];g[h]&&g[h]--}}
print a;for(r in g)print r"="g[r]}

这是第一个测试的输出:

% cat | awk -f mrm1.awk
s0 : a - s1 "Ok"
s1 : b + s0
a=3 b=4
^D
Ok
a=0
b=7

1

STAX115个 100 字节

╥áípßNtP~£G±☼ΩtHô⌐╒╡~·7╝su9êq7h50Z`╩ë&ñ╝←j╞.½5└∩√I|ù┤╧Åτ╘8┼ç╕╒Æ►^█₧♫÷?²H½$IG☺S╚]«♀_≥å∩A+∩╣Δ└▐♫!}♥swα

运行并调试

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.