Suponga que está ensartando un hilo de Froot Loops para un collar, pulsera, cordón de zapatos o lo que sea. Hay 6 colores de bucle: r ed, o range, y ellow, g reen , b lue y p urple. Desea que su hebra comience con rojo en el extremo izquierdo y realice un ciclo en el orden del arco iris hacia la derecha, terminando con púrpura. Es decir, desea hacerlo para que su cadena pueda ser representada por la cadena roygbp
repetida varias veces (posiblemente 0).
El problema es que ya has conectado tus bucles, y no en ningún orden en particular. ¿Qué bucles debe comer y no comer para poder maximizar el número de ciclos de arco iris correctos de izquierda a derecha, con el primer bucle rojo y el último bucle púrpura?
Escriba un programa o función que tome una cadena arbitraria de los caracteres roygbp
e imprima o devuelva una cadena de la misma longitud e
en lugar de bucles para comer y n
en lugar de bucles para no comer.
Por ejemplo, si su hebra de Froot Loop se parecía a
la entrada sería
gorboypbgbopyroybbbogppbporyoygbpr
y de izquierda a derecha podemos encontrar 3 roygbp
secuencias de arcoíris completas , pero algunos de los bucles deben ser eliminados. Por lo tanto, la salida sería
eenenneennenennneeeeneennenennnnne
resultando en una cadena perfecta de 3 ciclos:
Si no hay ciclos de arco iris completos en la entrada, entonces la salida sería todo e
y la cadena termina sin bucle. Por ejemplo, la entrada proygb
tiene salida eeeeee
. Por el contrario, proygbp
tiene salida ennnnnn
.
Puede suponer que todos los hilos de entrada tienen al menos un bucle.
El código más corto en bytes gana.
r
ooygbproygbpr
también podría calificar?Respuestas:
Pyth, 31 bytes
Increíblemente ineficiente, la explicación llegará pronto.
yUlz
genera todos los subconjuntos posibles de todos los índices posibles dez
(la entrada) en orden. Por ejemplo, si la entrada esabc
:Luego
hf!
encuentra el primeroT
en la lista anterior, que:jk.DzT"roygbp"k
es falso..D
toma una cadena y una lista de índices, y elimina los elementos en esos índices. Así.D"abcd",1 3
es"ac"
. Como.D
devuelve una lista (que no debería ser el caso, se solucionará en futuras versiones de Pyth), usojk
(k
es""
) para unirla nuevamente en una cadena. La:_"roygbp"k
parte reemplaza cada instancia de un ciclo con la cadena vacía.Como la cadena vacía es falsa, los párrafos anteriores explican cómo encuentro el conjunto más pequeño de índices necesarios para comer para obtener una cadena que consta solo de ciclos.
:*lz\n_\e
luego convierte esa lista de índices en unannnneeennene
cadena.fuente
Hexagony ,
920722271 bytes¿Seis tipos diferentes de bucles de fruta, dices? Para eso fue hecha Hexagony.
De acuerdo, no lo fue. Oh dios, que me hice a mi mismo ...
Este código ahora es un hexágono de longitud lateral 10 (comenzó en 19). Probablemente podría jugar un poco más, tal vez incluso hasta el tamaño 9, pero creo que mi trabajo se hace aquí ... Como referencia, hay 175 comandos reales en la fuente, muchos de los cuales son espejos potencialmente innecesarios (o se agregaron para cancelar un comando desde un cruce).
A pesar de la aparente linealidad, el código es en realidad bidimensional: Hexagony lo reorganizará en un hexágono regular (que también es un código válido, pero todo el espacio en blanco es opcional en Hexagony). Aquí está el código desplegado en todos sus ... bueno, no quiero decir "belleza":
Explicación
Ni siquiera intentaré comenzar a explicar todas las rutas de ejecución complicadas en esta versión de golf, pero el algoritmo y el flujo de control general son idénticos a esta versión sin golf que podría ser más fácil de estudiar para los realmente curiosos después de haber explicado el algoritmo:
Honestamente, en el primer párrafo solo bromeaba a medias. El hecho de que estemos lidiando con un ciclo de seis elementos fue realmente una gran ayuda. El modelo de memoria de Hexagony es una cuadrícula hexagonal infinita donde cada borde de la cuadrícula contiene un entero de precisión arbitraria con signo, inicializado a cero.
Aquí hay un diagrama del diseño de la memoria que he usado en este programa:
El bit recto largo de la izquierda se usa como una cadena terminada en 0
a
de tamaño arbitrario que está asociada con la letra r . Las líneas discontinuas en las otras letras representan el mismo tipo de estructura, cada una rotada 60 grados. Inicialmente, el puntero de memoria apunta al borde con la etiqueta 1 , hacia el norte.El primer bit lineal del código establece la "estrella" interna de los bordes en las letras
roygbp
y establece el borde inicial en1
, de modo que sepamos dónde termina / comienza el ciclo (entrep
yr
):Después de esto, volvemos al borde etiquetado como 1 .
Ahora la idea general del algoritmo es esta:
e
en el borde con la etiqueta ? , porque mientras el ciclo no esté completo, debemos suponer que también tendremos que comer este personaje. Luego, nos moveremos alrededor del anillo hasta el siguiente personaje del ciclo.e
s en el ? bordes conn
s, porque ahora queremos que ese ciclo permanezca en el collar. Luego pasamos a imprimir código.e
yn
). Luego buscamos el borde 1 (para omitir el resto de un ciclo potencialmente incompleto) antes de pasar también al código de impresión.e
para cada carácter. Entonces se mueve a la ? borde asociado con el personaje. Si es negativo, simplemente terminamos el programa. Si es positivo, simplemente lo imprimimos y pasamos al siguiente personaje. Una vez que completamos el ciclo, volvemos al paso 2.Otra cosa que puede ser interesante es cómo he implementado las cadenas de tamaño arbitrario (porque es la primera vez que uso memoria sin límites en Hexagony).
Imagine que estamos en algún punto en el que todavía estamos leyendo caracteres para r (para que podamos usar el diagrama tal como está) y un [0] y un 1 ya se han llenado de caracteres (todo el noroeste de ellos sigue siendo cero) ) Por ejemplo, quizás acabamos de leer los dos primeros caracteres
og
de la entrada en esos bordes y ahora estamos leyendo ay
.El nuevo carácter se lee en el en el borde. Usamos el ? borde para verificar si este carácter es igual a
r
. (Aquí hay un truco ingenioso: la hexagonía solo puede distinguir entre positivo y no positivo fácilmente, por lo que verificar la igualdad por sustracción es molesto y requiere al menos dos ramas. Pero todas las letras son menos que un factor de 2 entre sí, por lo que podemos comparar los valores tomando el módulo, que solo dará cero si son iguales).Debido a que
y
es diferente der
, movemos el borde (sin marcar) a la izquierda de adentro y copiamosy
allí. Ahora nos movemos más alrededor del hexágono, copiando el personaje un borde más cada vez, hasta que tengamosy
el borde opuesto a in . Pero ahora ya hay un carácter en un [0] que no queremos sobrescribir. En cambio, "arrastramos"y
alrededor del siguiente hexágono y verificamos un 1 . Pero también hay un personaje allí, así que vamos a otro hexágono más lejos. Ahora un [2] sigue siendo cero, así que copiamos ely
en ello. El puntero de memoria ahora retrocede a lo largo de la cuerda hacia el anillo interno. Sabemos cuándo hemos llegado al comienzo de la cadena, porque los bordes (no marcados) entre a a [i] son todos cero, mientras que ? es positivo.Probablemente sea una técnica útil para escribir código no trivial en Hexagony en general.
fuente
Hexagonía , 169 bytes.
Me inspiró la respuesta de Martin Büttner (también es su esolang) y decidí que puedo hacerlo en la talla 8. (Estoy convencido de que también es posible en la talla 7, pero es muy difícil. Ya he pasado cuatro días sin -Detente en esto.)
Presentado hexagonalmente:
El programa en realidad no usa la
#
instrucción, así que he usado ese carácter para mostrar qué celdas están realmente sin usar. Además, cada celda no operativa que se atraviesa en una sola dirección es un espejo (por ejemplo,_
si se atraviesa horizontalmente), por lo que sabe que todos los.
caracteres se atraviesan en más de una dirección.Explicación
Al principio, ejecutamos la secuencia de instrucciones
r''o{{y''g{{b''p"")"
. Estos están esparcidos un poco al azar en el código porque los introduje después de escribir todo lo demás. Yo uso]
para cambiar al siguiente puntero de instrucción varias veces; de esta manera puedo teletransportarme esencialmente a otra esquina del hexágono. Todo el resto del programa se ejecuta mediante el puntero de instrucción # 3.La memoria ahora se ve de la siguiente manera, con los bordes importantes etiquetados con nombres que usaré en esta explicación:
Los bordes etiquetados significan lo siguiente:
in
: Utilizamos este borde para almacenar un personaje que leemos de STDIN.%
: Utilizamos este borde para realizar una operación de módulo en el carácter de stdin (in
) y el carácter actual “válida” (r
,o
, etc.), los cuales serán0
si son iguales. Robé este truco de la respuesta de Martin Büttner, pero el resto del programa es diferente.#
: Mientras leamos caracteres "inválidos" (es decir, colores que necesitamos comer), incrementaremos este borde. Por lo tanto, este borde recuerda cuántose
s necesitamos generar más tarde.r?
: Siempre0
excepto donde está la parter
(roja). Esto nos dice cuándo hemos completado un ciclo.El programa procede así:
#
. De lo contrario, pase al siguiente segmento de la memoria en el sentido de las agujas del reloj.r?
es positivo, hemos hecho una revolución completa. Realice una ronda completa y produzca#
e
sy 1n
por segmento. Esto hace que cada uno#
vuelva a0
. (Ele
se coloca en un borde sin etiquetar, pero para eln
mal uso del#
borde, que configuramos para0
usar después una*
(multiplicación), lo que funciona porque sabemos que todos los%
bordes son cero en este momento).#
+1e
s hasta que regrese a donder?
es positivo, luego salga.Después de una ejecución completa, la memoria se ve aproximadamente como sigue al final. Notará los bordes que contienen
101
(el código ASCII dee
); uno de losin
bordes es-1
(EOF); todos los#
bordes están en 0; y el puntero de memoria termina en elr?
borde positivo .fuente
Retina ,
1488579 bytesPuede ejecutar esto desde un único archivo fuente con el
-s
indicador de intérprete.Explicación
Primero saquemos las cosas simples del camino:
Se agrega
#roygbp
al final de la cadena, que usaremos para calcular el ciclo de letras dinámicamente.El siguiente paso (largo) determina qué bucles mantener y los reemplaza
n
. Veremos cómo funciona esto en un momento.Esto elimina nuestro asistente de búsqueda al final de la cadena.
Esto reemplaza todos los personajes que no fueron reemplazados en el segundo paso con
e
, completando la transformación.Ahora volvamos al segundo paso.
La estructura básica utiliza un truco, que descubrí hace unos meses para reemplazar los caracteres seleccionados en una coincidencia global:
donde
...
corresponde a un patrón arbitrariamente complejo. Esto coincide con el carácter con el que se va a reemplazar.
y luego comienza una mirada hacia atrás (que debe leer de derecha a izquierda). La mirada atrás captura todo, hasta el personaje coincidente, en un grupoprefix
. Luego cambia a una mirada hacia adelante , que ahora comienza desde el principio de la cadena y puede contener un patrón complejo. Después del carácter que queremos reemplazar en ese patrón, colocamos una mirada opcional detrás , que verifica si elprefix
grupo coincide aquí. Si lo hace, captura una cadena vacía en elflag
grupo. Si no lo hace, porque es opcional, no afecta el estado del motor regex en absoluto y se ignora. Finalmente, una vez que la búsqueda anticipada coincide con éxito, solo queda el\k<flag>
final, que solo coincide si la bandera se estableció en algún momento durante el cálculo.Ahora eliminemos un poco la expresión regular larga utilizando grupos con nombre y el modo de espacio libre:
Espero que reconozca el esquema general de arriba, por lo que solo necesitamos ver lo que completé
...
.Queremos capturar al siguiente personaje del ciclo en el grupo
char
. Hacemos esto también recordando la cadena desde#
el carácter actual encycle
. Para obtener el siguiente personaje, usamos una búsqueda anticipada para buscar el#
. Ahora intentamos unircycle
y luego unir el siguiente personajechar
. Esto generalmente será posible, a menos quechar
sea el último personajep
. En este caso,\k<cycle>
coincidirá con el resto de la cadena y no quedará ningún personaje para capturarchar
. Por lo tanto, el motor retrocede, omite la referenciacycle
y simplemente coincide con el primer carácterr
.Ahora que tenemos el siguiente personaje en el ciclo
char
, buscamos la próxima posible aparición de ese personaje con.*?\k<char>
. Estos son los caracteres que queremos reemplazar, por lo que colocamos elprefix
cheque después. Estos pasos (encontrar el siguientechar
en el ciclo, buscar la próxima aparición del mismo, establecer la marca si es apropiado) ahora simplemente se repiten con a+
.En realidad, eso es todo para encontrar la subsecuencia cíclica, pero también debemos asegurarnos de que terminemos con a
p
. Esto es bastante fácil: solo verifique que el valor almacenado actualmentechar
coincidap
con al final de la cadena con.*\k<char>$
. Esto también asegura que nuestra cadena de búsqueda no se use para finalizar un ciclo incompleto, porque necesitamos el seguimientop
de esta verificación.fuente
Python 2,
133 130 126121 bytesEl primer ciclo obtiene ciclos, y el segundo elimina un ciclo incompleto.
Guardado 3 bytes gracias a JF y 5 de DLosc
fuente
r
yn
asír=n=''
:?R=r.count
no funciona ya que las cadenas son inmutables, porR
lo que lo es''.count
incluso cuandor
se cambia.Perl 5,
7665 bytesUna pizca de expresiones regulares puras sin diluir.
Primero encuentra lo que no se debe comer. Lo que queda es comestible.
Prueba
fuente
[^o]*
etc., ¿puedes usar.*?
(cuantificador no codicioso)?\s
lugar de\n
en la clase de caracteres negativos de la primera versión.r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p
n$1n$2n$3n$4n$5n
[^n\s]
e
(4 archivos, 57 bytes).Lua, 101 bytes
Utiliza patrones de Lua de forma creativa; Creo que es un enfoque interesante.
Reemplaza todos los caracteres no comidos con "*" s, reemplaza todos los caracteres alfanuméricos con "e" s, luego reemplaza todos los "*" s con "n" s.
fuente
Javascript (ES6), 118
Fiddle probado en Firefox. Escuché que Chrome admite funciones de flecha ahora, pero aún no lo he probado en Chrome.
Sin golf:
fuente
...
notación.gawk, 96
Construye el patrón de búsqueda
"([^r]*)r([^o]*)o([^y]*)y([^g]*)g([^b]*)b([^p]*)p"
y el reemplazo"\\1n\\2n\\3n\\4n\\5n\\6n"
. Después de ese reemplazo, declara todo alimento ("e"), eso no es parte de un arco iris completo.Esta combinación garantiza automáticamente que no se dañará ningún arco iris durante esta operación, y que no se muestre ningún arco iris cortado al final.
fuente
Pyth, 42 bytes
Pruébelo en línea: demostración
fuente
CJam, 41 bytes
Enfoque de fuerza bruta que prueba todas las variaciones de comer / no comer y selecciona la que da como resultado el collar más largo y válido.
Pruébelo en línea en el intérprete de CJam .
fuente
CJam, 50 bytes
Pruébalo en línea
Esto es un poco más largo que algunas de las otras presentaciones, pero es muy eficiente con la complejidad lineal. Escanea a través de la cadena de entrada y coincide con los caracteres uno por uno.
La parte central del algoritmo es en realidad bastante compacta. Aproximadamente la mitad del código es para eliminar el ciclo incompleto al final.
fuente
C90, 142-146 bytes (hasta 119, dependiendo)
Opera en tiempo lineal para comer eficientemente esos bucles de frutas que no pueden ser parte de un bonito arco iris. Luego, un postproceso mata cualquier bucle parcial al final.
Aquí hay cuatro versiones:
Versión 1 (146 bytes), llame con
[name] [string]
:main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Versión 2 (142 bytes), llame con
[name] [string] [rainbow order]
:main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Esto le permite definir su propio orden de arco iris con los colores que desee, siempre que no lo sean
n
oe
. ¡Esto realmente hace que el código sea más corto!Versión 3 (123 bytes), llame como la versión 1: ¡
main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
Esta le brinda la mayor cantidad posible de su arco iris! ¡Los arcoíris finales incompletos muestran promesa! ¡No debemos comerlos!
Versión 4 (119 bytes), llamada como la versión 2: ¡
main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
Igual que la versión 3, pero TIPOS DE ARCO IRIS!
Limitación menor: la máquina debe tener caracteres firmados (el caso general) y la cadena debe ser bastante corta. Emite un final
\n
para mayor claridad.La versión 1 es la única que claramente pasa los requisitos, aunque la versión 2 es discutible. Las versiones 3 y 4 son una interpretación menos correcta (pero aún divertida) de la pregunta.
fuente
Pyth, 38 bytes
Sé que esto es significativamente más largo que la respuesta de orlp, pero esta se ejecuta en tiempo lineal: o)
Pruébalo aquí .
En resumen, este programa reemplaza todos los caracteres después de la 'p' final con espacios, luego itera sobre cada carácter en la cadena resultante. Si el personaje es el siguiente en la secuencia 'roygbp', imprima 'n', de lo contrario imprima 'e'.
Me costó encontrar una forma más corta de procesar la cadena de entrada.
_>_zJ
en particular se siente incómodo, pero<Jz
no da la cadena requerida cuandoJ == 0
, es decir, cuando la entrada termina con una 'p'.fuente
Haskell, 138 bytes
g
lo hace.fuente
f
yz
como infijo:'n'%'n'='n'
etc. Además, algunos paréntesis en la definición deg
se pueden eliminar con$
.Javascript (ES6),
8582 bytesLa regla "el collar debe terminar en púrpura" fue originalmente un gran obstáculo, ya que aumentó mi puntaje de 66 a 125, pero encontré un camino más corto (¡afortunadamente!).
Explicación:
Este código recorre cada carácter en la entrada y reemplaza cada uno con
r
oe
con esta lógica:p
, Y el personaje es el siguiente en el arco iris, manténgalo (reemplácelo conn
).e
).Sin golf:
Sugerencias bienvenidas!
fuente
Python 2, 254 bytes
Bucles!
Disculpe el juego de palabras. :PAGS
fuente