Lokale Zeiträume
Nehmen Sie eine nicht leere Zeichenfolge s . Die lokale Periode von s am Index i ist die kleinste positive ganze Zahl n, so dass wir für jede 0 ≤ k <n s [i + k] = s [i-n + k] haben, wenn beide Seiten definiert sind. Alternativ ist es die minimale Länge einer nicht leeren Zeichenfolge w, so dass, wenn die Verkettung ww neben s platziert wird, so dass die zweite Kopie von w am Index i von s beginnt , die beiden Zeichenfolgen übereinstimmen, wo immer sie sich überlappen.
Als Beispiel berechnen wir die lokale Periode von s = "abaabbab" bei (0-basiertem) Index 2.
- Versuchen Sie n = 1 : dann ist s [2 + 0] ≠ s [2-1 + 0] , daher ist diese Auswahl nicht korrekt.
- Versuchen n = 2 : dann ist s [2 + 0] = s [2-2 + 0], aber s [2 + 1] ≠ s [2-2 + 1] , also ist dies auch nicht korrekt.
- Versuchen Sie es mit n = 3 : dann s [2 + 0-3] nicht definiert, s [2 + 1] = s [2-3 + 1] und s [2 + 2] = s [2-3 + 2] . Somit ist die Ortszeit 3.
Hier ist eine Visualisierung der lokalen Perioden mit der zweiten Definition, wobei der Übersichtlichkeit halber Semikolons zwischen den beiden Kopien von w eingefügt sind :
index a b a a b b a b period
0 a;a 1
1 b a;b a 2
2 a a b;a a b 3
3 a;a 1
4 b b a b a a;b b a b a a 6
5 b;b 1
6 a b b;a b b 3
7 b a;b a 2
Beachten Sie, dass w nicht unbedingt eine Unterzeichenfolge von s ist . Dies geschieht hier im Fall von Index-4.
Die Aufgabe
Ihre Eingabe ist eine nicht leere Zeichenkette s von Klein ASCII - Zeichen. Falls gewünscht, kann es als Liste von Zeichen verwendet werden. Ihre Ausgabe soll die Liste sein, die die lokale Periode von s an jedem ihrer Indizes enthält. Im obigen Beispiel wäre die korrekte Ausgabe [1,2,3,1,6,1,3,2] .
Die niedrigste Byteanzahl in jeder Sprache gewinnt. Es gelten die Standardregeln für Code-Golf .
Testfälle
a -> [1]
hi -> [1, 2]
www -> [1, 1, 1]
xcxccxc -> [1, 2, 2, 5, 1, 3, 2]
abcbacb -> [1, 4, 7, 7, 7, 3, 3]
nininini -> [1, 2, 2, 2, 2, 2, 2, 2]
abaabbab -> [1, 2, 3, 1, 6, 1, 3, 2]
woppwoppw -> [1, 4, 4, 1, 4, 4, 4, 1, 4]
qwertyuiop -> [1, 10, 10, 10, 10, 10, 10, 10, 10, 10]
deededeededede -> [1, 3, 1, 5, 2, 2, 5, 1, 12, 2, 2, 2, 2, 2]
abababcabababcababcabababcaba -> [1, 2, 2, 2, 2, 7, 7, 7, 7, 2, 2, 2, 19, 19, 5, 5, 2, 5, 5, 12, 12, 2, 2, 2, 7, 7, 5, 5, 2]
qwertyuiop
ist w eine gedrehte Version vonqwertyuiop
. Siehe auch das Beispiel bei Index 4: w ist nicht unbedingt ein Teilstring von s .;
in Ihrem Beispiel ist). Das würde die führende 1 loswerden.Antworten:
Retina ,
89-86BytesProbieren Sie es online! Bearbeiten: 3 Bytes dank @MartinEnder gespeichert. Erläuterung:
Teilen Sie die Eingabe bei jedem Zeichen auf, und erstellen Sie ein Zeilenpaar, eines für das Präfix und eines für das Suffix des Präfix.
Führen Sie den Rest des Skripts für jedes resultierende Paar aus.
Finde alle überlappenden Übereinstimmungen und liste die Ergebnisse auf. (Siehe unten.)
Verwerfen Sie das leere Streichholz.
Nimm die Länge jedes Matches.
Numerisch sortieren.
Nimm den Kleinsten.
Der Abgleich funktioniert, indem Präfix und Suffix in drei Teile geteilt werden. Es sind vier gültige Fälle zu berücksichtigen:
Der reguläre Ausdruck erlaubt daher nur, dass A und C gleichzeitig auf einer Seite übereinstimmen.
quelle
$&$'
ist gleich$<'
und die Berechnungsleitungslängen sind kürzer mit%C`.
. tio.run/##K0otycxLNPz/X49LJeHQNhUb9UPbuPQ14mr0tDUPbdPT1o/…Java 8,
167154152 Bytes-2 Bytes dank @ceilingcat .
Probieren Sie es online aus.
Erläuterung:
quelle
JavaScript (ES6), 84 Byte
Nimmt die Eingabe als Array von Zeichen.
Testfälle
Code-Snippet anzeigen
quelle
Ruby ,
104102 BytesProbieren Sie es online!
Ein Lambda, das eine Zeichenfolge akzeptiert und ein Array zurückgibt.
-2 Byte: Tauschen Sie Bereichsendpunkte mit indexgebundenen Schutzvorrichtungen aus
Ungolfed:
quelle
Japt ,
3332 Bytes1 Byte dank @Shaggy gespeichert
Online testen!
Erläuterung
Mein erster Gedanke war, einfach jedes Zeichen in der linken Teilzeichenfolge mit dem entsprechenden Zeichen in der rechten Teilzeichenfolge zu vergleichen, wie in der JS-Antwort. Das würde jedoch nicht funktionieren, da Japts Methode, um ein Zeichen zu erhalten, nur an das andere Ende der Zeichenkette übergeht, wenn der Index negativ oder zu groß ist.
Stattdessen erstellt meine Lösung einen regulären Ausdruck aus der zweiten Teilzeichenfolge und testet ihn auf der ersten Teilzeichenfolge. Nehmen wir
abaabbab
als Beispiel das fünfte Objekt im Testfall :Der Haupttrick ist das
^
man unendlich Übereinstimmungen finden kann, bis ein tatsächlicher Charakter gefunden wurde. Auf diese Weise können wir eine beliebige Anzahl von Zeichen vom Beginn der Regex ignorieren und gleichzeitig sicherstellen, dass alle anderen Zeichen nacheinander abgeglichen werden und am Ende der Testzeichenfolge enden.Ich bin mir nicht sicher, ob ich das sehr gut erklärt habe. Lassen Sie es mich wissen, wenn Sie etwas klarstellen möchten oder etwas anderes, das erklärt werden sollte.
quelle
C (GCC) ,
143142140139128126123 Bytes!b&&printf
zub||printf
.for
Loop-Klammern wurden durch Jonglieren derprintf
Platzierung entfernt.b+=S[i+k]!=S[i-n+k]
zub|=S[i+k]-S[i-n+k]
.l=strlen(S)
, beide Zeichenkettenbehandlungsschleifen zu konditionieren, um beim Erreichen des Zeichenkettenendes (ein Null-Byte'\0'
) zu brechen .i-n+k>~0
zui-n>~k
.b||printf("|"),n++
ist äquivalent zun+=b||printf("|")
.Probieren Sie es online!
quelle
b||printf("%d,",n)
die for-Schleifei,b,k,n,l;f(char*S){for(l=strlen(S),i=-1;++i<l;)for(b=n=1;b;b||printf("%d,",n),n++)for(b=k=0;k<n;k++)i+k<l&i-n+k>=0&&(b+=S[i+k]!=S[i-n+k]);}
Python 2 , 115 Bytes
Probieren Sie es online!
quelle