String.prototype.isRepeated


41

AGGIORNAMENTO : la presentazione di Pyth di isaacg è il vincitore!


Molti di voi devono aver sentito che in città esiste una versione più interessante di JavaScript (leggi ES6) che ha un metodo String.prototype.repeatche puoi fare

"Hello, World!".repeat(3)

e prendi

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

come uscita.

Il tuo compito è scrivere una funzione o un programma in una lingua a tua scelta che rilevi se una stringa è stata sottoposta a tale trasformazione.

cioè la stringa di input può essere rappresentata come una nripetizione esatta dei tempi di una stringa più piccola. L'output (come istruzione return della funzione o STDOUT) dovrebbe essere veritiero se la stringa può essere o falsa se la stringa non può essere rappresentata come ripetizione di una stringa più piccola.

Alcuni input di esempio:

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

Si noti che l'ultimo input è falso, quindi ndovrebbe essere maggiore di1

Regole complete

  • Scrivi una funzione / programma in qualsiasi lingua per inserire (tramite argomento funzione / riga di comando args / STDIN) una stringa
  • Restituisce / stampa il valore di verità se la stringa data viene formata tramite una ripetizione esatta di una stringa più piccola, ripetendo almeno due volte.
  • La dimensione massima della stringa di input è idealmente Infinity
  • La stringa può avere tutti i possibili caratteri ASCII
  • Questo è un vince il codice più piccolo in caratteri.

Cosa dovrebbe "" - la stringa vuota - restituire? (Contiene un numero infinito di copie della stringa vuota.)
billpg

@billpg valore falsy
Optimizer

Stai rompendo i voti? Penso che la pratica comune sia una presentazione precedente (beh, la prima che è stata portata a punteggio ridotto). Ma non sono sicuro che sia scritto come il tie-breaker predefinito ovunque, quindi alla fine dipende da te.
Martin Ender,

Il tempo che intercorre tra la loro pubblicazione è di soli 30 minuti. Non lo considero sufficiente per vincere :). Dato che quel momento non cambierà ora, ma i voti possono, sono andato con i voti
Optimizer

Questa domanda dovrebbe essere rinominata in xnor :) Lui è l'uomo!
Silviu Burcea,

Risposte:


16

Pyth , 9

/:+zz1_1z

O

}z:+zz1_1

Queste sono entrambe traduzioni vicine della risposta python di @ xnor, tranne per il fatto che prendono input da STDIN e lo stampano. Il primo equivale a:

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

0 per Falso, 1 per Vero.

La seconda riga equivale a:

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

Falso per falso, vero per vero.

Il compilatore ufficiale di Pyth aveva un bug relativo al secondo, che ho appena corretto, quindi il primo è il mio invio ufficiale.


Stavo solo cercando un modo per informarti di quel bug (il booleano non viene stampato). Non pensavo al primo e l'utilizzo xera troppo lungo ...
Dennis

Sì, il bug è stato corretto ora. Inoltre, se vuoi segnalare bug, un buon modo potrebbe essere quello di aprire un problema sul sito github, qui: github.com/isaacg1/pyth/issues
isaacg

Oh, eccolo . Non conosco GitHub e non ho mai notato il pannello di navigazione sulla destra ...
Dennis

81

Python (24)

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

Verifica se la stringa è una sottostringa di se stessa concatenata due volte, eliminando il primo e l'ultimo carattere per evitare corrispondenze banali. Se lo è, deve essere una permutazione ciclica non banale di se stessa, e quindi la somma di segmenti ripetuti.


8
Una banale traduzione in Golfscript produce 10 caratteri:..+);(;\?)
Justin

3
Non capisco bene come funzioni. Puoi dare un esempio spiegato manualmente di come gestire una stringa?
Nzall,

8
@NateKerkhofs take abcabc. s+slo trasforma in abcabcabcabc. le [1:-1]braciole delle due estremità cedono bcabcabcabcab. e poi s in ...cerca di trovarlo abcabccome sottostringa di quello. Questa sottostringa non può essere trovata in nessuna delle due metà originali, perché entrambe sono state accorciate, quindi deve coprire entrambe le metà. In particolare, deve avere una sua fine prima del suo inizio, il che implica che deve essere costituito da sottostringhe identiche (ripetute).
Martin Ender,

6
Lo tagli dopo averlo raddoppiato. abdiventa ababdiventa ba, quindi restituisce falso, mentre aadiventa aaaadiventa aa, che restituisce vero.
histocrat,

1
@SargeBorsch Funziona allo stesso modo: qweqweqwein weqweqweqweqweqwis True.
xnor

30

Regex (sapore ECMAScript), 11 byte

Sembra un lavoro per regex!

^([^]+)\1+$

Provalo qui.

Ho scelto ECMAScript, perché è l'unico sapore (lo so) in cui [^]corrisponde a qualsiasi personaggio. In tutti gli altri, avrei bisogno di una bandiera per cambiare il comportamento .o l'uso di [\s\S]tre caratteri in più.

A seconda di come stiamo contando la bandiera, questo potrebbe ovviamente essere un byte più breve. Ad esempio se contiamo pattern + flag (ad esempio ignorando i delimitatori), l'equivalente PCRE / Perl sarebbe

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

Che è di 10 byte, ignorando i delimitatori.

Provalo qui.

Questo corrisponde solo alle stringhe che consistono in almeno due ripetizioni di alcune sottostringhe.

Ecco una funzione ES6 completa a 26 byte, ma sostengo che gli invii di espressioni regolari sono generalmente validi:

f=s->/^([^]+)\1+$/.test(s)

^(.+)\1+$funziona per me, che è di 9 byte. Non funziona per te?
Ottimizzatore

@Optimizer Prova una stringa con interruzioni di riga.
Martin Ender,

Ci ho provato asd\nasd\nasd\n. Funziona
Ottimizzatore

@Optimizer refiddle.com/refiddles/5417fb2475622d4df7e70a00 non sembra funzionare per me (e non dovrebbe)
Martin Ender

Sì, non funziona. Forse sfugge a \ quando scrivo \nmanualmente
Optimizer,

12

CJam, 9

q__+)@+#)

Simile all'idea di 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. ";

+1 obbligato a votare questo prima della mia risposta CJam
Digital Trauma,

Perché la necessità del finale )? Penso che sia ragionevole avere -1 FALSO medio e> = 0 VERO medio
Trauma digitale

@DigitalTrauma Penso che 0 sia falsa in CJam ... per operatori come ge ?.
jimmy23013,

@DigitalTrauma: se alla fine è necessario dipende dall'OP, ma in senso stretto solo zero è considerato falsa in CJam.
Dennis,

@ user23013 @Dennis Ma per quanto riguarda l' #operatore find? Sicuramente il risultato è anche "veritiero" dal punto di vista del successo rispetto al fallimento?
Trauma digitale,

7

APL, 11

2<+/x⍷,⍨x←⍞

La spiegazione
prende l'input di stringa dalle
x←assegnazioni di schermate alla variabile x
,⍨concatena la stringa con se stessa
x⍷cerca xnella stringa risultante. Restituisce un array composto da 1 nella posizione iniziale di una corrispondenza e 0 da un'altra parte.
+/somma l'array
2<check se la somma è maggiore di 2 (poiché ci saranno 2 banali corrispondenze)


7

CJam, 10 byte

Ho rilevato il bug di CJam. La mia prima risposta, quindi probabilmente si può giocare ancora un po 'a golf:

q__+(;);\#

Uscite -1 per FALSE e un numero> = 0 per VERO


5
Benvenuto nel club!
Dennis,

5

GolfScript, 10 byte

..+(;);\?)

Ancora un'altra implementazione dell'idea intelligente di xnor.


Hahaha, l'ho appena pubblicato un minuto fa: codegolf.stackexchange.com/questions/37851/… . Ho pensato di pubblicarlo come una risposta, ma ho pensato che traduzioni banali non sono interessanti.
Justin,

Questa volta ho anche cercato nuove risposte, ma non per nuovi commenti ... Il tuo codice manca )però; quando non c'è corrispondenza, verrà stampato -1. Se lo pubblicherai come risposta, eliminerò volentieri il mio.
Dennis,

Ho aggiunto il )poco prima che tu abbia pubblicato la tua risposta (ho modificato il commento)
Justin

1
Versione migliorata (in CJam): q__+)@+#). Non funziona in GolfScript.
jimmy23013,

1
@ user23013: non ancora. Lo stavo solo postando! Ormai ci sono troppi CJammer là fuori ...: P
Dennis,

3

Python - 59 57

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

3

Bash puro, 30 byte

Semplice porta della risposta intelligente di @ xnor :

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

Il codice di uscita è 0 per VERO e 1 per FALSO:

$ 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
$ 

Nota =~all'interno [[ ... ]]è l'operatore regex in bash . Tuttavia "Qualsiasi parte del modello può essere quotata per forzare la corrispondenza come stringa" . Quindi, come spesso accade con bash, ottenere le virgolette giuste è molto importante - qui vogliamo solo verificare la presenza di un invio di stringhe e non una corrispondenza regex.


3

TI-BASIC - 32

Ho pensato di provare un linguaggio tokenizzato. Esegui con la stringa in Ans, restituisce 0 se falso e la lunghezza della stringa ripetuta se vero.

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

Incredibile come sia una fodera.


Ma ... ma ... stavo per usare TI-BASIC: P +1
Timtech,

@Timtech Bene, nota a chiunque cerchi di manipolare le stringhe in TI-BASIC: non provare a manipolare le stringhe in TI-BASIC. : P È stato così difficile da realizzare e ottimizzare.
Josiah Winslow,

Buona idea. La manipolazione delle stringhe è una delle cose più difficili da fare. Tuttavia, ho pubblicato diverse risposte come questa, quindi immagino che tu abbia un concorrente;)
Timtech,

Prendilo! : 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

Sicuramente questa è l'unica soluzione valida? Ad esempio, la parola (stringa) nananon è necessariamente creata da"na".repeat(2)


"nana"non lo è, ma la domanda non sta verificando se è .repeatstato utilizzato o meno. Piuttosto, sia che la stringa sia ripetuta o meno
Optimizer,

Lo so, stavo solo cercando di fare il furbo: P
Mardoxx,

2

ECMAScript 6 (34 36 )

Un'altra risposta ES6, ma senza usare repeate usare il trucco di xnor :

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

Deve essere eseguito nella console di un browser compatibile con ES6 come Firefox.


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;}

Si è rivelato piuttosto lungo ma le funzioni esterne sono sempre così. Mi è venuto in mente che avrei potuto riscrivere ogni funzione di stringa sostituendole con un loop o uno ricorsivo. Ma nella mia esperienza sarebbe risultato più a lungo e francamente non voglio provarlo.

Dopo alcune ricerche ho visto soluzioni ad alte prestazioni ma non intelligenti (e brevi) come quelle di xnor. solo per essere originale ... ho riscritto la stessa idea in c.

spiegazione:

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;
}

1

ECMAScript 6 (59 62 67 73 )

Non è un vincitore, ma sembra che in ES6 dovrebbe esserci almeno una risposta per questa domanda che utilizza effettivamente la repeatfunzione:

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

Deve essere eseguito nella console di un browser compatibile con ES6 come Firefox.

Fa molte iterazioni inutili, ma perché allungarlo solo per evitarlo, giusto?

  • Modifica n. 1: salvato alcuni byte convertendolo in una funzione. Grazie a Optimizer!
  • Modifica n. 2: grazie a hsl per il trucco dell'operatore spread per salvare più byte!
  • Modifica n. 3: E grazie a Rob W. per altri 3 byte!

Puoi semplicemente convertirlo in una funzione per salvare più byte lì
Optimizer

@Optimizer Vero, suppongo che non debba essere "stdin". La tua vita fino al tuo nome :)
Ingo Bürk,

Non ho ancora testato questo, ma si dovrebbe essere in grado di utilizzare l' operatore di diffusione per [...i], invece dii.split('')
NinjaBearMonkey

1
@hsl Crazy, funziona. Non sapevo che l'operatore di diffusione funzionasse così. Inizialmente ho cercato disperatamente di usarlo per creare un array con l'intervallo 0..N. Grazie!
Ingo Bürk,

1
.slice(0,j)è un personaggio più corto di .substr(0,j). Inoltre, la conversione in un numero intero sembra non necessaria |0può essere rimossa (l'utilizzo in |0realtà riduce l'utilità del metodo perché fallirà per le ripetizioni che superano 2 ^ 31).
Rob W,


0

Java 8, 28 byte

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

Provalo online.

Spiegazione:

Verifica se la stringa di input corrisponde alla regex, dove si String#matchesaggiunge implicitamente ^...$per far corrispondere l'intera stringa.
Spiegazione della regex stessa:

^(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

Quindi controlla sostanzialmente se una sottostringa viene ripetuta due o più volte (supportando le nuove linee).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.