Crie uma corda ilimitada

11

Uma contraparte é algum tipo de dado de teste autoexplicativo usado nos testes de software. Não tenho certeza se foi realmente inventado por James Bach , mas eu sei disso a partir daí.

A ideia é a seguinte: os dados de teste contêm muitos asteriscos ( *). O número na frente do asterisco informa quanto tempo os dados do teste estão nesse ponto. Se você precisar conhecer uma posição nos dados de teste que não é um asterisco, localize o último asterisco, verifique o número anterior e adicione o número de dígitos a seguir.

A sequência começa assim:

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

Como você pode ver, o asterisco marcado está na posição 14.

Se um arquivo estiver truncado da seguinte maneira

[...]2045*20

então você pode derivar que há um limite de 2047 caracteres em algum lugar (2045 onde o asterisco é mais 2 para 2e 0).

É sua tarefa criar o programa mais curto (este é o ) que gera (std :: out ou arquivo ou qualquer outra coisa) uma sequência de testes longa arbitrária desse formato. O comprimento em caracteres é dado como argumento. O programa deve suportar até 2 GB de dados de teste (valor de entrada 2147483647 caracteres).

Posições "perigosas" no arquivo de 2 GB:

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

Isso deve responder à pergunta de @Leaky Nun se houver uma decisão a tomar entre 995 * 999 * e 995 * 1000 * ou similar: não.

O final do arquivo de 2 GB com o valor de entrada 2147483647 é:

2147483640*2147483
Thomas Weller
fonte
Se não parar, como você o testará?
Leaky Nun
2
Esse comprimento é de caracteres?
TheBikingViking 23/08
4
Você pode provar que nunca teríamos que escolher entre 995*999*e 995*1000*ou algo assim?
Leaky Nun
1
No futuro, use o Sandbox para resolver problemas de seus desafios antes de publicá-los.
Mego
1
@ThomasWeller Se pudermos criar uma saída mais longa, não podemos dar entrada e apenas produzir a sequência de 2 GB?
Xnor

Respostas:

4

Haskell, 60 58 bytes

Como função, obtemos:

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

Programa completo, 72 70 bytes

Isso gera uma contraparte infinita para STDOUT:

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

A entrada do comprimento requer 20 bytes adicionais:

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

Isso funciona com o tamanho aproximado do seu RAM, já que Haskell usa como padrão os tipos integrais numéricos Integer.

ThreeFx
fonte
3

Pitão, 25 17 15 14 bytes

<uu++GlN\*k)Qk

Experimente online.

O comprimento é obtido via STDIN.

PurkkaKoodari
fonte
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""

Pega um número inteiro n e gera uma cadeia de caracteres de comprimento n.

versão do programa, 69 bytes:

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

Pega um número inteiro n de stdin e imprime uma cadeia de caracteres de comprimento n.

Versão alternativa mais curta, mas apenas quase funcional:

n,i=input(),2
while i<2*n:print("%d*"%i)[:n-i],;i+=len(str(i+2))+1
KarlKastor
fonte
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}

Recebe a entrada como um argumento da linha de comando $n, define o auxiliar $lque usamos para acompanhar nosso comprimento inteiro. Então, fazemos um loop de 0até $n. Cada iteração, incrementamos $ipela .lengthda corda formada a partir $ie um asterisco. Então, se o .lengthde $imudou (por exemplo, passamos de 2 para 3 dígitos), incrementamos a $lvariável de entrada do auxiliar e $i(para contabilizar o dígito adicional). Em seguida, usamos o add-contentcomando para anexar "$i*"ao arquivo .\ono diretório atual, com -noNewLine.

NB

  • Requer v5, pois o -noNewLineparâmetro foi finalmente adicionado nessa versão.
  • O PowerShell fará a conversão automática de [int]para [double](não, não sei por que não vai [long]), portanto, isso manipulará adequadamente as entradas até e maiores que 2147483648, sem problemas. Teoricamente, ele manipulará a entrada em algum lugar 1.79769313486232E+308(valor máximo de [double]) antes de reclamar, mas espero que o disco seja preenchido antes que isso aconteça. ;-)
  • Devido à verificação condicional do loop, isso produzirá no arquivo um mínimo do comprimento da entrada. Por exemplo, para entrada, 10isso será exibido 2*4*6*8*11*, pois 11é o primeiro $ivalor maior que a entrada.

PowerShell v2 +, também 97 bytes (não concorrente)

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

Em vez de enviar para um arquivo, isso encapsula as iterações do loop e -joinas reúne em uma string. Isso permite que ele funcione para versões anteriores à v5. No entanto, como o .NET define a [string]com um construtor String(char c,Int32 length), essa versão não atende ao requisito máximo de entrada, já que a sequência de saída transbordará e será vomitada.

Além disso, você pode não querer ter uma seqüência de ~ 2 GB flutuando no seu pipeline. Apenas dizendo'.

AdmBorkBork
fonte
1.79769313486232E + 308 certamente não funcionará, porque adicionar números pequenos a um float não alterará mais o valor. Veja stackoverflow.com/questions/12596695/... Assim, a minha acho que ele pára de funcionar, uma vez que foi "atualizado" para dobrar
Thomas Weller
Os @ThomasWeller PowerShell [double]s são de 64 bits. Por exemplo, a execução for($i=2147483645;$i-lt2147483655;$i++){"$i - " + $i.GetType()}mostrará uma progressão constante de $imas as Typealterações em 2147483648para double. Tenho certeza de que em algum momento ele irá parar de funcionar, provavelmente em torno de ~ 15 dígitos de precisão ou quando .ToStringcomeçar a usar e. A [double]::MaxValueera mais uma piada descartável do que um sério limite 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])

Uma função que recebe entrada via argumento da contagem de caracteres na qual truncar a string e imprime em STDOUT.

Como funciona

A diferença entre os números na sequência é inicialmente 2. Toda vez que uma ordem de magnitude é passada, essa diferença é aumentada em 1; isso pode ser alcançado considerando a diferença entre o número de dígitos do número atual e o número de dígitos do número atual adicionado à diferença, que é 1 somente quando necessário. A função simplesmente faz um loop enquanto o comprimento da string é menor que a entrada, anexa à string e atualiza a diferença e o número conforme necessário e, em seguida, trunca antes da impressão.

Experimente no Ideone

Versão de saída infinita, 69 bytes

s=i=2
while 1:i+=len(str(s+i))-len(str(s));print(end=str(s)+'*');s+=i
TheBikingViking
fonte
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)}

Exemplo de saída:

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 "

JDL
fonte
0

Geléia , 22 19 18 bytes

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

Experimente online!

Encontre os primeiros nnúmeros na string e entre na lista com um asterisco. Isso sempre será mais longo do nque o permitido pelo OP nos comentários.

O programa atualiza seletivamente o registro com o número atual na sequência no #loop com ¹©=¡. Eu esperava que isso pudesse ser mais curto, colocando ©após o segundo, µpor exemplo, mas infelizmente isso não funciona e eu não consegui descobrir nada mais curto.

dylnan
fonte