Su tarea, si elige aceptarla, es crear un programa que analice y evalúe una cadena (de izquierda a derecha y de longitud arbitraria) de tokens que dan instrucciones, ya sea izquierda o derecha. Aquí están los cuatro tokens posibles y sus significados:
> go right one single step
< go left one single step
-> go right the total amount of single steps that you've gone right, plus one,
before you previously encountered this token and reset this counter to zero
<- go left the total amount of single steps that you've gone left, plus one,
before you previously encountered this token and reset this counter to zero
Sin embargo, hay un inconveniente: las señales de direcciones que su programa debería poder analizar se presentarán de esta forma:
<<->-><<->->>->>->
... en otras palabras, están concatenados, y es tarea de su programa averiguar la precedencia correcta de las direcciones y la cantidad de pasos a seguir (mirando hacia adelante). El orden de precedencia es el siguiente (de mayor a menor precedencia):
->
<-
>
<
Si encuentra <-
que no se han realizado pasos hacia la izquierda desde el inicio o desde el último reinicio, dé un solo paso hacia la izquierda. Se aplica la misma regla ->
, pero luego para ir a la derecha.
Su programa debe comenzar en 0 y su resultado debe ser un entero con signo que represente la posición final final.
Puede esperar que la entrada siempre sea válida ( <--->>--<
por ejemplo , nada parecido ).
Entrada de ejemplo:
><->><-<-><-<>>->
Pasos en este ejemplo:
step | token | amount | end position
------+-------+--------+--------------
1. | > | +1 | 1
2. | < | -1 | 0
3. | -> | +2 | 2
4. | > | +1 | 3
5. | <- | -2 | 1
6. | < | -1 | 0
7. | -> | +2 | 2
8. | <- | -2 | 0
9. | < | -1 | -1
10. | > | +1 | 0
11. | > | +1 | 1
12. | -> | +3 | 4
Para aclarar: la salida del programa solo debe ser la posición final final como un entero con signo. La tabla de arriba está ahí para ilustrar los pasos que tomó mi ejemplo. No es necesario generar una tabla, una fila de tablas o incluso las posiciones finales de los pasos. Solo se requiere la posición final final, como un entero con signo.
El código más corto, después de una semana, gana.
<-
es si es seguido inmediatamente por a<
o a->
. No hay forma en este lenguaje de representar la secuencia<-
entonces>
, lo que seríago left the total amount of single steps that you've gone left, plus one, then go right one single step
. ¿Es esto correcto y por diseño?Respuestas:
GolfScript, 46 caracteres
Este es uno de los programas de GolfScript más lineales que he escrito: no hay una sola asignación de bucle, condicional o variable. Todo se hace mediante la manipulación de cadenas:
Primero, reemplazo cada aparición de
->
by)
. Como se garantiza que la entrada sea válida, esto garantiza que cualquier ocurrencia restante de-
debe ser parte de<-
.A continuación, hago dos copias de la cadena. De la primera copia, elimino los caracteres
<
y-
, dejando solo>
y)
. Luego duplico el resultado, elimino todos los)
sy cada uno de>
los últimos)
de la segunda copia, los concateno y cuento los caracteres. Por lo tanto, en efecto, estoy contando:)
,>
después del último)
, y>
antes del último)
.A continuación, hago lo mismo para la otra copia, excepto esta vez contando
<
y en<-
lugar de>
y)
, y eliminando la-
s antes del recuento final de caracteres. Por lo tanto, cuento:<-
,<
después del último<-
, y<
antes del último<-
.Finalmente, resta el segundo recuento del primero y obtengo el resultado.
fuente
Python 2,7 -
154147134128 bytesSe han realizado serios cambios en la forma en que funciona este programa. Eliminé la explicación anterior, que todavía se puede encontrar en el historial de edición de esta respuesta.
Este es asqueroso.
Funciona casi de la misma manera que otras respuestas para esta pregunta, reemplazando los caracteres en la entrada con declaraciones válidas en ese idioma y ejecutándolos. Sin embargo, hay una gran diferencia:
replace
es una palabra larga. Tornillo que.A @ProgrammerDan en el chat se le ocurrió la idea de usar una tupla con la cadena
;').replace('
4 veces, para usar elstr.format()
método previo de formateo del texto. Cuatro instancias de%s
están en la cadena en la segunda línea, cada una tomando su valor del elemento asociado de la tupla al final. Como todos son iguales, cada uno%s
se reemplaza con;').replace('
. Cuando realiza las operaciones, obtiene esta cadena:Este es ahora un código válido de Python que se puede ejecutar con
exec
. Así es, bebé: Nestedexec
s me permite usar operaciones de cadena en el código que necesita realizar operaciones de cadena en el código . Alguien por favor mátame.El resto es bastante sencillo: cada comando se reemplaza con un código que realiza un seguimiento de tres variables: la posición actual, el número de derechos desde la última
->
, y lo mismo para las izquierdas y<-
. Todo se ejecuta y se imprime la posición.Notarás que lo hago
raw_input(';')
, usando ';' como un aviso, en lugar de loraw_input()
que no tiene aviso. Esto ahorra caracteres de una manera poco intuitiva: si lo hicieraraw_input()
, tendría que llenar la tupla).replace('
, y cada instancia de%s
tendría '; \' 'antes, excepto la primera . Tener un aviso crea más redundancia para que pueda guardar más caracteres en general.fuente
list.index()
regresa-1
cuando no puede encontrar el personaje" .. erm no. Se levanta unIndexError
. Es posible que lo hayas confundido constr.find
. De hecho, podría reemplazar[list('><rl').index(c)]
con['><rl'.find(c)]
.Perl,
134131...9995 bytesToma la entrada como una sola línea en stdin, por ejemplo:
o:
Dividí las instrucciones en operadores "derechos" (">" y "->") y operadores "izquierdos" ("<" y "<-"). Las ventajas de esto son que es más fácil explotar el paralelismo entre los operadores izquierdo y derecho, y no tenemos que hacer nada sofisticado para tokenizar la cadena. Cada "dirección" se trata como una operación de sustitución donde ajustamos el total acumulado por el número de pasos dados en esa dirección, ignorando la dirección inversa que se ocupa de la otra operación de sustitución. Aquí hay un antepasado menos golfista de este código como una especie de documentación:
En una iteración anterior de este código, todas las sustituciones se realizaron en una sola pasada. Esto tenía la ventaja de mantener una asignación directa entre $ p / $ pos y la posición que se devolvería en cualquier momento dado, pero tomó más bytes de código.
Si desea usar () 5.10.0, puede s / print / say / para eliminar otros 2 caracteres del conteo, pero ese no es realmente mi estilo.
fuente
Perl,
8877 bytesSe espera la entrada a través de STDIN, por ejemplo:
Actualizar
No es necesario convertir la cadena en una suma, porque
s//
ya está contando. :-)Primera versión
Se espera la entrada a través de STDIN, por ejemplo:
Explicación:
La idea es convertir la cadena de dirección en una suma para que el resultado salga de manera simple
print eval
.>
antes de que cualquiera->
tome dos pasos, uno a la vez y el otro al siguiente->
. No importa cuál de los dos->
sigue al menos a uno de ellos. El contador interno se reinicia después del siguiente->
, por lo>
que no provoca más pasos, el máximo es de dos pasos. Luego->
agrega un paso por sí mismo y también lo que queda>
después del último->
.Lo mismo vale para la dirección hacia atrás con recuentos de pasos negativos en lugar de positivos.
P.ej:
><->><-<-><-<>>->
s/->/+1/
: Comience con dirección hacia adelante, porque->
tiene la mayor prioridad.P.ej:
><+1><-<+1<-<>>+1
s/>(?=.*1)/+2/g
: Las asegura patrón de preanálisis que sólo el>
antes de que cualquier->
se convierten.P.ej:
+2<+1+2<-<+1<-<+2+2+1
s/>/+1/g
: Ahora los restantes>
están cubiertos.P.ej:
+2<+1+2<-<+1<-<+2+2+1
s/<-/-1/g
: Análogo a la dirección hacia atrás.P.ej:
+2<+1+2-1<+1-1<+2+2+1
s/<(?=.*-)/-2/g
: En el patrón de anticipación, no es necesario completar-1
el primero<-
, porque no quedan-
símbolos de dirección.P.ej:
+2-2+1+2-1-2+1-1<+2+2+1
s/</-1/g
: Los restantes<
después de los últimos<-
se convierten.P.ej:
+2-2+1+2-1-2+1-1-1+2+2+1
print eval
: Calcular y generar el resultado.P.ej:
4
fuente
-p
: 74 bytes he cambiado sus/>//g
ay/>//
guardar un byte en cada caso, que también permitió la eliminación de los parens en la expresión.Rubí, 141 bytes
Sin golf:
fuente
l=1;r=1
puede serl=r=1
y$><<o
puede serp o
. Creo que podría afeitarse mucho reemplazando esa declaración de caso con algo menos voluminoso, tal vez algo en la línea deeval %w(o-=1;l+=1 o+=1;r+=1 o-=l;l=1 o+=r;r=1)['<>LR'.index c]
l=r=1;o=0;gets.gsub('->',??).scan(/<-|./){eval"o+=#{%w[-1;l+ -l;l 1;r+ r;r][$&[-1].ord%4]}=1"};p o
podría bajar a 94 usandoruby -p
D - 243
Golfizado :
Sin golf :
fuente
C,
148141140140:
141:
148:
Con espacios en blanco:
Probablemente mucho más espacio para jugar al golf. Principalmente dejé de tratar de manipular 4 variables en los ternaries que capturaban valores (seguía saliendo más y llegando más tarde), pero no fue un mal primer paso. Pase de matriz bastante sencillo. Toma la entrada como un argumento de línea de comando, sale a través del valor de retorno.
Necesitarás la
-std=c99
bandera para compilarlo con gcc.EDITAR: Sí, es tarde, se perdieron algunas cosas obvias.
fuente
main
:main(char*x,char**v)
. Entonces tienes 138 en lugar de 140.>><-
da 0 en lugar de 1 o><->
da 0 en lugar de 2.char
y*
, y reemplaza(*(x+1)==45)?(x++,o-=l+2,l=0):(o--,l++)
con(*++x==45)?(o-=l+2,l=0):(x--,o--,l++)
.JavaScript, 136
No minificado:
Cómo funciona
Dada una entrada de cadena
s
como esta:Utiliza una expresión regular para reemplazar cada comando con un conjunto de instrucciones que modifican
z
(la posición final),l
(movimientos almacenados a la izquierda) yr
movimientos almacenados a la derecha. Cada expresión regular se realiza en orden de precedencia.Para la entrada anterior, esto se convierte
s
en:Bonita, ¿no es así?
Finalmente debemos
eval(s)
realizar las instrucciones y alertasz
que contiene la posición final.fuente
Javascript (116,
122,130)116:
122:
130:
fuente
JavaScript [217 bytes]
Probablemente se acorte un poco más ...
fuente
PHP,
284282Sin expresiones regulares.
Sin golf:
fuente
str_split($i)
(1
es el valor predeterminado para el segundo argumento). Y$i
probablemente debería ser$c
, ¿correcto?$i
): P ¡Lo arregló!Otra solución perl, 113 caracteres
Ya hay dos respuestas que superan esto, es solo por risitas. Utiliza un enfoque basado en la observación de Ilmari sobre el valor de los tokens:
Explotó un poco:
fuente