Wenn eine Zeichenfolge T der Länge K erscheint K oder mehrmals in einem String S , dann ist es möglicherweise kommunistisch . Zum Beispiel 10
in 10/10
potentiell kommunistisch, denn es erscheint 2 - mal und ist mit einer Länge von 2 . Beachten Sie, dass sich diese Teilzeichenfolgen nicht überlappen können.
Eine kommunistische Transformation ist eine Transformation , bei der diese Zeichenfolge T verwendet und jedes Zeichen t i von T zum i- Vorkommen von T in S verschoben wird . Für das vorige Beispiel würde die kommunistische Transformation also nachgeben 1/0
; Das erste Zeichen von 10
ersetzt 10
das erste Mal 10
und 0
das zweite Mal.
Eine kommunistische Normalisierung ist eine Funktion, die alle diese Zeichenketten T mit K ≥ 2 nimmt und eine kommunistische Transformation an ihnen durchführt.
Einige Besonderheiten des Algorithmus:
- Führen Sie kommunistische Transformationen mit den längsten gültigen Zeichenfolgen T zuerst durch . Favor die ersten Vorkommen von T .
- Führen Sie dann kommunistische Transformationen für die nächstlängsten Zeichenfolgen durch, dann für die nächstlängsten ... usw.
- Wiederholen Sie diesen Vorgang, bis keine derartigen Zeichenfolgen mehr in der Zeichenfolge vorhanden sind.
Beachten Sie, dass einige Zeichenfolgen, z. B. das Beispiel "Hallo, Hallo" in den Testfällen, auf zwei verschiedene Arten interpretiert werden können. Sie können ell
für T verwenden , aber Sie können auch verwenden llo
. In diesem Fall kann Ihr Code eine der beiden Optionen auswählen. Der gezeigte Testfall wird verwendet llo
, Sie erhalten jedoch möglicherweise eine andere und gleichermaßen gültige Ausgabe.
Ihre Aufgabe ist es, die kommunistische Normalisierung umzusetzen. Die Eingabe besteht immer nur aus druckbaren ASCII-Zeichen (0x20 bis 0x7E, Leerzeichen bis Tilde). Sie können ein Programm oder eine Funktion schreiben, um diese Aufgabe zu lösen. Die Eingabe kann als Zeile aus STDIN, String / Character-Array-Argument, Argument aus ARGV usw. übernommen werden.
Testfälle
'123' -> '123'
'111' -> '111'
'1111' -> '11'
'ABAB' -> 'AB'
'111111111' -> '111'
'asdasdasd' -> 'asd'
'10/10' -> '1/0'
'100/100+100' -> '1/0+0'
' + + ' -> ' + '
'Hello, hello, dear fellow!' -> 'Hel he, dear feow!' OR 'Heo hl, dear flow!'
'11122333/11122333/11122333' -> '112/13' OR '132/23'
'ababab1ababab' -> 'a1bab'
'1ab2ab3ab4ab5ab6' -> '1a2b3a4b5ab6'
Testfall ausgearbeitet
Format ist 'string', 'substring'
bei jedem Schritt der Ersetzung. Ersetzte Bits werden in eckige Klammern gesetzt.
'11[122]333/11[122]333/11[122]333', '122'
'111[333]/112[333]/112[333]', '333'
'1113/11[23]/11[23]', '23'
'11[13]/112/1[13]', '13'
'1[11]/[11]2/13', '11'
'1[/1]12[/1]3', '/1'
'112/13', ''
Ein weiterer Testfall:
'Hello, hello, dear fellow!', 'llo'
'Hel, hel, dear feow!', 'l,'
'Hel he, dear feow!', ''
Referenzcode (Python)
Dies kann hilfreich sein, um den Algorithmus zu visualisieren.
#!/usr/bin/env python
import re
def repeater(string):
def repeating_substring(substring):
return (string.count(substring) == len(substring)) and string.count(substring) > 1
return repeating_substring
def get_substrings(string):
j = 1
a = set()
while True:
for i in range(len(string) - j+1):
a.add(string[i:i+j])
if j == len(string):
break
j += 1
return list(a)
def replace_each_instance(string, substring):
assert `string`+',', `substring`
for i in substring:
string = re.sub(re.escape(substring), i, string, 1)
return string
def main(s):
repeats = repeater(s)
repeating_substr = filter(repeater(s), get_substrings(s))
while repeating_substr:
repeating_substr.sort(lambda x,y: cmp(len(y), len(x)))
s = replace_each_instance(s, repeating_substr[0])
repeating_substr = filter(repeater(s), get_substrings(s))
return s
assert main('123') == '123'
assert main('111') == '111'
assert main('1111') == '11'
assert main('ABAB') == 'AB'
assert main('111111111') == '111'
assert main('asdasdasd') == 'asd'
assert main('10/10') == '1/0'
assert main('100/100+100') == '1/0+0'
assert main(' + + ') == ' + '
assert main('Hello, hello, dear fellow!') == 'Hel he, dear feow!'
assert main('11122333/11122333/11122333') == '112/13'
Vielen Dank an @ ConorO'Brien für die Veröffentlichung der ursprünglichen Idee dieser Herausforderung.
ababab1ababab
,1ab2ab3ab4ab5ab6
ab
kommt in beiden Saiten mindestens zweimal vor.Antworten:
Pyth, 22 Bytes
Testsuite
Überprüfen Sie Folgendes, um zu sehen, was das Programm tatsächlich tut:
Interna
Insbesondere verwendet das Programm immer die endgültig auftretende Ersetzung der längsten Ersetzungen.
Erläuterung:
quelle
JavaScript (ES6), 121 Byte
Stimmt rekursiv mit dem Muster überein:
... bis das Muster nicht mehr gefunden wird. (Dies garantiert, dass die längste Zeichenfolge zuerst verarbeitet wird.)
Anschließend werden die "kommunistischen Transformationen" für das zuletzt gefundene Muster ausgeführt, indem das Match aufgeteilt und die einzelnen Charaktere des Matches zusammengefügt werden. (
map
wird für diesen Zweck verwendet. Schade,join
nimmt keinen Rückruf entgegen.)Es wiederholt sich schließlich auf dieser neuen Zeichenfolge, bis es nicht mehr kommunistisch ist .
Testfälle:
Code-Snippet anzeigen
quelle
Sauber ,
420... 368 BytesProbieren Sie es online!
quelle