Descripción del desafío
Hemos tenido algunos desafíos relacionados con la secuencia de mirar y decir . Recordatorio rápido:
- La secuencia comienza con
1, - Los términos posteriores de esta secuencia se generan enumerando cada grupo de dígitos repetidos en el término anterior,
Entonces, los primeros términos son:
1 "one"
11 "one one" (we look at the previous term)
21 "two ones"
1211 "one two, one one"
111221 "one one, one two, two ones"
312211 "three ones, two twos, one one"
Ahora hagamos lo mismo, pero use números romanos en su lugar. Comenzamos con Iy seguimos las mismas reglas (aplicamos la regla de conteo de dígitos a los caracteres en su lugar, así que leemos IVXcomo en one one, one five, one tenlugar de one four, one teno de alguna otra manera):
I "one"
II "one one"
III "two ones" = "II" + "I"
IIII "three ones" = "III" + "I"
IVI "four ones" = "IV" + "I"
IIIVII "one one, one five, one one"
IIIIIVIII "three ones, one five, two ones" = ("III" + "I") + ("I" + "V") + ("II" + "I")
Dado un entero positivo N, ya sea:
- Imprime los primeros
Nnúmeros de esta secuencia (cualquier separador razonable está bien, así como["I", "II", "III", ...] NTérmino de salida de esta secuencia (puede estar indexado a 0).
Recuerde hacer su código lo más corto posible, ya que este es un desafío de código de golf .
EDITAR: Creo que siempre hay una forma estándar / preferida de expresar enteros como números romanos, (como 95-> en XCVlugar de VC). Un par de convertidores de números romanos que encontré en línea corroboran mi opinión. En caso de duda, utilice un convertidor en línea , ya que enumerar todos los casos límite posibles y las reglas específicas de escribir números romanos no es el punto de este desafío.
Edit2: @PeterTaylor y @GregMartin señalaron que sólo los números menores o iguales a 5aparecer en la secuencia, por lo que no tiene que preocuparse por la ambigüedad de los números romanos (números 1- 8son I, II, III, IV, V, VI, VII, y VIII)
fuente

4/IV/IIII? O95/XCV/VC? Puede que no siempre haya una forma única de expresar un número entero, pero estoy bastante seguro de que siempre hay uno preferido (estándar): corrígeme si me equivoco.Respuestas:
Perl, 49 bytes
Incluye +1 para
-pEjecutar con el índice basado en 0 en STDIN, p. Ej.
ecce.pl:Las fórmulas mágicas son tan mágicas.
Normalmente, usaría
($_=//)x$'para hacer que el control de bucle sea un byte más corto, pero la puntuación en este sitio le da una desventaja de 2, por lo que termina 1 byte más. En perls más antiguos, puede soltar el espacio antesfor. Algunas versiones de perl te obligan a agregar una final;para cerrar la transliteración. Pero lo que se da arriba es el código que funciona en mi sistema.Explicación
Trabajando hacia atrás desde la solución al código:
Las transformaciones de cadena que necesitamos:
Cada reemplazo termina con el carácter repetido. Obtendré una secuencia de los mismos caracteres usando regex
/(.)\1*/, por lo que esto se puede hacer agregando$1. La parte anterior a la->está en$&. Con eso todavía necesito:Escribe
Icomo1yVcomo 9:Al dividir la parte anterior
->por el dígito repetido, esto se convierte en:Así que ahora el original repetido
Vya no es una excepción. Entonces quiero una expresión que haga que esto suceda:Y esto se puede hacer mediante un simple módulo 182:
(Esto incluso llega
IIIIIIa laVIderecha, aunque no es necesario aquí)Todo lo que queda es inicializar la variable de trabajo
1para el índice 0, repetir esta transformación en un bucle y al final reemplazar1porIy9porV1,9y182es la única combinación de parámetros para la que funciona esta fórmula simple.fuente
Mathematica,
1139083 bytes¡Gracias a Martin Ender por las sugerencias que redujeron la longitud en más del 25%!
Mostrando los comandos de alto nivel en Mathematica.
Una función pura, que toma un argumento N y genera el enésimo elemento de esta secuencia (indexada en 0), como una lista de caracteres. Extender un poco:
El exterior
Nestitera la función de cuatro líneas del medio, comenzando en{"I"}, N veces. La línea 4 divide la lista de caracteres del número romano de entrada en series de caracteres similares, cuenta cada serieTallyy coloca las cuentas antes de los caracteres que están contando. La línea 3 representa los recuentos como números romanos, luego divide esos números romanos en listas de caracteres. ElFlattencomando reduce toda la lista de listas a una lista unidimensional.Aquí está la versión inicial:
fuente
@@@lugar de/@puede usar#y en#2lugar de#[[1]]y#[[2]]. Además, las listas de caracteres son tipos de cadena aceptables, por lo que puede trabajar con ellos y evitar su usoCharacters@.@@@atajo similar! En cuanto a las listas de caracteres que son tipos de cadena aceptables (lo que estoy de acuerdo acortaría el código): ¿hay alguna publicación en este sitio que me pueda señalar que describa los estándares de la comunidad?Charactershilos automáticamente para que pueda usar@,Reverse@#&por supuesto , es lo mismo que simpleReverse, en cuyo caso tampoco necesita esos paréntesis. Y la notación de prefijo (en el caso deFlatten) no guarda nada si necesita agregar paréntesis para que funcione. Combinando todos esos:Nest[Flatten[Characters@{RomanNumeral@#,#2}&@@@Reverse@@@Tally/@Split@#]&,{"I"},#]&CJam (
3330 bytes)Demostración en línea
La clave para la corrección de la implementación es el siguiente teorema:
Si la primera generación es
I, ninguna longitud de ejecución es nunca mayor que cincoLema: si la primera generación es
I, ninguna cadena contiene nuncaVVV. La prueba es por contradicción. Supongamos que hay un primer índicenpara el quencontiene la generación thVVV. Si eso seVVVrompe,(a)V VVentonces la conversión de la generación anterior es mala: debería haberlo sido(a+5)V. Así debe serVV V(d), y la generación anterior contenidaVVVVV, contradiciendo la elección den.Ahora, supongamos que hay un primer índice
mquemcontiene la generación th...IIIIII.... Tenga en cuenta que no puede haber dígitos distintos deIyVen la cadena, porque ninguna generación anterior ha tenido una ejecución de nueveIso nueveVs. Como máximo, cuatro de losIs provienen de una serie deIs en la cadena anterior, por lo que la sección correspondiente de la cadena anterior debe estar...IIIVV...dando... IIII IIV .... Como laVVgeneraciónm-1no proviene deVVVVV(ver lema), la segundaVdebe ser una longitud de dígitosI, por lo que en generaciónm-1sí...IIIVVI.... Y dado que queremos que laIs inicial déIIIIy noIVIoVI, está precedido por el inicio de la cadena o por unV.Si tenemos
(...V)?IIIVVI...en generaciónm-1, ¿qué tenemos en generaciónm-2? Ya hemos observado que laVVde gen.m-1debe analizarse como(a)V V(I).Supongamos que tomamos
a=2: en(...V)?I IIV VI...realidad debe ser...VI IIV VI..., aunque ese liderazgoVpodría ser parte deIV; así que en la generación anterior tenemos(...V)? IIII VV IIIII...o(...V)? IIIII VV IIIII. De cualquier manera nos encontramos con problemasVVIIIII: el segundoVdebe ser una longitud de ejecución, pero luego...VI IIII...requiere un par siguiente (longitud de ejecución, dígito) con el mismo dígito.Lo que debe ser
a=1:(...V)?II IV VI.... Dado que la generaciónmes la primera con una carrera de seisIs, debe ser(...V)? II IV VI..., por lo que esa generaciónm-2es(...V)? I V IIIII.......VIVIIIII...es imposible: sin embargo, elegimos interpretar el segundoVy terminamos con dos pares consecutivos (longitud de ejecución, dígitos) con el mismo dígito.Por lo tanto, la generación
m-2debe ser^IVIIIII...analizada como^IV IIII I(V)...o^IV III II(V).... Estos dan respectivamente generaciónm-3como^V III V ...o^V II VV....Pero si miramos el inicio de las cadenas que comienzan con la primera que comienza
V, obtenemos un ciclo:y entonces ninguna generación comienza con ninguno
VIIIVoVIIVV. Debemos concluir que no existe talm.Disección
fuente
Python 3, 195 bytes
Hay una gran cantidad de bytes desperdiciados en los números romanos, por lo que es probable que haya algo de golf allí.
Gracias a @ El'endiaStarman, @ Sherlock9 y @Shooqie
Ideone it!
fuente
for v,i in(5,"V"),(4,"IV"),(1,"I")for v,i in(5,"V"),(4,"IV"),(1,"I"):a,x=divmod(x,v);r+=i*aGuarda un byte.i(como enfor i in range(...)). Traté de incursionar con,execpero esto escapó1en el método 'sub' parece estar estropeando el código, no he podido encontrar una solución.rangeR,
110107 Bytesas.romancombinado conrlehace esto fácil. Abuso de alcance y comportamiento de gato integrado de<<-guarda unos pocos bytes.Toma N de la consola. Emite los primeros 2 a N términos de secuencia (que creo que está dentro de las especificaciones ...)
fuente
JavaScript (ES6), 107
Función recursiva que devuelve el enésimo término basado en 0
Prueba
fuente
Perl 6 , 62 bytes
Función anónima que acepta un índice basado en cero.
Hace uso del hecho de que no se necesitan números romanos superiores a 5, porque los únicos grupos de dígitos que se pueden repetir son:
( pruébalo en línea )
fuente