Erstellen Sie eine unbegrenzte Gegenzeichenfolge


11

Ein Counterstring ist eine Art selbstbeschreibender Testdaten, die beim Testen von Software verwendet werden. Ich bin mir nicht sicher, ob es tatsächlich von James Bach erfunden wurde , aber ich weiß es von dort.

Die Idee ist wie folgt: Die Testdaten enthalten viele Sternchen ( *). Die Zahl vor dem Sternchen gibt an, wie lange die Testdaten zu diesem Zeitpunkt sind. Wenn Sie eine Position in den Testdaten kennen müssen, die kein Sternchen ist, suchen Sie das letzte Sternchen, sehen Sie sich die Nummer zuvor an und fügen Sie die Anzahl der folgenden Ziffern hinzu.

Die Sequenz beginnt wie folgt:

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

Wie Sie sehen können, befindet sich das markierte Sternchen an Position 14.

Wenn eine Datei wie folgt abgeschnitten wird

[...]2045*20

dann können Sie ableiten, dass es irgendwo ein Limit von 2047 Zeichen gibt (2045, wo das Sternchen plus 2 für 2und ist 0).

Es ist Ihre Aufgabe, das kürzeste Programm (dies ist ) zu erstellen, das eine beliebige lange Testzeichenfolge dieses Formats ausgibt (std :: out oder file oder was auch immer). Die Länge in Zeichen wird als Argument angegeben. Das Programm muss bis zu 2 GB Testdaten unterstützen (Eingabewert 2147483647 Zeichen).

"Gefährliche" Positionen in der 2-GB-Datei:

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

Dies sollte die Frage von @Leaky Nun beantworten, wenn eine Entscheidung zwischen 995 * 999 * und 995 * 1000 * oder ähnlichem getroffen wird: Nein.

Das Ende der 2-GB-Datei mit dem Eingabewert 2147483647 lautet:

2147483640*2147483

Wenn es nicht anhält, wie testen Sie es dann?
Undichte Nonne

2
Ist diese Länge in Zeichen?
TheBikingViking

4
Können Sie beweisen, dass wir uns niemals zwischen 995*999*und 995*1000*oder so etwas entscheiden müssten ?
Undichte Nonne

1
Verwenden Sie in Zukunft die Sandbox , um Knicke in Ihren Herausforderungen auszubügeln, bevor Sie sie veröffentlichen.
Mego

1
@ThomasWeller Wenn wir eine längere Ausgabe erstellen können, können wir dann keine Eingabe vornehmen und nur die 2-GB-Zeichenfolge erstellen?
xnor

Antworten:


4

Haskell, 60 58 Bytes

Als Funktion erhalten wir:

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

Volles Programm, 72 70 Bytes

Dies gibt eine unendliche Gegenzeichenfolge an STDOUT aus:

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

Die Eingabe der Länge erfordert 20 zusätzliche Bytes:

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

Dies funktioniert bis zu Ihrer ungefähren RAM-Größe, da Haskell standardmäßig numerische Integraltypen verwendet 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""

Nimmt eine ganze Zahl n und gibt einen Gegenstring der Länge n aus.

Programmversion, 69 Bytes:

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

Nimmt eine ganze Zahl n von stdin und druckt eine Gegenzeichenfolge der Länge n.

Kürzere, aber nur fast funktionierende alternative Version:

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}

Nimmt die Eingabe als Befehlszeilenargument $nund legt den Helfer fest, mit $ldem wir unsere Ganzzahllänge verfolgen. Dann schleifen wir von 0bis $n. Bei jeder Iteration erhöhen wir uns $ium die .lengthaus der Zeichenfolge $iund einem Sternchen. Wenn sich dann das .lengthvon $igeändert hat (z. B. haben wir von 2 auf 3 Stellen gewechselt), $lerhöhen wir sowohl die Hilfslängenvariable als auch $i(um die zusätzliche Ziffer zu berücksichtigen). Wir verwenden dann den add-contentBefehl , um mit oNewLine "$i*"an die Datei .\oim aktuellen Verzeichnis -nanzuhängen.

NB

  • Benötigt v5, da der -noNewLineParameter in dieser Version endlich hinzugefügt wurde.
  • PowerShell konvertiert automatisch von [int]nach [double](nein, ich weiß nicht, warum es nicht zu geht [long]), sodass Eingaben bis zu und größer als 2147483648problemlos problemlos verarbeitet werden können. Theoretisch werden Eingaben bis zu ungefähr 1.79769313486232E+308(Maximalwert von [double]) verarbeitet, bevor Sie sich beschweren, aber ich erwarte, dass sich die Festplatte füllt, bevor dies geschieht. ;-);
  • Aufgrund der Schleifenbedingungsprüfung wird ein Minimum der Eingabelänge in die Datei ausgegeben . Bei der Eingabe wird 10dies beispielsweise ausgegeben 2*4*6*8*11*, da 11der erste $iWert größer als die Eingabe ist.

PowerShell v2 +, ebenfalls 97 Byte (nicht konkurrierend)

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

Anstatt an eine Datei zu senden, werden die Schleifeniterationen gekapselt und dann -joinzu einer Zeichenfolge zusammengefasst. Dies ermöglicht es, für Versionen vor Version 5 zu arbeiten. Da .NET jedoch a [string]mit einem Konstruktor wie definiert String(char c,Int32 length), erfüllt diese Version nicht die maximale Eingabeanforderung, da die Ausgabezeichenfolge überläuft und barf.

Möglicherweise möchten Sie auch keine ~ 2 GB-Zeichenfolge in Ihrer Pipeline haben. Ich sag bloß'.


1.79769313486232E + 308 wird sicherlich nicht funktionieren, da das Hinzufügen kleiner Zahlen zu einem Float den Wert nicht mehr ändert. Siehe stackoverflow.com/questions/12596695/… Ich vermute also, dass es nicht mehr funktioniert, sobald es auf doppelt "aktualisiert" wurde
Thomas Weller

@ThomasWeller PowerShell [double]s sind 64-Bit. Zum Beispiel zeigt der Lauf for($i=2147483645;$i-lt2147483655;$i++){"$i - " + $i.GetType()}einen stetigen Verlauf von, $iaber die TypeÄnderungen bei 2147483648bis double. Ich bin mir sicher, dass es irgendwann nicht mehr funktioniert, wahrscheinlich mit einer Genauigkeit von ca. 15 Stellen oder wenn die .ToStringVerwendung beginnt e. Das [double]::MaxValuewar eher ein Wegwerfwitz ​​als eine ernsthafte Obergrenze.
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])

Eine Funktion, die über ein Argument der Zeichenanzahl, bei der die Zeichenfolge abgeschnitten werden soll, Eingaben vornimmt und in STDOUT druckt.

Wie es funktioniert

Die Differenz zwischen den Zahlen in der Zeichenfolge beträgt anfänglich 2. Jedes Mal, wenn eine Größenordnung übergeben wird, wird diese Differenz um 1 erhöht. Dies kann erreicht werden, indem die Differenz zwischen der Anzahl der Ziffern der aktuellen Nummer und der Anzahl der Ziffern der aktuellen Nummer zur Differenz addiert wird, die nur bei Bedarf 1 beträgt. Die Funktion wird einfach wiederholt, während die Länge der Zeichenfolge kleiner als die Eingabe ist, an die Zeichenfolge angehängt und die Differenz und Anzahl nach Bedarf aktualisiert und dann vor dem Drucken abgeschnitten.

Probieren Sie es auf Ideone

Unendliche Ausgabeversion, 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)}

Beispielausgabe:

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

Gelee , 22 19 18 Bytes

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

Probieren Sie es online aus!

Suchen Sie die ersten nZahlen in der Zeichenfolge und fügen Sie die Liste mit einem Sternchen hinzu. Dies wird immer länger sein, als nes OP in den Kommentaren erlaubt hat.

Das Programm aktualisiert das Register selektiv mit der aktuellen Nummer in der Sequenz in der #Schleife mit ¹©=¡. Ich hatte gehofft, dass dies kürzer sein könnte, indem ich zum Beispiel ©nach dem zweiten µsetze, aber leider funktioniert das nicht und ich konnte nichts kürzeres herausfinden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.