String.prototype.isRepeated

41

UPDATE : isaacg's Pyth Submission ist der Gewinner!


Viele von Ihnen müssen gehört haben, dass es eine coolere Version von JavaScript in der Stadt gibt (lesen Sie ES6), die eine Methode String.prototype.repeathat, mit der Sie dies tun können

"Hello, World!".repeat(3)

und bekomme

"Hello, World!Hello, World!Hello, World!"

als Ausgabe.

Ihre Aufgabe ist es, eine Funktion oder ein Programm in einer Sprache Ihrer Wahl zu schreiben, die erkennen, ob eine Zeichenkette einer solchen Transformation unterzogen wurde.

Das heißt, die Eingabezeichenfolge kann als genaue nWiederholung einer kleineren Zeichenfolge dargestellt werden. Die Ausgabe (als return-Anweisung der Funktion oder STDOUT) sollte wahr sein, wenn die Zeichenfolge fehlerhaft sein kann, oder wenn die Zeichenfolge nicht als Wiederholung einer kleineren Zeichenfolge dargestellt werden kann.

Einige Beispieleingaben:

"asdfasdfasdf"  // true
"asdfasdfa"     // false
"ĴĴĴĴĴĴĴĴĴ"     // true
"ĴĴĴ123ĴĴĴ123"  // true
"abcdefgh"      // false

Beachten Sie, dass die letzte Eingabe falsch ist und ndaher größer als sein sollte1

Regeln vervollständigen

  • Schreiben Sie eine Funktion / ein Programm in einer beliebigen Sprache, um (über Funktionsargumente / Befehlszeilenargumente / STDIN) eine Zeichenfolge einzugeben
  • Gibt den Wahrheitswert zurück / druckt ihn aus, wenn die angegebene Zeichenfolge durch exakte Wiederholung einer kleineren Zeichenfolge gebildet wird, die mindestens zweimal wiederholt wird.
  • Die maximale Größe der Eingabezeichenfolge ist idealerweise Unendlich
  • String kann alle möglichen ASCII-Zeichen enthalten
  • Dies ist ein so dass der kleinste Code in Zeichen gewinnt.
Optimierer
quelle
Was soll "" - der leere String - zurückgeben? (Es enthält eine unendliche Anzahl von Kopien der leeren Zeichenfolge.)
billpg
@billpg falscher Wert
Optimierer
Brechen Sie mit Stimmen ab? Die übliche Praxis ist, glaube ich, die frühere Einreichung (die erste, die bis zur Punktzahl golfen hat). Aber ich bin mir nicht sicher, ob das irgendwo als Standardbindungsbrecher vermerkt ist, also liegt es letztendlich an Ihnen.
Martin Ender
Die Zeit zwischen ihrer Entsendung beträgt nur 30 Minuten. Ich werde das nicht für ausreichend halten, um zu gewinnen :). Da sich diese Zeit jetzt nicht ändert, aber die Stimmen können, bin ich mit den Stimmen gegangen
Optimizer
Diese Frage sollte in xnor umbenannt werden :) Er ist der Mann!
Silviu Burcea

Antworten:

16

Pyth , 9

/:+zz1_1z

Oder

}z:+zz1_1

Dies sind beide enge Übersetzungen von @ xnors Python-Antwort, mit der Ausnahme, dass sie Eingaben von STDIN entgegennehmen und sie ausdrucken. Das erste ist äquivalent zu:

z = input()
print((z+z)[1:-1].count(z))

0 für falsch, 1 für wahr.

Die zweite Zeile entspricht:

z = input()
print(z in (z+z)[1:-1])

Falsch für Falsch, wahr für wahr.

Pyths offizieller Compiler hatte einen Fehler im Zusammenhang mit dem zweiten, den ich gerade gepatcht habe. Der erste ist also meine offizielle Einreichung.

isaacg
quelle
Ich habe nur nach einer Möglichkeit gesucht, Sie über diesen Fehler zu informieren (der Boolesche Wert wird nicht gedruckt). Ich habe nicht an die erste gedacht und die Verwendung xwar zu lang ...
Dennis
Ja, der Fehler ist jetzt behoben. Wenn Sie Fehler melden möchten, können Sie auch ein Problem auf der Github-Website eröffnen: github.com/isaacg1/pyth/issues
isaacg
Oh, da ist es. Ich kenne mich mit GitHub nicht aus und habe das Navigationsfeld auf der rechten Seite nie bemerkt ...
Dennis
81

Python (24)

lambda s:s in(s+s)[1:-1]

Überprüft, ob die Zeichenfolge eine zweimal verkettete Teilzeichenfolge ist, wobei das erste und das letzte Zeichen entfernt werden, um triviale Übereinstimmungen zu vermeiden. Wenn ja, muss es sich um eine nichttriviale zyklische Permutation von sich selbst und damit um die Summe der wiederholten Segmente handeln.

xnor
quelle
8
Eine einfache Übersetzung in Golfscript ergibt 10 Zeichen:..+);(;\?)
Justin
3
Ich verstehe nicht ganz, wie das funktioniert. Können Sie ein manuell erklärtes Beispiel geben, wie dies mit einer Zeichenfolge umgehen würde?
Nzall
8
@NateKerkhofs nehmen abcabc. s+smacht es zu abcabcabcabc. die [1:-1]hiebe der beiden enden nachgeben bcabcabcabcab. und dann s in ...versucht, abcabcals Teilzeichenfolge davon zu finden . Diese Teilzeichenfolge kann in keiner der ursprünglichen Hälften gefunden werden, da beide gekürzt wurden und sich daher über beide Hälften erstrecken müssen. Insbesondere muss es vor seinem Start ein eigenes Ende haben, was bedeutet, dass es aus identischen (wiederholten) Teilzeichenfolgen bestehen muss.
Martin Ender
6
Sie hacken es, nachdem Sie es verdoppelt haben. abwird ababwird ba, also gibt es false zurück, während aawird aaaawird aa, was true zurückgibt.
Histocrat
1
@SargeBorsch Es funktioniert genauso: qweqweqwein weqweqweqweqweqwist True.
17.
30

Regex (ECMAScript-Variante), 11 Byte

Klingt nach einem Job für Regex!

^([^]+)\1+$

Teste es hier.

Ich habe mich für ECMAScript entschieden, weil es (wie ich weiß) die einzige Variante ist, die [^]zu einem Zeichen passt. In allen anderen Fällen benötige ich entweder eine Markierung, um das Verhalten zu ändern, .oder verwende [\s\S]eine drei Zeichen längere Markierung.

Je nachdem, wie wir das Flag zählen, könnte das natürlich ein Byte kürzer sein. Wenn wir z. B. Muster + Flags zählen (z. B. Trennzeichen ignorieren), ist dies das PCRE / Perl-Äquivalent

/^(.+)\1+$/s

Das sind 10 Bytes, wobei die Begrenzer ignoriert werden.

Teste es hier.

Dies entspricht nur Zeichenfolgen, die aus mindestens zwei Wiederholungen einer Teilzeichenfolge bestehen.

Hier ist eine vollständige 26-Byte-ES6-Funktion, aber ich behaupte, dass Einsendungen von regulären Ausdrücken allgemein gültig sind:

f=s->/^([^]+)\1+$/.test(s)
Martin Ender
quelle
^(.+)\1+$funktioniert bei mir, das sind 9 bytes. Funktioniert es bei dir nicht?
Optimierer
@Optimizer Versuchen Sie einen String mit Zeilenumbrüchen.
Martin Ender
Ich habe es versucht asd\nasd\nasd\n. Es funktioniert
Optimierer
@Optimizer refiddle.com/refiddles/5417fb2475622d4df7e70a00 scheint nicht für mich zu funktionieren (und sollte es auch nicht)
Martin Ender
Ja, das geht nicht. Vielleicht entgeht es dem, \ wenn ich \nmanuell schreibe
Optimizer
12

CJam, 9

q__+)@+#)

Ähnlich wie die Idee von xnor.

q      " Read input. ";
__+    " Duplicate twice and concatenate them together. ";
)      " Remove the last character of the longer string. ";
@+     " Insert that character at the beginning of the shorter string. ";
#)     " Find the shorter string in the longer string, and increase by one. ";
jimmy23013
quelle
+1 verpflichtet, dies vor meiner eigenen CJam-Antwort zu verbessern
Digital Trauma
Warum die Notwendigkeit für das Finale )? Ich denke, es ist vernünftig, -1 bedeutet FALSCH und> = 0 bedeutet WAHR
Digitales Trauma
@DigitalTrauma Ich denke, 0 ist in CJam falsch ... für Betreiber wie gund ?.
Jimmy23013
@DigitalTrauma: Ob es letztendlich benötigt wird, hängt vom OP ab, aber streng genommen wird in CJam nur Null als falsch angesehen.
Dennis
@ user23013 @Dennis Aber was ist mit dem Suchoperator #? Sicherlich ist das Ergebnis davon auch aus der Perspektive von Erfolg gegen Misserfolg "wahr"?
Digital Trauma
7

APL, 11

2<+/x⍷,⍨x←⍞

Bei der Erläuterung werden
Zeichenfolgeneingaben vom Bildschirm übernommen,
x←die einer Variablen x
,⍨zugewiesen werden, die die Zeichenfolge mit der
x⍷Suche xin der resultierenden Zeichenfolge verknüpft. Gibt ein Array zurück, das aus Einsen an der Startposition einer Übereinstimmung und Nullen an einer anderen Stelle besteht.
+/summiert die Array-
2<Prüfung, wenn die Summe größer als 2 ist (da es 2 triviale Übereinstimmungen gibt)

TwiNight
quelle
7

CJam, 10 Bytes

Ich habe den CJam-Fehler entdeckt. Meine erste Antwort, damit kann man wohl noch etwas mehr golfen:

q__+(;);\#

Ausgänge -1 für FALSE und eine Zahl> = 0 für TRUE

Digitales Trauma
quelle
5
Willkommen im Klub!
Dennis
5

GolfScript, 10 Bytes

..+(;);\?)

Eine weitere Implementierung von xnors cleverer Idee.

Dennis
quelle
Hahaha, ich habe das gerade vor einer Minute gepostet: codegolf.stackexchange.com/questions/37851/… . Ich dachte darüber nach, es als Antwort zu veröffentlichen, fand aber, dass triviale Übersetzungen uninteressant sind.
Justin
Ich habe diesmal sogar nach neuen Antworten gesucht, aber nicht nach neuen Kommentaren ... In Ihrem Code fehlt das )allerdings; Wenn es keine Übereinstimmung gibt, wird gedruckt -1. Wenn du das als Antwort posten willst, lösche ich gerne meine.
Dennis
Ich fügte hinzu, )kurz bevor du deine Antwort gepostet hast (ich habe den Kommentar bearbeitet)
Justin
1
Verbesserte Version (in CJam): q__+)@+#). In GolfScript funktioniert es nicht.
Jimmy23013
1
@ user23013: Nicht schon wieder. Ich wollte das gerade posten! Mittlerweile gibt es zu viele CJammer ...: P
Dennis
3

Python - 59 57

lambda s:any([s*n==s[:n]*len(s)for n in range(2,len(s))])
Falko
quelle
3

Pure Bash, 30 Bytes

Einfache Portierung der cleveren Antwort von @ xnor :

[[ ${1:1}${1:0: -1} =~ "$1" ]]

Der Exit-Code ist 0 für TRUE und 1 für FALSE:

$ for s in 'Hello, World!Hello, World!Hello, World!' 'asdfasdfasdf' 'asdfasdfa' 'ĴĴĴĴĴĴĴĴĴ' 'ĴĴĴ123ĴĴĴ123' 'abcdefgh'; do echo "./isrepeated.sh "\"$s\"" returns $(./isrepeated.sh "$s"; echo $?)"; done
./isrepeated.sh "Hello, World!Hello, World!Hello, World!" returns 0
./isrepeated.sh "asdfasdfasdf" returns 0
./isrepeated.sh "asdfasdfa" returns 1
./isrepeated.sh "ĴĴĴĴĴĴĴĴĴ" returns 0
./isrepeated.sh "ĴĴĴ123ĴĴĴ123" returns 0
./isrepeated.sh "abcdefgh" returns 1
$ 

Hinweis =~innerhalb [[ ... ]]ist der Regex - Operator in bash . Jedoch „kann ein beliebiger Teil des Musters zitiert werden sie zu zwingen , als String angepasst werden“ . Wie so oft bei bash, ist es sehr wichtig, die richtigen Anführungszeichen zu setzen - hier wollen wir nur auf einen String-Submatch und nicht auf eine Regex-Übereinstimmung prüfen.

Digitales Trauma
quelle
3

TI-BASIC - 32

Ich dachte, ich würde eine Token-Sprache ausprobieren. Führen Sie den Befehl mit der Zeichenfolge in Ans aus, und geben Sie bei false 0 und bei true die Länge der wiederholten Zeichenfolge zurück.

inString(sub(Ans+Ans,1,2length(Ans)-1),sub(Ans,length(Ans),1)+Ans

Erstaunlich, wie es ein Einzeiler ist.

Josiah Winslow
quelle
Aber ... aber ... ich wollte TI-BASIC verwenden: P +1
Timtech
@Timtech Hinweis für alle, die in TI-BASIC die Manipulation von Zeichenfolgen versuchen: Versuchen Sie nicht, in TI-BASIC die Manipulation von Zeichenfolgen zu versuchen. : P Das war so schwer zu machen und zu optimieren.
Josiah Winslow
Gute Idee. Die Manipulation von Saiten ist eine der schwierigsten Aufgaben. Ich habe jedoch mehrere Antworten wie diese gepostet, daher schätze ich, dass Sie jetzt einen Konkurrenten haben;)
Timtech
Her damit! : P
Josiah Winslow
3

ECMAScript 6 (189)

(function(){var S=String.prototype,r=S.repeat;S.isRepeated=function(){return!1};S.repeat=function(c){var s=new String(r.call(this,c));if(c>1)s.isRepeated=function(){return!0};return s}}());

 

< console.log("abc".isRepeated(),"abc".repeat(10).isRepeated());
> false true

Das ist doch die einzig gültige Lösung? Beispielsweise wird das Wort (Zeichenfolge) nananicht unbedingt aus erstellt"na".repeat(2)

Mardoxx
quelle
"nana"ist nicht, aber die Frage ist nicht zu testen, ob .repeatverwendet wurde oder nicht. Eher, ob die Zeichenfolge eine wiederholte ist oder nicht
Optimizer
Ich weiß, ich habe nur versucht, ein schlauer Arsch zu sein: P
Mardoxx
2

ECMAScript 6 (34 36 )

Eine weitere Antwort von ES6, aber ohne den Trickrepeat von xnor zu verwenden :

f=i=>(i+i).slice(1,-1).contains(i)

Muss in der Konsole eines ES6-fähigen Browsers wie Firefox ausgeführt werden.

Ingo Bürk
quelle
2

C 85

l,d;f(s){return l=strlen(s),strstr(d,strcpy(strcpy(d=alloca(l*2+1),s)+l,s)-1)-d-l+1;}

Es hat sich als ziemlich lang herausgestellt, aber externe Funktionen sind immer so. Mir fiel ein, dass ich jede String-Funktion neu schreiben konnte, indem ich sie durch eine Schleife oder eine rekursive ersetzte. Aber meiner Erfahrung nach würde es länger dauern und ehrlich gesagt möchte ich das nicht ausprobieren.

Nach einigen Recherchen sah ich Lösungen für hohe Leistung, aber nicht so clever (und kurz) wie die von xnor. nur um originell zu sein ... ich habe die gleiche idee in c umgeschrieben.

Erläuterung:

int length, 
    duplicate;
int is_repetition(char *input)
{
    // length = "abc" -> 3
    length = strlen(input);
    // alloca because the function name is as long as "malloc" 
    // but you don't have to call free() because it uses the stack
    // to allocate memory
    // duplicate = x x x x x x + x
    duplicate = alloca(length*2 + 1);
    // duplicate = a b c 0 x x + x
    strcpy(duplicate, input);
    // duplicate = a b c a b c + 0
    strcpy(duplicate + length, input);
    if (strstr(duplicate,duplicate + length - 1) != duplicate + length - 1)
        // repetition
        // e.g. abab -> abababab -> aba[babab]
        // -> first occurence of [babab] is not aba[babab]
        // but a[babab]ab -> this is a repetition
        return 1;
    else
        // not repetition
        // e.g. abc -> abcabc -> ab[cabc]
        // -> first occurence of [cabc] is ab[cabc]
        // it matches the last "cabc"
        return 0;
}
bebe
quelle
1

ECMAScript 6 (59 62 67 73 )

Kein Gewinner, aber es scheint, dass es in ES6 mindestens eine Antwort auf diese Frage geben sollte, die tatsächlich die repeatFunktion verwendet:

f=i=>[...i].some((_,j)=>i.slice(0,j).repeat(i.length/j)==i)

Muss in der Konsole eines ES6-fähigen Browsers wie Firefox ausgeführt werden.

Es macht eine Menge unnötiger Iterationen, aber warum sollte es länger dauern, nur um das zu vermeiden, oder?

  • Edit # 1: Sparte ein paar Bytes, indem du es in eine Funktion umwandelst. Danke an Optimizer!
  • Edit # 2: Danke an hsl für den Spread-Operator-Trick, um mehr Bytes zu sparen!
  • Edit # 3: Und danke an Rob W. für weitere 3 Bytes!
Ingo Bürk
quelle
Sie können es einfach in eine Funktion umwandeln, um dort mehr Bytes zu sparen
Optimizer
@Optimizer Stimmt, ich denke, es muss nicht "stdin" sein. Sie werden Ihrem Namen gerecht :)
Ingo Bürk
Ich habe nicht getestet, aber Sie sollten die nutzen können Spread Operator für [...i]statti.split('')
NinjaBearMonkey
1
@hsl Verrückt, das funktioniert. Ich wusste nicht, dass der Spread-Operator so funktioniert. Ursprünglich habe ich verzweifelt versucht, damit ein Array mit dem Bereich zu erstellen 0..N. Vielen Dank!
Ingo Bürk
1
.slice(0,j)ist ein Zeichen kürzer als .substr(0,j). Außerdem kann die Konvertierung in eine Ganzzahl, die unnötig zu |0sein scheint , entfernt werden (wenn Sie diese Option verwenden, |0wird die Nützlichkeit der Methode verringert, da sie bei Wiederholungen, die 2 ^ 31 überschreiten, fehlschlägt).
Rob W
0

Java 8, 28 Bytes

s->s.matches("(?s)(.+)\\1+")

Probieren Sie es online aus.

Erläuterung:

Überprüft, ob der Eingabe-String mit dem regulären Ausdruck übereinstimmt. Dabei wird String#matchesimplizit hinzugefügt ^...$, dass er mit dem gesamten String übereinstimmt.
Erklärung des regulären Ausdrucks selbst:

^(s?)(.+)\1+$
^                Begin of the string
 (s?)            Enable DOTALL-mode, where `.` also matches new-lines
     (           Open capture group 1
      .+          One or more characters
        )        Close capture group 1
         \1+     Plus the match of the capture group 1, one or more times
            $    End of the string

Es wird also grundsätzlich geprüft, ob eine Teilzeichenfolge zwei- oder mehrmals wiederholt wird (Unterstützung von Zeilenumbrüchen).

Kevin Cruijssen
quelle