Escriba un programa que tome una cadena de longitud impar que contenga solo los caracteres .
y :
. Con la ayuda de una pila inicialmente vacía , genere un número a partir de esta cadena de la siguiente manera:
Para cada carácter c en la cadena (de izquierda a derecha) ...
- Si c es
.
y la pila tiene menos de 2 elementos, presione 1 en la pila. - Si c es
.
y la pila tiene 2 o más elementos, saque los dos valores superiores de la pila y empuje su suma a la pila. - Si c es
:
y la pila tiene menos de 2 elementos, presione 2 en la pila. - Si c es
:
y la pila tiene 2 o más elementos, saque los dos valores superiores de la pila y empuje su producto a la pila.
El número resultante es el valor en la parte superior de la pila. Su programa debe imprimir este número en stdout (con una nueva línea final opcional).
(Un pequeño análisis muestra que solo queda un número a menos que la cadena tenga una longitud uniforme, por lo que los ignoramos. De hecho, la pila nunca tiene más de 2 elementos).
Por ejemplo, el número para ::...:.:.
es 9:
2 1 2 2 /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9 \
: : . . . : . : . <-- string, one character at a time
Como verificación de cordura, aquí están los números para todas las cadenas de longitud 1, 3 y 5:
. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8
El programa más corto en bytes gana. Tiebreaker es una publicación anterior.
- Puede suponer que la entrada siempre es válida, es decir, una cadena que solo contiene
.
y:
cuya longitud es impar. - En lugar de escribir un programa, puede escribir una función que tome una cadena válida e imprima o devuelva el número generado.
Respuestas:
CJam,
27 24 2322 bytesMuy claro. Uso la pila de CJam como la pila mencionada en la pregunta;)
Algoritmo
Primero veamos el código ASCII para
.
y:
.Dado que en CJam, el índice se ajusta, veamos si podemos usar estos valores directamente para obtener la operación deseada.
Por lo tanto, no puedo simplemente usar los códigos ASCII en una cadena de operación de 4 longitudes. Probemos algunos otros valores.
que en una cuerda de 4 longitudes se reduce a
Puedo usar esta operación mod 10 pero costará 2 bytes. Probemos otra cosa
¡Bien !, ahora solo restamos 1 para la condición del tamaño de la pila para obtener los índices
0, 1, 2 and 3
y usar una5
matriz de longitud ("1+2* "
) como un caso de cambio. El último espacio es solo un relleno para que sea de longitud 5. Esto es solo 1 byte adicional en comparación con la operación de modificación.Pruébalo en línea aquí
1 byte guardado gracias a cosechy
fuente
> <> (Pez) , 33 bytes
Bastante sencillo con pequeños trucos / optimizaciones.
Explicación:
i
= punto de código de la siguiente entrada de caracteres,-1
si se alcanza el final de la entrada;a
= 10;b
= 11;)
=>
i
punto de código de la primera entrada char,b%1-
top_of_stack mod 11 - 1
máscaras48 ('.') , 56 (':')
para1 , 2
i:1+?\~n;
si se alcanza el final de la entrada, imprima el último resultado y finaliceb%1-
entrada de máscara a1 , 2
0@
empujar0
debajo del número dosi5a*)
lea la siguiente entrada y enmascarela para0 , 1
compararla con50
1
(':'
) multiplica los dos elementos superiores creando una pila [0 producto][0 sum]
o[0+product=product]
40.
saltar (bucle) de vuelta a la posición(4,0)
, nuestro punto4
,i:1+?\~n;
fuente
Haskell,
7365 bytesUna solución sencilla, utilizando el hecho de que la pila nunca tiene más de 2 elementos.
fuente
C, 104 bytes
Bueno, esto es demasiado largo.
fuente
Pyth,
2524 bytesTengo una idea al estudiar la solución de @ isaacg. Pero estoy usando una pila.
Demostración en línea o conjunto de pruebas
Explicación
Lo primero que hago es convertir la cadena de entrada en 0s y 1s. A
"."
se convierte en a0
, a":"
en a1
.Luego reduzco esta lista de números:
fuente
JavaScript (ES6), 65
Solo usamos 2 celdas de nuestra pila.
Comience a poner un valor en s [0].
Luego, en cada posición impar (contando desde 0) en la cadena de entrada, ponga un valor en s [1].
En cada posición par, ejecute un cálculo (sumar o multiplicar) y almacenar el resultado en s [0].
Así que olvídate de la pila y usa solo 2 variables, a y b.
Una prueba rápida
Salida
fuente
f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
Pyth, 27 bytes
¿Un montón? ¿Quién necesita una pila?
Demostración.
fuente
Retina ,
1057573 bytesMi primer programa de retina! (Gracias a Martin Büttner por guardar 2 bytes, sin mencionar la invención del idioma en primer lugar).
Cada línea debe ir en un archivo separado; o puede ponerlos todos en un archivo y usar la
-s
bandera. La<empty>
notación representa un archivo / línea vacío.Inspirado por la respuesta de mbomb007 , pero adopto un enfoque algo diferente. Una diferencia importante es que construyo la pila frente a la cadena de puntos (con la parte superior de la pila hacia la derecha). Esto facilita la conversión de símbolos a los números correspondientes en el lugar. También lo uso en
a
lugar de1
intercambiarlo solo al final, para evitar analizar la ambigüedad en secuencias como$1a
. Si una respuesta comoaaaaaa
es aceptable como un número unario, las últimas dos líneas / archivos podrían eliminarse para guardar 4 bytes.Explicación:
Coincide si hay 0 o 1 elementos en la pila (
(a+;)?
) seguidos de un punto (\.
); si es así, reemplaza el punto cona;
(es decir, empuja un 1).Coincide si hay 0 o 1 elementos en la pila seguidos de dos puntos. Si es así, reemplaza el colon con
aa;
(es decir, empuja un 2).Coincide si hay dos elementos en la pila seguidos de un punto. Elimina el punto y el punto y coma entre los elementos, y así los agrega.
Coincide si hay dos elementos en la pila, la parte superior de los cuales es un 2, seguido de dos puntos. Elimina los dos puntos y el 2 y repite el otro número dos veces, multiplicándolo así por 2.
La expresión regular coincide si hay dos elementos en la pila, la parte superior de los cuales es un 1, seguido de dos puntos. Elimina los dos puntos y el 1, dejando el otro número sin cambios (es decir, multiplicado por 1).
)`
indica el final de un ciclo. Si se realizó algún cambio en la cadena, el control vuelve a la parte superior del programa y ejecuta las sustituciones nuevamente. Si la cadena ha dejado de cambiar, hemos reemplazado todos los puntos y dos puntos, y todo lo que queda es la limpieza ...Elimina el punto y coma restante.
Transforma todas las a en 1. Nuevamente, si los números unarios pueden usar cualquier símbolo, este paso es innecesario.
fuente
Moho, 170 caracteres
Más pruebas de que Rust es absolutamente terrible en el golf. Código completo sin golf:
Aquí hay un truco interesante que utilicé en este. Puede eliminar un carácter en una instrucción if / else haciendo que devuelvan un valor que se descarta inmediatamente, lo que significa que solo necesita un punto y coma en lugar de dos.
Por ejemplo,
se puede cambiar a
que salva a un personaje al afeitarse un punto y coma.
fuente
Haskell,
888179 BytesParece que alguien me dio en el blanco en una solución de Haskell, no solo eso, su solución es más corta que la mía. Eso es malo, pero no veo ninguna razón para no publicar lo que se me ocurrió.
fuente
APL (50)
Estoy en una gran desventaja aquí, porque APL no es un lenguaje basado en pila. Sin embargo, finalmente pude abusar de la reducción para acortar el programa.
La función interna toma un 'comando' a la izquierda y una pila a la derecha, y lo aplica, devolviendo la pila. La función externa lo reduce sobre la cadena, comenzando con una pila vacía.
Explicación:
(⌽⍵),⊂⍬
: la lista inicial para reducir más.⊂⍬
es una lista vacía en caja, que representa la pila,(⌽⍵)
es el reverso de la entrada. (La reducción se aplica de derecha a izquierda sobre la lista, por lo que la cadena se procesará de derecha a izquierda. Invertir la entrada de antemano hace que aplique los caracteres en el orden correcto).{
...}
: la función interna. Toma la pila a la derecha, un personaje a la izquierda, y devuelve la pila modificada.F←'.:'⍳⍺
: el índice del carácter en la cadena.:
, será 1 o 2 dependiendo del valor.2>⍴⍵:F,⍵
: Si 2 es mayor que el tamaño actual de la pila, simplemente agregue el valor actual a la pila.⋄
: de lo contrario,2↓⍵
: elimina los dos elementos superiores de la pila(
...)/2↑⍵
: reduce una función dada sobre ellos y agrégala a la pila.⍎F⌷'+×'
: la función es+
(suma) o×
(multiplicación), seleccionada porF
.⊃
: finalmente, devuelve el elemento más alto en la pilafuente
Ruby - 96 caracteres
La pieza interesante aquí es
eval
.Aparte de eso, estoy asumiendo que después del primer carácter, la pila siempre irá 2, matemáticas, 2, matemáticas, ... Esto me permite usar menos código agarrando dos caracteres a la vez, nunca tengo que calcular averiguar si un personaje es matemático o número. Es posicional.
Sin golf:
fuente
TI-BASIC,
7873706966 bytesTI-BASIC es bueno en líneas simples, porque el cierre de paréntesis es opcional; por el contrario, es un lenguaje pobre donde se requiere almacenar múltiples valores porque el almacenamiento en una variable requiere de dos a cuatro bytes de espacio. Por lo tanto, el objetivo es escribir tanto en cada línea como sea posible. TI-BASIC también es horrible (para un lenguaje tokenizado) en la manipulación de cadenas de cualquier tipo; incluso leer una subcadena es largo.
Los trucos incluyen:
int(e^([boolean]
en lugar de1+(boolean
; ahorra un bytefuente
".:.":prgmDOTTY
, guardar 4 bytes.1+(":"=sub(Ans,1,1
Ir,
129 129115112 bytes(un poco) no golfista:
Pruébelo en línea aquí: http://play.golang.org/p/B3GZonaG-y
fuente
Pitón 3, 74
Primero transforma la lista de entrada en una secuencia de 1 y 2, tomando el primer valor como valor inicial
x
. Luego, saca dos elementos a la vez desde el frentes
, toma el primer número y suma o multiplica con el número actual en función de si el segundo es 1 o 2.fuente
bueno, esta es una operación tan fácil, sofisticada por el operador (intencionalmente)
es sólo ...
Código: C (80 bytes)
entrada
longitud = 2n + 1 vector V de tipo char '.' o ':'
Salida
un entero k
Función
Simulación:
pruébalo aquí
fuente
*(V-1)
) es cero?Retina,
181135129 bytesCada línea debe estar en un archivo separado.
<empty>
representa un archivo vacío La salida está en Unary.Cuando${0}1
se usa, las llaves se separan$0
del1
, de lo contrario, sería$01
el primer grupo coincidente. Intenté usarlo$001
, pero parece que esto no funciona en el sabor .NET de regex.Editar: encontrado que
$&
es lo mismo que$0
.En pseudocódigo, esto sería esencialmente un ciclo do-while, como se ve a continuación. Presiono el primer número, luego repito: presiono el segundo número, elimino la operación (instrucción), hago matemáticas, elimino el op. Continuar en bucle. Tenga en cuenta que cuando aparece una operación, esto también eliminará el espacio después de que se hayan completado todas las instrucciones.
Comentado:
fuente
(:)(.*)
->$1$2
, que estoy bastante seguro de que podría ser solo(:.*)
->$1
(ya que mantiene los dos grupos en el mismo orden y no hace nada más con ellos) )Python 3, 122 bytes
Sin golf:
En python, hace referencia al índice de una lista como esta:
Puede poner un valor booleano en eso,
True
es1
yFalse
es0
.Pruébalo en línea aquí
fuente
Perl, 77 bytes
expandido:
La
@o
matriz asigna dígitos a los operadores. Luego sustituimos pares de dígitos con el operador apropiado, reordenado a infijo. La expresión regular comienza por\B
lo que no coincidimos con el primer personaje. El resultado des///g
nos dice cuántos padres abiertos necesitamos al principio. Luego, cuando hemos reunido la expresión infija completa, podemos evaluarla. (Retirareval
si desea ver la expresión en su lugar).Aquí está el arnés de prueba que utilicé para verificar los resultados:
La entrada es la lista de expresiones dotty y sus valores (provistos en la pregunta) y la salida es pares de {real, esperado}.
fuente