Simula una macchina registro Minsky (II)


11

Questa è un'estensione di Simulate a Minsky Register Machine (I) . Non ripeterò qui tutta la descrizione, quindi per favore leggi prima la descrizione del problema.

La grammatica in parte (I) era il più semplice possibile, ma risulta in programmi piuttosto lunghi. Dal momento che questo è un sito di golf in codice, preferiremmo avere una grammatica del golf, no?

Ad un livello elevato, le modifiche rispetto alla grammatica originale sono le seguenti:

  • L'etichetta sulla prima riga è facoltativa
  • Lo spazio bianco è facoltativo, tranne dove richiesto per separare due identificativi adiacenti
  • Gli stati possono essere integrati. Per garantire un'analisi non ambigua, se il primo stato di un'operazione di decremento è uno stato inline, deve essere racchiuso tra parentesi. Ciò significa che qualsiasi programma può essere giocato in un solo giocatore.

Ad esempio, nei casi di test originali abbiamo avuto:

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

Nella grammatica del golf questo potrebbe essere abbreviato in:

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

o anche:

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

Il nuovo BNF per le righe del "programma" (al contrario della riga finale, che è data) è:

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

Identificatori e messaggi sono flessibili come nella sfida precedente.


Tutti i casi di test della sfida precedente sono ancora applicabili. Inoltre, la seguente soluzione golfica di Josephus dovrebbe esercitare la maggior parte della grammatica:

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

Uscita prevista:

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

E penso che questo riguardi il caso rimanente:

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

Uscita prevista:

nop
k=3

Puoi presumere che tutti i programmi avranno una semantica ragionevole. In particolare, avranno almeno uno stato e non ridefiniranno uno stato. Tuttavia, come in precedenza, è possibile utilizzare uno stato prima di definirlo.

Il punteggio è una variante del code-golf. È possibile scrivere un programma autonomo e assegnerà un punteggio come lunghezza del programma in byte dopo la codifica UTF-8. In alternativa, poiché il riutilizzo del codice è una buona cosa, se hai implementato la parte (I) in n1byte, puoi scrivere un programma che trasforma un programma di parte (II) in un programma di parte (I), pronto per il piping all'originale. Il tuo punteggio sarà quindi la lunghezza del tuo programma di trasformazione più ceil(n1 / 2).

NB Se si opta per la trasformazione, sarà necessario generare nomi per gli stati anonimi in modo tale da garantire che non si scontrino con gli stati con nome.

Risposte:


6

Haskell, 552 499 493 caratteri

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

Più o meno una riscrittura completa. Sostituito CPS con una monade RWS che legge il proprio output per cercare gli stati che non ha ancora analizzato (yay per pigrizia!), Oltre ad altre modifiche.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.