Crea una contromossa illimitata


11

Una contromisure è una sorta di dati di test autodescriventi utilizzati nei test del software. Non sono sicuro che sia stato inventato da James Bach , ma lo so da lì.

L'idea è la seguente: i dati del test contengono molti asterisco ( *). Il numero davanti all'asterisco indica la durata dei dati del test a quel punto. Se devi conoscere una posizione nei dati del test che non è un asterisco, trova l'ultimo asterisco, osserva il numero precedente e aggiungi il numero di cifre che seguono.

La sequenza inizia in questo modo:

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

Come puoi vedere, l'asterisco contrassegnato si trova in posizione 14.

Se un file sembra essere troncato come segue

[...]2045*20

allora puoi derivare che c'è un limite di 2047 caratteri da qualche parte (2045 dove l'asterisco è più 2 per 2e 0).

È tuo compito creare il programma più breve (questo è ) che emetta (std :: out o file o altro) una stringa di test lunga arbitraria di quel formato. La lunghezza in caratteri è indicata come argomento. Il programma deve supportare fino a 2 GB di dati di prova (valore di input 2147483647 caratteri).

Posizioni "pericolose" nel file da 2 GB:

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

Questo dovrebbe rispondere alla domanda di @Leaky Nun se c'è una decisione da prendere tra 995 * 999 * e 995 * 1000 * o simile: no.

La fine del file da 2 GB con valore di input 2147483647 è:

2147483640*2147483

Se non si ferma allora come lo testate?
Leaky Nun,

2
È quella lunghezza in caratteri?
TheBikingViking

4
Si può dimostrare che non avremmo mai dovuto scegliere tra 995*999*e 995*1000*o qualcosa di simile?
Leaky Nun,

1
In futuro, utilizzare Sandbox per appianare i nodi nelle sfide prima di pubblicarle.
Mego,

1
@ThomasWeller Se possiamo creare un output più lungo, non possiamo prendere input e produrre solo la stringa da 2 GB?
xnor

Risposte:


4

Haskell, 60 58 byte

Come funzione otteniamo:

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

Programma completo, 72 70 byte

Questo genera una controtendenza infinita per STDOUT:

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

L'immissione della lunghezza richiede 20 byte aggiuntivi:

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

Questo funziona fino a circa la dimensione della RAM, poiché Haskell imposta automaticamente i tipi numerici integrali Integer.



2

Python 2, 74 72 66 64 61 byte

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

Accetta un numero intero n e genera una controtendenza di lunghezza n.

versione del programma, 69 byte:

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

Prende un numero intero n da stdin e stampa una contromossa di lunghezza n.

Versione alternativa più breve, ma quasi funzionante:

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

1

PowerShell v5, 97 byte

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

Prende l'input come argomento della riga di comando $n, imposta l'helper $lche usiamo per tenere traccia della nostra lunghezza intera. Quindi, passiamo da un 0punto all'altro $n. Ogni iterazione, incrementiamo $iper .lengthla stringa formata da $ie un asterisco. Quindi, se il .lengthdi è $icambiato (ad esempio, ci siamo spostati da 2 cifre a 3 cifre), incrementiamo sia la $lvariabile ength helper che $i(per tenere conto della cifra aggiuntiva). Quindi utilizziamo il add-contentcomando per aggiungere "$i*"al file .\onella directory corrente, con -noNewLine.

NB

  • Richiede v5, poiché il -noNewLineparametro è stato finalmente aggiunto in quella versione.
  • PowerShell eseguirà automaticamente la conversione da [int]a [double](no, non so perché non vada a [long]), quindi questo gestirà correttamente l'input fino ae maggiore di 2147483648, senza problemi. Teoricamente, gestirà l'input da qualche parte fino a circa 1.79769313486232E+308(valore massimo di [double]) prima di lamentarsi, ma mi aspetto che il disco si riempia prima che ciò accada. ;-)
  • A causa del controllo condizionale del loop, questo invierà al file un minimo della lunghezza di input. Ad esempio, per l'input 10questo verrà emesso 2*4*6*8*11*, poiché 11il primo $ivalore è maggiore dell'input.

PowerShell v2 +, anche 97 byte (non concorrenti)

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

Invece di inviare a un file, questo incapsula le iterazioni del ciclo e poi -joinle unisce in una stringa. Ciò gli consente di funzionare per versioni precedenti alla v5. Tuttavia, poiché .NET definisce un [string]con un costruttore simile String(char c,Int32 length), questa versione non soddisfa il requisito di input massimo, poiché la stringa di output traboccerà e barf.

Inoltre, potresti non voler avere una stringa di ~ 2GB fluttuante nella pipeline. Sto solo dicendo.


1.79769313486232E + 308 sicuramente non funzionerà, perché l'aggiunta di piccoli numeri a un float non modificherà più il valore. Vedi stackoverflow.com/questions/12596695/… Quindi immagino che smetta di funzionare una volta "aggiornato" per raddoppiare
Thomas Weller,

@ThomasWeller I PowerShell [double]sono a 64 bit. Ad esempio, corsa for($i=2147483645;$i-lt2147483655;$i++){"$i - " + $i.GetType()}mostra una progressione costante $ima i Typecambiamenti a 2147483648a double. Sono sicuro che a un certo punto smetterà di funzionare, probabilmente intorno a circa 15 cifre di precisione o quando .ToStringinizia a usare e. L' [double]::MaxValueera più di uno scherzo usa e getta che un serio limite superiore.
AdmBorkBork,

1

Python 3, 126 114 99 99 byte

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 funzione che accetta l'input tramite argomento del conteggio dei caratteri in corrispondenza del quale troncare la stringa e stampa su STDOUT.

Come funziona

La differenza tra i numeri nella stringa è inizialmente 2. Ogni volta che viene passato un ordine di grandezza, questa differenza viene aumentata di 1; ciò può essere ottenuto prendendo la differenza tra il numero di cifre del numero corrente e il numero di cifre del numero corrente aggiunto alla differenza, che è 1 solo quando richiesto. La funzione esegue semplicemente un ciclo mentre la lunghezza della stringa è inferiore all'input, accoda la stringa e aggiorna la differenza e il numero come richiesto, quindi si tronca prima della stampa.

Provalo su Ideone

Versione di output infinita, 69 byte

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

1

R, 92 byte

    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)}

Esempio di output:

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


0

Gelatina , 22 19 18 byte

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

Provalo online!

Trova i primi nnumeri nella stringa, quindi unisciti all'elenco con un asterisco. Questo sarà sempre più lungo di quanto nconsentito da OP nei commenti.

Il programma aggiorna selettivamente il registro con il numero corrente nella sequenza nel #ciclo con ¹©=¡. Speravo che questo potesse essere più breve, ad esempio ©dopo il secondo µ, ma sfortunatamente non funziona e non sono riuscito a capire qualcosa di più breve.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.