Hintergrund
Incident ist eine ziemlich ungewöhnliche Programmiersprache, da die Liste der Token nicht vorbestimmt ist, sondern aus der Eingabe abgeleitet wird. Daher kann das Tokenisieren eines Incident-Programms ziemlich schwierig sein, insbesondere wenn Sie dies effizient tun möchten. Bei dieser Aufgabe geht es darum, das selbst zu tun.
Die Aufgabe
Ihr Programm erhält als Eingabe einen String. Hier ist der Algorithmus, den Incident verwendet, um es zu kennzeichnen:
- Identifizieren Sie alle Zeichenfolgen, die als Teilzeichenfolge der Eingabe vorkommen, auf genau drei Arten (dh, die Zeichenfolge kommt in der Eingabe genau dreimal vor).
- Verwerfen Sie alle diese Zeichenfolgen, die eine Teilzeichenfolge einer anderen solchen Zeichenfolge sind (z. B. für die Eingabe wäre
ababab
die einzige verbleibende Zeichenfolgeab
, nichta
oderb
, weila
undb
beide Teilzeichenfolgen vonab
). - Verwerfen Sie alle Zeichenfolgen, die sich in der Eingabe überschneiden. (
aaaa
Enthält z. B. genau drei Kopien vonaa
, aber diese Kopien überlappen sich beim zweiten und dritten Zeichen, sodass sie verworfen werden. In ähnlicher Weiseabababa
gibt es drei Kopien vonab
und drei Kopien vonba
, aber das zweite bis sechste Zeichen befinden sich jeweils beim Überlappung von aab
und aba
, also beideab
undba
würden verworfen). - Alle Zeichenfolgen, die an diesem Punkt verbleiben, sind die vom Programm verwendeten Token. Unterteilen Sie die ursprüngliche Eingabe in eine Sequenz dieser Token (aufgrund des Verwerfens im vorherigen Schritt gibt es nur eine Möglichkeit, dies zu tun). Alle Zeichen in der Eingabe, die nicht Teil eines Tokens sind, werden als Kommentare behandelt und verworfen.
Ihr Programm muss eine Zeichenfolge als Eingabe nehmen und die entsprechende Tokenisierung der Zeichenfolge (eine Liste von Token, die jeweils als Zeichenfolgen ausgedrückt werden) als Ausgabe zurückgeben. Darüber hinaus muss dies zumindest mäßig effizient erfolgen; Insbesondere muss das Programm in quadratischer Zeit ("O (n²)") oder besser ausgeführt werden. (Übrigens ist es mit ziemlicher Sicherheit möglich, schneller als quadratisch zu arbeiten, aber dies ist kein schneller Algorithmus. Verwenden Sie also den genauesten Algorithmus, der innerhalb der Komplexitätsgrenzen liegt.)
Klarstellungen
- Obwohl Incident-Programme theoretisch jedes der 256 Oktette enthalten können, ist es für den Zweck dieser Herausforderung für Ihr Programm akzeptabel, nur Eingaben zu verarbeiten, die aus druckbarem ASCII (einschließlich Leerzeichen) sowie Zeilenumbrüchen und Tabulatoren bestehen. (Alle bekannten Incident-Programme beschränken sich auf diese Untermenge.) Beachten Sie, dass Leerzeichen / Zeilenumbrüche / Tabulatoren nichts Besonderes sind und in der Mitte von Token angezeigt werden können. Incident behandelt alle 256 Oktette als undurchsichtig.
- Die Definition von "quadratischer Zeit" ist "wenn die Größe der Eingabe verdoppelt wird, läuft das Programm um nicht mehr als eine Konstante plus einen Faktor von 4 langsamer", dh wenn t ( x ) die maximale Zeit ist, die Ihr Programm benötigt Verarbeiten Sie eine Eingabe der Größe x , dann muss es eine Konstante k geben, so dass t (2 x ) <4 t ( x ) + k für alle x gilt . Beachten Sie, dass das Vergleichen von Zeichenfolgen eine Zeit benötigt, die proportional zur Länge der Zeichenfolgen ist.
- Ihr Programm sollte theoretisch in der Lage sein, Eingabeprogramme beliebiger Länge zu verarbeiten, wenn es in einer (möglicherweise hypothetischen) Variante Ihrer Sprache mit unbegrenztem Speicher und unbegrenzten Ganzzahlen ausgeführt wird (es ist in Ordnung, wenn das Programm dieses Ziel in der Praxis aufgrund von nicht erreicht die ganzen Zahlen oder das Gedächtnis der Sprache sind tatsächlich endlich groß). Sie können davon ausgehen (um die Komplexität zu berechnen), dass ganze Zahlen, die nicht länger als die Länge der Eingabe sind, in konstanter Zeit verglichen werden können (denken Sie jedoch daran, wenn Sie größere Werte verwenden, z. B. aufgrund der Konvertierung der Eingabe in a Bei einer einzelnen Ganzzahl dauert der Vergleich proportional zur Anzahl der Stellen länger.
- Sie können jeden Algorithmus verwenden, der innerhalb der Komplexitätsgrenzen liegt, auch wenn er nicht denselben Schritten wie der oben angegebene Algorithmus folgt, sofern er dieselben Ergebnisse liefert.
- In diesem Rätsel geht es darum, die Eingabe zu tokenisieren und nicht wirklich die Ausgabe zu formatieren. Wenn die natürlichste Art, eine Liste in Ihrer Sprache auszugeben, ein mehrdeutiges Format beinhaltet (z. B. durch Zeilenumbrüche getrennt, wenn die Zeichenfolgen wörtliche Zeilenumbrüche enthalten oder ohne Trennzeichen zwischen den Zeichenfolgen), machen Sie sich keine Sorgen darüber, dass die Ausgabe mehrdeutig wird ( solange die Liste tatsächlich aufgebaut ist). Möglicherweise möchten Sie eine zweite Version Ihrer Einreichung erstellen, die eine eindeutige Ausgabe liefert, um das Testen zu erleichtern. Die Originalversion ist jedoch die Version, die für die Bewertung zählt.
Testfall
Für die folgende Eingabezeichenfolge:
aaabcbcbcdefdfefedghijghighjkllkklmmmmonono-nonppqpq-pqprsrsrstststuvuvu
Ihr Programm sollte die folgende Ausgabeliste erzeugen:
a a a bc bc bc d e f d f e f e d gh gh gh k l l k k l pq pq pq u u u
Siegbedingung
Dies ist Code-Golf , daher gewinnt das kürzeste gültige (dh korrekte Eingabe- / Ausgabeverhalten und ausreichend schnell zum Ausführen) Programm, gemessen in Bytes.