Hay muchos formalismos, por lo que si bien puede encontrar otras fuentes útiles, espero especificar esto con suficiente claridad como para que no sean necesarias.
Un RM consta de una máquina de estados finitos y un número finito de registros con nombre, cada uno de los cuales contiene un número entero no negativo. Para facilitar la entrada de texto, esta tarea requiere que también se nombren los estados.
Hay tres tipos de estado: incremento y decremento, que hacen referencia a un registro específico; y terminar. Un estado de incremento incrementa su registro y pasa el control a su único sucesor. Un estado decreciente tiene dos sucesores: si su registro no es cero, lo decrementa y pasa el control al primer sucesor; de lo contrario (es decir, el registro es cero) simplemente pasa el control al segundo sucesor.
Para "amabilidad" como lenguaje de programación, los estados de terminación toman una cadena codificada para imprimir (para que pueda indicar una terminación excepcional).
La entrada es de stdin. El formato de entrada consta de una línea por estado, seguido del contenido del registro inicial. La primera línea es el estado inicial. BNF para las líneas estatales es:
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
Existe cierta flexibilidad en la definición de identificador y mensaje. Su programa debe aceptar una cadena alfanumérica no vacía como identificador, pero puede aceptar cadenas más generales si lo prefiere (por ejemplo, si su idioma admite identificadores con guiones bajos y es más fácil trabajar con usted). De manera similar, para el mensaje debe aceptar una cadena no vacía de caracteres alfanuméricos y espacios, pero puede aceptar cadenas más complejas que permitan líneas salientes y comillas dobles si lo desea.
La última línea de entrada, que proporciona los valores de registro iniciales, es una lista separada por espacios de asignaciones identificador = int, que no debe estar vacía. No es necesario que inicialice todos los registros nombrados en el programa: se supone que cualquiera que no esté inicializado es 0.
Su programa debe leer la entrada y simular el RM. Cuando alcanza un estado de terminación, debe emitir el mensaje, una nueva línea y luego los valores de todos los registros (en cualquier formato conveniente, legible para humanos y en cualquier orden).
Nota: formalmente los registros deben contener enteros ilimitados. Sin embargo, si lo desea, puede suponer que el valor de ningún registro superará los 2 ^ 30.
Algunos ejemplos simples
a + = b, a = 0s0 : a - s1 "Ok"
s1 : b + s0
a=3 b=4
Resultados previstos:
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
Resultados previstos:
Ok
a=3 b=7 t=0
Casos de prueba para máquinas más difíciles de analizar
s0 : t - s0 s1
s1 : t + "t is 1"
t=17
Resultados previstos:
t is 1
t=1
y
s0 : t - "t is nonzero" "t is zero"
t=1
Resultados previstos:
t is nonzero
t=0
Un ejemplo mas complicado
Tomado del desafío del código del problema Josephus del DailyWTF. La entrada es n (número de soldados) yk (avance) y la salida en r es la posición (indexada a cero) de la persona que sobrevive.
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
Resultados previstos:
Ok
i=40 k=3 n=0 r=27 t=0
Ese programa como una imagen, para aquellos que piensan visualmente y les sería útil comprender la sintaxis:
Si disfrutaste este golf, mira la secuela .