Intro
Deshalb habe ich wieder meine Zeit damit verschwendet, nach Suffix-Sortieralgorithmen zu suchen und neue Ideen von Hand und im Code zu bewerten. Aber ich habe immer Mühe, mich an die Art meiner Suffixe zu erinnern! Können Sie mir sagen, welcher Typ meine Suffixe sind?
Ganz links was?
Viele Suffix-Sortieralgorithmen (SAIS, KA, meine eigene Daware) gruppieren Suffixe in verschiedene Typen, um sie zu sortieren. Es gibt zwei Grundtypen: S-Typ- und L-Typ- Suffixe. Suffixe vom Typ S sind Suffixe, die lexikographisch kleiner ( S maller) sind als das folgende Suffix und L-Typ, wenn sie lexikographisch größer sind ( L arger). Ein S-Typ ganz links ( LMS-Typ ) ist genau das: Ein S-Typ- Suffix, dem ein L-Typ- Suffix vorangestellt ist .
Das Besondere an diesen Suffixen vom Typ LMS ist, dass wir nach dem Sortieren alle anderen Suffixe in linearer Zeit sortieren können! Ist das nicht großartig?
Die Herausforderung
Angenommen, eine Zeichenfolge wird durch ein Sonderzeichen abgeschlossen, das kleiner als jedes andere Zeichen in dieser Zeichenfolge ist (z. B. kleiner als das Nullbyte). Geben Sie für jedes Suffix ein entsprechendes Zeichen aus.
Sie können frei wählen , welche Zeichen für welche Art zu verwenden , aber ich würde es vorziehen , L, S and *
für L-, S- and LMS-type
so lange , wie sie alle druckbaren sind ( 0x20 - 0x7E
).
Beispiel
Angesichts der String- mmiissiissiippi
Ausgabe (bei Verwendung L, S and *
):
LL*SLL*SLL*SLLL
Zum Beispiel ist das erste L
auf die Tatsache zurückzuführen, dass mmiissiissiippi$
es lexikographisch größer ist als miissiissiippi$
(das $
repräsentiert das hinzugefügte Minimalzeichen):
L - mmiissiissiippi$ > miissiissiippi$
L - miissiissiippi$ > iissiissiippi$
* - iissiissiippi$ < issiissiippi and preceeded by L
S - issiissiippi$ < ssiissiippi$
L - ssiissiippi$ > siissiippi$
L - siissiippi$ > iissiippi$
* - iissiippi$ < issiippi$ and preceeded by L
S - issiippi$ < ssiippi$
L - ssiippi$ > siippi$
L - siippi$ > iippi$
* - iippi$ < ippi$ and preceeded by L
S - ippi$ < ppi$
L - ppi$ > pi$
L - pi$ > i$
L - i$ > $
Einige weitere Beispiele:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Tor
Ich bin nicht hier, um Peter Cordes zu ärgern (ich werde das irgendwann beim Stackoverflow tun); Ich bin nur sehr faul, das ist natürlich Code-Golf ! Die kürzeste Antwort in Bytes gewinnt.
Bearbeiten: Die Reihenfolge der Zeichen wird durch ihren Bytewert angegeben. Das heißt, vergleichen sollte wie C sein strcmp
.
Edit2: Wie in den Kommentaren angegeben, sollte die Ausgabe für jedes Eingabezeichen ein einzelnes Zeichen sein. Obwohl ich davon ausgegangen bin, dass dies als "Rückgabe einer Zeichenfolge" verstanden wird, scheint mindestens 1 Antwort eine Liste einzelner Zeichen zurückzugeben. Um die vorhandenen Antworten nicht ungültig zu machen, können Sie eine Liste einzelner Zeichen (oder Ganzzahlen, die beim Drucken nur 1 Zeichen ergeben) zurückgeben.
Tipps für die lineare Zeit:
- Dies kann in 2 parallelen Vorwärtsiterationen oder in einer einzelnen Rückwärtsiteration erfolgen.
- Der Status jedes Suffix hängt nur von den ersten beiden Zeichen und dem Typ des zweiten ab.
- Durch Scannen des Eingangs in umgekehrter Richtung können Sie L oder S wie folgt bestimmen:
$t=$c<=>$d?:$t
(PHP 7), wobei$c
das aktuelle Zeichen$d
der vorherige und$t
der vorherige Typ ist. - Siehe meine PHP-Antwort . Morgen werde ich das Kopfgeld vergeben.
c++
. Betrachten Sie es als binäre Daten.*
das*
bedeutet, dass das entsprechende Suffix vom Typ istleft most s-type
.A S-type suffix that is preceeded by a L-type suffix.
.Antworten:
Haskell ,
64534842 BytesProbieren Sie es online aus!
Ungolfed, mit
Char
anstelle vonInt
:quelle
z=
können diese entfernt werden.go
Funktion akzeptiert zwei Argumente. Das erste ist das Zeichen, das darstellt, was zur Beschreibung derS
Situation verwendet werden soll. Der zweite ist eine Zeichenfolge. Diese Zeichenfolge wird rekursiv durchlaufen, wobei bei jedem Schritt das erste Zeichen entfernt wird (genau dastail
tut es). Der Trick ist, dass das erste Argument auf gesetzt wird,*
wenn das vorherige Ergebnis aL
war oder aufS
andere Weise. Auf diese Weise kann in dem Fall, in dem ein*
oder ein verwendetS
werden soll, dieses erste Argument direkt verwendet werden. Hoffe das macht Sinn.Gelee ,
25 23 21 2019 BytesEin vollständiges Programm, das die Liste der Zeichen druckt und dabei Folgendes verwendet:
(Als Link wird eine Liste zurückgegeben, in der alle Elemente Zeichen sind, mit Ausnahme des letzten, bei dem es sich um eine Null handelt.)
Probieren Sie es online aus! oder sehen Sie sich die Testsuite an (mit Konvertierung in
LS*
).Wie?
quelle
+
auf Strings zu vektorisieren scheint, aber die zugrunde liegenden Ergebnisse sind nicht tatsächlich Jelly-Iterables, sondern Strings (!) (ZB versuchen+@/L€
oder+@/L€€
oder ...)+
erzeugt einen tatsächlichen String. Dies ist eine undokumentierte Funktion oder ein Fehler, den Sie als Fehler bezeichnen.Python 3,
9287746965 BytesVerwendet
0
fürL
,1
fürS
und2
für*
. Wickeln Sie die Eingabezeichenfolge in Anführungszeichen. Ich glaube, das ist konventionell erlaubt.Probieren Sie es online aus!
Anwendungsbeispiel:
5 Bytes dank Leaky Nun gespart, 4 Bytes dank Ovs
quelle
JavaScript (ES6),
5145 Byte6 Bytes dank @Neil gespeichert.
Eine rekursive Lösung für die Übung.
quelle
f=(c,d)=>c&&(d<(d=c<(c=c.slice(1))))+d+f(c,d)
JavaScript (ES6), 52 Byte
Port von @ L3viathans Antwort.
quelle
c=1
alsc=0
...C (Klirren) , 88 Bytes
Probieren Sie es online aus!
quelle
Haskell ,
7775 Bytes, lineare ZeitProbieren Sie es online aus!
Wie es funktioniert
Hierbei wird eine Rekursion verwendet, bei der jeweils ein Zeichen vom Anfang der Zeichenfolge entfernt wird. (Der Haskell-Zeichenfolgentyp ist eine einfach verknüpfte Liste von Zeichen, daher ist jeder dieser Schritte zeitkonstant.)
quelle
S, L and *
?[1,1,2,0,1,1,2,0,1,1,2,0,1,1,1]
ist eine Liste von einstelligen Zahlen, keine Liste von einzelnen Zeichen. In meinem Fall denke ich, dass die Ausgabe einer Liste von Zahlen mir keine Bytes ersparen würde.Python 2 ,
6555 BytesRekursive Version, basierend auf L3viathan Antwort , mit
012
wieLS*
:Probieren Sie es online aus!
Python 3 ,
6559 BytesRekursive Lösung mit
L
,S
und*
:Läuft von vorne durch die Zeichenfolge und ersetzt alle Instanzen von
LS
durchL*
Probieren Sie es online aus!
quelle
blah if s else''
→s and blah
spart sechs Bytes. In Python 2 speichertstr(blah)
→`blah`
weitere drei Bytes für die zweite Lösung.PHP, 82 Byte, lineare Zeit
Überläuft die Eingabe von rechts nach links und ersetzt jedes Zeichen durch den Typ.
Berechnet den Typ anhand des aktuellen und des vorherigen Zeichens (-1 oder 1). Wenn gleich, ändert sich der Typ nicht.
quelle
strtr
PHP , 70 Bytes
L = 1, S = 0, * = 2
Für den letzten Testfall mit den
§
+3 Bytes wirdmb_substr
stattdessen Multibyte-Unterstützung benötigtsubstr
Probieren Sie es online aus!
PHP , 71 Bytes
L = 1, S = 0, * = 2
Probieren Sie es online aus!
PHP , 74 Bytes
Probieren Sie es online aus!
quelle
$s=&$argn
ziemlich schlau ! Ich bin mir ziemlich sicher, dass es eine bessere Antwort gibt;) Hoffentlich kommt jemand darauf :)mb_substr
anstattsubstr
wenn die Eingabe nicht im einfachen ASCII-Bereich liegt. Muss der letzte Testfall unterstützt werden?§