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 I
y seguimos las mismas reglas (aplicamos la regla de conteo de dígitos a los caracteres en su lugar, así que leemos IVX
como en one one, one five, one ten
lugar de one four, one ten
o 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
N
números de esta secuencia (cualquier separador razonable está bien, así como["I", "II", "III", ...]
N
Té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 XCV
lugar 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 5
aparecer en la secuencia, por lo que no tiene que preocuparse por la ambigüedad de los números romanos (números 1
- 8
son 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
-p
Ejecutar 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
I
como1
yV
como 9:Al dividir la parte anterior
->
por el dígito repetido, esto se convierte en:Así que ahora el original repetido
V
ya 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
IIIIII
a laVI
derecha, aunque no es necesario aquí)Todo lo que queda es inicializar la variable de trabajo
1
para el índice 0, repetir esta transformación en un bucle y al final reemplazar1
porI
y9
porV
1
,9
y182
es 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
Nest
itera 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 serieTally
y 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. ElFlatten
comando reduce toda la lista de listas a una lista unidimensional.Aquí está la versión inicial:
fuente
@@@
lugar de/@
puede usar#
y en#2
lugar 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?Characters
hilos 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 índicen
para el quen
contiene la generación thVVV
. Si eso seVVV
rompe,(a)V VV
entonces 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
m
quem
contiene la generación th...IIIIII...
. Tenga en cuenta que no puede haber dígitos distintos deI
yV
en la cadena, porque ninguna generación anterior ha tenido una ejecución de nueveI
so nueveV
s. Como máximo, cuatro de losI
s provienen de una serie deI
s en la cadena anterior, por lo que la sección correspondiente de la cadena anterior debe estar...IIIVV...
dando... IIII IIV ...
. Como laVV
generaciónm-1
no proviene deVVVVV
(ver lema), la segundaV
debe ser una longitud de dígitosI
, por lo que en generaciónm-1
sí...IIIVVI...
. Y dado que queremos que laI
s inicial déIIII
y noIVI
oVI
, 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 laVV
de gen.m-1
debe analizarse como(a)V V(I)
.Supongamos que tomamos
a=2
: en(...V)?I IIV VI...
realidad debe ser...VI IIV VI...
, aunque ese liderazgoV
podrí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 segundoV
debe 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ónm
es la primera con una carrera de seisI
s, debe ser(...V)? II IV VI...
, por lo que esa generaciónm-2
es(...V)? I V IIIII...
....VIVIIIII...
es imposible: sin embargo, elegimos interpretar el segundoV
y terminamos con dos pares consecutivos (longitud de ejecución, dígitos) con el mismo dígito.Por lo tanto, la generación
m-2
debe ser^IVIIIII...
analizada como^IV IIII I(V)...
o^IV III II(V)...
. Estos dan respectivamente generaciónm-3
como^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
VIIIV
oVIIVV
. 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*a
Guarda un byte.i
(como enfor i in range(...)
). Traté de incursionar con,exec
pero esto escapó1
en el método 'sub' parece estar estropeando el código, no he podido encontrar una solución.range
R,
110107 Bytesas.roman
combinado conrle
hace 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