Alquimista (1547 bytes)
_->In_NN+2b+al+g
al+g+0NN->ak
al+g+NN->ah
ah+b->ah+m+d+z+a
ah+0b->C+Z+Q
Z+j+z->Z+j+d
Z+j+0z->M+s
M+g+b->M+g+r
M+g+h->M+g+d
M+g+0b+0h+q->J+U
J+o+h->J+o+m
J+o+a->J+o+d
J+o+0h+0a->2C+an+Q
an+j+h->an+j+d
an+j+0h->aC+s
aC+g->e+am+P
am+l+b->am+l+d
am+l+0b->al+s
ak+b->ak+m+d
ak+0b->C+aj+Q
aj+j+h->aj+j+b
aj+j+0h->I+n
I+f+e->I+f+a
I+f+b->I+f+m+d+z
I+f+0e+0b->C+ai+Q
ai+j+h->ai+j+b
ai+j+0h->aB+n
aB+f->H
H+z->H+d
H+a+e->H
H+0z+0e->G+i
G+i+0b->ag
G+i+b->az+b+n
az+f+0b->Out_a
az+f+b->G+b+n
G+f->G+t
ag+e->ag
ag+0e->af+t
af+i+e->af+i+a
af+i+0e->Out_a
Q->F+s
F+g+b->F+g+y
F+g+A->F+g
F+g+0b+0A->av+o
av+o+0m->w
av+o+m->m+ae+A
ae+m->ae+b
ae+0m->u+n
u+f+b->u+f+m
u+f+e->u+f+E
u+f+A->u+f+k+c
u+f+0b+0e+0A->ad
ad+c->ad+A
ad+0c->ac
ac+y->ac+d+c
ac+0y->ab
ab+c->ab+y
ab+0c->V+l
V+l+0k->x
V+l+k->aa+t
aa+i+0e->W
aa+i+e->Y
Y+E->Y+D+c
Y+0E->X
X+c->X+E
X+0c->aa+i
W+D->W+e
W+0D->V+P
x+E->x
x+d->x
x+b->x+k
x+0E+0d+0b->aw
aw+h->aw+d
aw+0h->aE+s
aE+g->p
p+b->p+2r
p+k->p+d
p+B->p
p+q->p
p+0b+0k+0B+0q->r+q+av+U
w+h->w+d
w+y->w+r
w+C->w+B+q
w+0h+0y+0C->aD+U
aD+o->j
U->au+s
au+g+b->au+g+d
au+g+0b->v
v+d->d+aA+t
aA+i+k->R
aA+i+0k->at
at+B->at+k+c
at+0B->L
L+c->L+B
L+r->L+b
L+0c+0r->as+n
as+f+b->as+f+r
as+f+0b->R
R+0e->K
R+e+q->ar+D+c
ar+e+q->ar+c
ar+0q->aq
aq+c->aq+q
aq+0c->R
K+D->K+e
K+h->K+b
K+0D+0h->ap+P
ap+l+b->ap+l+h
ap+l+0b->v
v+0d+k->v
v+0d+r->v
v+0d+0k+0r->o
s+0d->g
s+d->d+ao+t
ao+i->ao+P
ao+l->s
P->O+c
O+b->2c+O
O+0b->N
N+c->b+N
N+0c+e->O
N+0c+0e->l
n+b->n+c
n+0b->T
T+c->ay
T+0c->e+n
ay+c->b+T
ay+0c->f
t+d->t+c
t+0d->S
S+c->ax
S+0c->e+t
ax+c->d+S
ax+0c->i
Demostración en línea .
Nota: esto es bastante lento. Si prueba con un intérprete que admite la aplicación de una regla varias veces a la vez (por ejemplo, mi , aunque asegúrese de tener la última versión que corrige un error en el analizador), puede obtener una aceleración significativa agregando dos reglas:
T+2c->b+T
S+2c->d+S
que en línea una ruta a través de las reglas existentes
T+c->ay
ay+c->b+T
S+c->ax
ax+c->d+S
Disección parcial
En un nivel alto, esto usa el mismo enfoque que mi respuesta de CJam.
El modelo de cálculo de Alchemist es esencialmente la máquina de registro Minsky . Sin embargo, Alchemist expone muy bien la equivalencia de código y datos, y al permitir muchas fichas en el lado izquierdo de una regla de producción de manera efectiva, el estado no está limitado a ser representado por un átomo: podemos usar una tupla de átomos, y esto permite subrutinas (no recursivas). Esto es muy útil para el golf. Lo único que realmente le falta son las macros y la depuración.
Para las matrices estoy usando una función de emparejamiento que se puede implementar bastante bien en RM. La matriz vacía está representada por0 0y el resultado de anteponer X para armar UN es ( 2 A + 1 ) 2X. Hay una subrutina para emparejar: se llama a la subrutina P
y antepone el valor de e
a b
. Hay dos subrutinas a desvincular: n
unpairs b
a e
y b
; y se t
desvincula d
de e
y d
. Esto me permitió guardar bastantes datos aleatorios entre variables, lo cual es importante: una sola operación de "movimiento"
a, b = b, 0
se expande al menos a 17 bytes:
S+a->S+b
S+0a->T
donde S
es el estado actual y T
es el siguiente estado. Una "copia" no destructiva es aún más costosa, ya que debe hacerse como un "movimiento" desde y a
hacia b
un auxiliar tmp
, seguido de un "movimiento" desde tmp
atrás hacia a
.
Ofuscación
Aliasé varias variables entre sí y eliminé unos 60 estados en el proceso de jugar golf en el programa, y muchos de ellos no tenían nombres particularmente significativos de todos modos, pero para jugar golf completamente escribí un minimizador para que los nombres ahora sean completamente indescifrables. ¡Buena suerte en ingeniería inversa! Aquí está el minimizador (en CJam), que hace algunas suposiciones sobre el código, pero podría adaptarse para minimizar otros programas de Alchemist:
e# Obfuscate / minimise Alchemist program
e# Tokenise
qN%[SNS]e_*S%
e# Get token frequencies for substitution purposes, special-casing the I/O ones
_["+" "0" "2" "->" "_" N "In_n" "n" "Out_tmp2" "tmp2"]-
$e`$W%1f=
e# Empirically we want a two-char input for n and a one-char one for tmp2
["In_n" "Out_tmp2" "n" "tmp2"]\+
["In_NN" "Out_a" "NN"] "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"1/:A+ A2m*:e_"NN"a-+
1$,<
er
_s,p