Crea una contracadena ilimitada


11

Una contracadena es una especie de datos de prueba autodescriptivos que se utilizan en las pruebas de software. No estoy seguro de que fuera realmente inventado por James Bach , pero lo sé a partir de ahí.

La idea es la siguiente: los datos de prueba contienen muchos asteriscos ( *). El número delante del asterisco le indica cuánto tiempo duran los datos de la prueba en ese punto. Si necesita conocer una posición en los datos de prueba que no es un asterisco, busque el último asterisco, mire el número anterior y agregue el número de dígitos que siguen.

La secuencia comienza así:

2*4*6*8*11*14*17*20*23*
             ^

Como puede ver, el asterisco marcado está en la posición 14.

Si un archivo se trunca de la siguiente manera

[...]2045*20

entonces puede deducir que hay un límite de 2047 caracteres en algún lugar (2045 donde el asterisco es más 2 para 2y 0).

Es su tarea crear el programa más corto (esto es ) que genera (std :: out o file o lo que sea) una cadena de prueba larga arbitraria de ese formato. La longitud en caracteres se da como argumento. El programa admitirá hasta 2 GB de datos de prueba (valor de entrada 2147483647 caracteres).

Posiciones "peligrosas" en el archivo de 2 GB:

8*11*
98*102*
998*1003*
9998*10004*
99998*100005*
999995*1000003*
9999995*10000004*
99999995*100000005*
999999995*1000000006*

Esto debería responder a la pregunta de @Leaky Nun si hay que tomar una decisión entre 995 * 999 * y 995 * 1000 * o similar: no.

El final del archivo de 2 GB con el valor de entrada 2147483647 es:

2147483640*2147483

Si no se detiene, ¿cómo lo prueba?
Leaky Nun

2
¿Es esa longitud en caracteres?
TheBikingViking

44
¿Puedes demostrar que nunca tendríamos que elegir entre 995*999*y 995*1000*nada de eso?
Leaky Nun

1
En el futuro, utilice el Sandbox para resolver problemas en sus desafíos antes de publicarlos.
Mego

1
@ThomasWeller Si podemos crear una salida más larga, ¿no podemos tomar entradas y solo producir la cadena de 2GB?
xnor

Respuestas:


4

Haskell, 60 58 bytes

Como función obtenemos:

f=length.show
iterate(\n->1+n+(f$n+1+f n))2>>=(++"*").show

Programa completo, 72 70 bytes

Esto genera una contracadena infinita a STDOUT:

f=length.show
main=putStr$iterate(\n->1+n+(f$n+1+f n))2>>=(++"*").show

Ingresar la longitud requiere 20 bytes adicionales:

main=interact(\j->take(read j)$iterate(\n->1+n+(f$n+1+f n))2>>=(++"*").show)

Esto funciona aproximadamente a su tamaño de RAM, ya que Haskell predetermina los tipos integrales numéricos a Integer.



2

Python 2, 74 72 66 64 61 Bytes

f=lambda n,i=2:"%d*"%i+f(n,len(`i+2`)-~i)[:n-2]if i<n*2else""

Toma un entero n y genera una contracadena de longitud n.

versión del programa, 69 Bytes:

s,n,i="",input(),2
while i<2*n:s+="%d*"%i;i+=len(`i+2`)+1
print s[:n]

Toma un entero n de stdin e imprime una contracadena de longitud n.

Versión alternativa más corta, pero solo casi funcional:

n,i=input(),2
while i<2*n:print("%d*"%i)[:n-i],;i+=len(str(i+2))+1

1

PowerShell v5, 97 bytes

param($n)$l=1;for($i=0;$i-lt$n){$i+="$i*".length;if("$i".Length-gt$l){$i++;$l++};ac .\o "$i*" -n}

Toma la entrada como un argumento de línea de comando $n, establece el ayudante $lque usamos para realizar un seguimiento de nuestra longitud entera. Luego, hacemos un bucle de 0hasta $n. Cada iteración, incrementamos $ipor .lengthla cadena formada a partir de $iun asterisco. Entonces, si el .lengthde $icambiado (por ejemplo, pasamos de 2 dígitos a 3 dígitos), incrementamos tanto el ayudante $lvariable de ength y $i(a la cuenta para el dígito adicional). Luego usamos el add-contentcomando para agregar "$i*"al archivo .\oen el directorio actual, con -noNewLine.

nótese bien

  • Requiere v5, ya que el -noNewLineparámetro finalmente se agregó en esa versión.
  • PowerShell convertirá automáticamente de arriba [int]a [double](no, no sé por qué no funciona [long]), por lo que manejará correctamente la entrada hasta y 2147483648sin problemas. Teóricamente, manejará la entrada en algún lugar hasta alrededor 1.79769313486232E+308(valor máximo de [double]) antes de quejarse, pero espero que el disco se llene antes de que eso suceda. ;-)
  • Debido a la verificación condicional del bucle, esto generará en el archivo un mínimo de la longitud de entrada. Por ejemplo, para la entrada, 10esto dará salida 2*4*6*8*11*, ya que 11es el primer $ivalor mayor que la entrada.

PowerShell v2 +, también 97 bytes (no competitivos)

param($n)$l=1;-join(&{for($i=0;$i-lt$n){$i+="$i*".length;if("$i".Length-gt$l){$i++;$l++};"$i*"}})

En lugar de enviar a un archivo, esto encapsula las iteraciones del bucle y luego -joinlas une en una cadena. Esto le permite funcionar para versiones anteriores a la v5. Sin embargo, dado que .NET define a [string]con un constructor como String(char c,Int32 length), esta versión no satisface el requisito de entrada máxima, ya que la cadena de salida se desbordará y se barf.

Además, es posible que no desee tener una cadena de ~ 2GB flotando en su tubería. Sólo digo'.


1.79769313486232E + 308 ciertamente no funcionará, porque agregar números pequeños a un flotante ya no cambiará el valor. Ver stackoverflow.com/questions/12596695/… Así que supongo que deja de funcionar una vez que se "actualizó" al doble
Thomas Weller

@ThomasWeller PowerShell [double]s son de 64 bits. Por ejemplo, la ejecución for($i=2147483645;$i-lt2147483655;$i++){"$i - " + $i.GetType()}mostrará una progresión constante de $ipero los Typecambios en 2147483648a double. Estoy seguro de que en algún momento dejará de funcionar, probablemente alrededor de ~ 15 dígitos de precisión o cuando .ToStringcomience a usarse e. El [double]::MaxValueera más de una broma de usar y tirar que un serio límite superior.
AdmBorkBork

1

Python 3, 126 114 99 bytes

def f(x,s=''):
 i=t=2
 while len(s)<x:i+=len(str(t+i))-len(str(t));s+=str(t)+'*';t+=i
 print(s[:x])

Una función que toma la entrada a través del argumento del recuento de caracteres en el que truncar la cadena e imprime en STDOUT.

Cómo funciona

La diferencia entre los números en la cadena es inicialmente 2. Cada vez que se pasa un orden de magnitud, esta diferencia aumenta en 1; esto se puede lograr tomando la diferencia entre el número de dígitos del número actual y el número de dígitos del número actual agregado a la diferencia, que es 1 solo cuando es necesario. La función simplemente se repite mientras la longitud de la cadena es menor que la entrada, se agrega a la cadena y actualiza la diferencia y el número según sea necesario, y luego se trunca antes de imprimir.

Pruébalo en Ideone

Versión de salida infinita, 69 bytes.

s=i=2
while 1:i+=len(str(s+i))-len(str(s));print(end=str(s)+'*');s+=i

1

R, 92 bytes

    N=nchar;f=function(n){z=0;y="";while(z<n){z=z+N(z+N(z)+1)+1;y=paste0(y,z,"*")};strtrim(y,n)}

Salida de ejemplo:

f (103) [1] "2 * 4 * 6 * 8 * 11 * 14 * 17 * 20 * 23 * 26 * 29 * 32 * 35 * 38 * 41 * 44 * 47 * 50 * 53 * 56 * 59 * 62 * 65 * 68 * 71 * 74 * 77 * 80 * 83 * 86 * 89 * 92 * 95 * 98 * 102 * 1 "


0

Jalea , 22 19 18 bytes

2µṾL+®‘¹©=¡=µ³#j”*

Pruébalo en línea!

Encuentra los primeros nnúmeros en la cadena y luego únete a la lista con un asterisco. Esto siempre será más largo que nel permitido por OP en los comentarios.

El programa actualiza selectivamente el registro con el número actual en la secuencia en el #ciclo con ¹©=¡. Esperaba que esto pudiera ser más corto, por ejemplo, ©después del segundo µ, pero desafortunadamente eso no funciona y no pude resolver nada más corto.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.