Garlandification


38

Ghirlanda di parole

Una parola ghirlanda è una parola che può essere unita come una ghirlanda, perché termina con le stesse lettere con cui inizia. Questi gruppi di lettere possono persino sovrapporsi!

Ad esempio, undergroundè una parola d'ordine ghirlanda3 , perché inizia e termina con gli stessi 3 caratteri und,. Ciò significa che potrebbe essere messo insieme come undergroundergrounderground....

alfalfaè anche una parola ghirlanda! È di ordine 4. Inizia e finisce conalfa . Può essere messe insieme in questo modo: alfalfalfalfa.

Un processo che chiamo ghirlanda è quello in cui una volta determinato l'ordine ndi una parola ghirlanda, prendi la parola originale e aggiungi il segmento richiesto per farla scorrere come una ghirlanda nvolte. Quindi, poiché onionè una 2parola ghirlanda dell'ordine , dovresti prendere onion, tagliare le prime 2lettere per ottenere ione aggiungerle alla fine 2per ottenere onionionion.

Obbiettivo

Crea un programma o una funzione da cui prende input dall'input standard o da un argomento di funzione e stampa o restituisce la parola, ghirlandata.

Tutte le parole saranno minuscole e l'ordine più alto possibile per una parola è length(word) - 1 .

Esempio I / O

"onion"       --> "onionionion"
"jackhammer"  --> "jackhammer"
"abracadabra" --> "abracadabracadabracadabracadabracadabra"
""            --> ""
"zvioz"       --> "zviozvioz"
"alfalfa"     --> "alfalfalfalfalfalfa"
"aaaa"        --> "aaaaaaa"

Questo è , quindi vince il numero minimo di byte.


2
Qualsiasi parola di lettera N inizia con le stesse lettere N con cui termina. Qual è l'ordine massimo che dovrebbe essere considerato?
feersum,

@feersum L'ordine massimo è la lunghezza della parola - 1. Aggiunto al post principale.
Kade,

Devo stampare solo la ghirlanda? o posso forse stamparlo e un'eccezione?
DeadChex,

@DeadChex Non dovrebbero esserci eccezioni.
Kade,

1
@LuisMendo Dovrebbe funzionare per parole arbitrariamente lunghe.
Kade,

Risposte:


12

Pyth, 19 18 byte

+z*>Kf!xz>zT1zl>zK

Provalo online: dimostrazione o cablaggio prova

spiegazioni:

+z*>Kf!xz>zT1zl>zK   implicit: z = input string
     f      1        find the first number T >= 1, which satisfies:
         >zT            all but the first T chars of z
       xz               index of ^ in z
      !                 == 0
    K                store in K
                     the order is length(z) - K
   >K        z       the last K chars
  *                  repeated
              l>zK   len(all but the last K chars) times
+z                   insert z at the beginning

14

Python, 60 byte

f=lambda s,i=1:s.find(s[i:])and f(s,i+1)or(len(s)-i)*s[:i]+s

Speravo in meglio, ma vabbè. s.findfunziona perfettamente qui al posto di not s.startswith.


12

Retina , 58 byte

.+
$0#$0
(.*)(.+)#.*\1$
$0#$1#$2-
+`\w#(\w*)-
#$1-$1
#.*-
<empty line>

Ogni riga dovrebbe andare al proprio file ma è possibile eseguire il codice come un file con il -s flag.

Le quattro coppie di sostituzione effettuano le seguenti operazioni:

  • Parola duplicata in modo da poter cercare anche sovrapposizioni.
  • Aggiungi la parola divisa in order numero di caratteri.
  • Aggiungi l'ultima parte order time.
  • Conserva la parola originale e l'ultima parte aggiunta e rilascia tutto il resto.

La stringa indica per l'esempio onion:

onion
onion#onion
onion#onion#on#ion-
onion#onion##ion-ionion
onionionion

10

Haskell, 64 byte

g s=[b>>a|(a,b)<-map(`splitAt`s)[1..],and$zipWith(==)s b]!!0++s

test:

λ: g "onion"       == "onionionion"
True
λ: g "jackhammer"  == "jackhammer"
True
λ: g "abracadabra" == "abracadabracadabracadabracadabracadabra"
True
λ: g ""            == ""
True
λ: g "zvioz"       == "zviozvioz"
True
λ: g "alfalfa"     == "alfalfalfalfalfalfa"
True
λ: g "aaaa"        == "aaaaaaa"
True

10

Java, 160 157 byte

static void g(String s){int i=s.length(),o;for(String p=s;i-->0;)if(s.endsWith(s.substring(0,i))){for(o=i;o-->0;)p+=s.substring(i);System.out.print(p);i=0;}}

Input Output:

 g("abracadabra"); --> "abracadabracadabracadabracadabracadabra"

Distanziati e a schede per leggibilità:

static void g(String s){
int i=s.length(),o;
for(String p=s;i-->0;)
    if(s.endsWith(s.substring(0,i))){
        for(o=i;o-->0;)
            p+=s.substring(i);
        System.out.print(p);
        i=0;
    }
}

Suggerimenti benvenuti.


Come nota per me stesso, le operazioni String possono essere spostate nel ciclo for per salvare un byte o due in punti
DeadChex

perché non farlo i=0;?
overactor

@overactor dove? Il motivo per cui utilizzo la lunghezza è perché voglio l'intera stringa e quindi non voglio spostarmi verso nessuna di essa, con la sottostringa non penso di poter evitare di usarla in questo metodo e prenderò la penalità in byte per essa
DeadChex

2
Volevo uscire dall'esterno per il loop.
overactor

8

Sed: 87 84 caratteri

(Codice 83 caratteri + opzione riga comandi 1 carattere.)

h
s/(.*)./& \1/
T
s/(.+) \1.*/ \1 \1/
t
g
q
:
s/^([^ ]+)(.*)[^ ]$/\1 \1\2/
t
s/ //g

Esecuzione di esempio:

bash-4.3$ sed -r 'h;s/(.*)./& \1/;T;s/(.+) \1.*/ \1 \1/;t;g;q;:;s/^([^ ]+)(.*)[^ ]$/\1 \1\2/;t;s/ //g' <<< 'underground'
undergroundergroundergrounderground

Voto automatico della risposta sed ;-). Segui questo suggerimento per eliminare 2 caratteri dalla definizione e dalla filiale dell'etichetta
Digital Trauma,

Ho provato, ma temo che i consigli siano solo per i casi in cui non si hanno salti senza etichetta fino alla fine del codice. [Poco dopo ...] Ok, ripensandoci, perché ho provato a elaborare più linee di input contemporaneamente?
arte

7

CJam, 24 23 byte

q_:Q,{~)Q>Q\#!},W>~_Q>*

q_:Q                       e# Read the input, take a copy and store it in Q too
    ,{        },           e# Take the length of the input and filter [0 .. len - 1] array
      ~)                   e# Same as number * -1
        Q>                 e# Take last number characters. Call this string S
          Q\#!             e# See if Q starts with S. After the filter, we will only have
                           e# those numbers from [0 .. len - 1] array which are valid orders
                W>~        e# Take the last order number, if exists.
                   _Q>*    e# Garlandify the input order times.

Solo per iniziare con qualcosa ..

Provalo online qui


5

Matlab: 97 89 82 byte

Funzione che utilizza un'espressione regolare con lookbehind e un gruppo di acquisizione:

function t=f(s)
n=sum(regexp(s,'(.*$)(?<=^\1.+)'))-1;t=[s(repmat(1:n,1,end-n)) s];

Ciò sumè necessario per gestire l'input di stringa vuota (convertire []in0 ).

Esempi:

> f('onion'), f('jackhammer'), f('abracadabra'), f(''), f('zvioz'), f('alfalfa'), f('aaaa')
ans =
onionionion
ans =
jackhammer
ans =
abracadabracadabracadabracadabracadabra
ans =
   Empty string: 1-by-0
ans =
zviozvioz
ans =
alfalfalfalfalfalfa
ans =
aaaaaaa

4

REGXY, 53 49 byte

Utilizza REGXY , un linguaggio basato sulla sostituzione regex

//$'#/
/.(.+)#\1\K/#/
a/(#).(.*#)|#.*/$'$1$2/
//a

Panoramica: vengono applicate alcune espressioni regolari. Un esempio di esecuzione sarebbe simile a:

onion (input)
onion#onion (line 1 regex)
onion#on#ion (line 2 regex - find the repeated section and separate with #)
onionion#n#ion (line 3 regex - the length of the middle token is the garland order, remove a character and append the third token onto the original string on the left)
onionionion##ion (line 4 regex is a pointer to line 3 - repeat the previous again)
onionionion##ion (line 4 regex is a pointer to line 3 - strip everything after and including the #)

Spiegazione dettagliata Quanto segue è una ripartizione riga per riga delle regex:

//$'#/

Questa è una sostituzione regex che corrisponde alla prima stringa vuota (cioè l'inizio della stringa) e la sostituisce con tutto a destra della corrispondenza ( $') seguito da un hash. Ad esempio, si trasformerà onionin onion#onion.

/.(.+)#\1\K/#/

Questa riga trova la sezione che si sovrappone cercando un gruppo di caratteri che precede immediatamente # ( (.+)) che sono gli stessi sull'altro lato di # ( \1). Il \ K significa semplicemente "dimentica che ho abbinato qualsiasi cosa", il che significa che non verrà effettivamente sostituito nella sostituzione. Questo in modo efficace, questo significa che aggiungiamo solo un # alla posizione dopo che la sovrapposizione è stata trovata, girandoonion#onion in onion#on#ion.

a/(#).(.*#)|#.*/$'$1$2/

La "a" iniziale è solo un'etichetta per la regex. Dopo questo, troviamo il primo # seguito da un singolo carattere ( .) e catturiamo tutto dopo questo fino al successivo # ( .*#). Sostituiamo questo con tutto a destra della partita, ovvero l'ultimo token ($ '), seguito da un # ( $1), seguito dal secondo token meno un carattere (lo trattiamo come un contatore, diminuendolo ogni iterazione). Nel caso di cipolla # su # ione, i due token su cui facciamo riferimento sono mostrati tra parentesi e la sezione a cui corrisponde l'intera regex è tra le pipe:onion|(#)o(n#)|ion . Sostituiamo quindi i bit che abbiniamo (tra i tubi) con $'(tutto a destra della corrispondenza, ad esempio 'ion'), quindi $ 1 (il #), quindi $ 2 (n #), il che significa che finiamo con onion|(ion)(#)(n#)|ion(parentesi mostrate i tre token nella stringa di sostituzione).

Se il regex non riesce ad abbinare nella prima alternanza (tutto prima della pipe), dobbiamo aver ridotto il nostro contatore a zero, il che significa che non ci sono caratteri all'interno del secondo token. Invece, guardiamo la seconda parte del modello, #.*. Questo semplicemente sostituisce tutto dopo il primo # con $'$1$2. Poiché non vi sono riferimenti secondari creati da questa alternanza e non esiste nulla a destra della corrispondenza ( .*corrispondenze fino alla fine della stringa), terminiamo la corrispondenza e restituiamo il risultato.

//a

Questo è solo un puntatore alla riga precedente, assicurandoci di continuare ad eseguire la sostituzione regex fino a quando non riesce più a corrispondere.


3

jq 1,5: 91 caratteri

(Codice di 87 caratteri + opzione della riga di comando di 4 caratteri.)

.+. as$t|[range(1;length)|select($t[:.]==$t[-.:])]|(max//0)as$i|[range($i)|$t[$i:]]|add

Esecuzione di esempio:

bash-4.3$ jq -R -r -f judy.jq <<< 'underground'
undergroundergroundergrounderground

3

rs , 51 48 byte

(.+)/\1 \1
(.+)(.+) .+\1$/\1(\2)^^((^^\1_))
 .*/

PRENDI QUELLO, RETINA E SEDUTA !!!!! ;)

Taglia 3 byte grazie a @randomra.

Demo live e casi di test.

Si noti che il jackhammercaso di test non è presente. C'è un bug nella gestione degli spazi nell'interfaccia web che gli fa stampare un output errato. La versione offline dirs gestisce correttamente.

Versione a 51 byte:

(.+)/\1 \1
^(.+)(.+) (.+)\1$/\1(\2)^^((^^\1_))
 .*/

Demo live e casi di test per originali.


@randomra Aggiornato. Grazie!
kirbyfan64sos,

2

JavaScript (ES6), 95 byte

f=s=>{for(e=i=s.length;i&&e;)s+=s.slice(--i).repeat(!(e=!s.endsWith(s.slice(0,i)))*i);return s}

dimostrazione

Firefox solo per ora:

f = s => {
  for (e = i = s.length; i && e;) s += s.slice(--i).repeat(!(e = !s.endsWith(s.slice(0, i))) * i);
  return s
}

console.log = x => X.innerHTML += x + '\n';

console.log(f('onion'));
console.log(f('jackhammer'));
console.log(f('abracadabra'));
console.log(f(''));
console.log(f('zvioz'));
console.log(f('alfalfa'));
console.log(f('aaaa'));
<pre id=X></pre>


2

JavaScript (ES6), 82 byte

g=(s,i=t=s.length)=>s.endsWith(c=s.slice(0,--i))?c+s.slice(i-t).repeat(i+1):g(s,i)

[Cancella la mia risposta originale, perché ora ho imparato ES6 ed ero interessato a trovare una soluzione ricorsiva a questa sfida]

Esempio

g=(s,i=t=s.length)=>s.endsWith(c=s.slice(0,--i))?c+s.slice(i-t).repeat(i+1):g(s,i)

console.log(g('onion'));
console.log(g('jackhammer'));
console.log(g('abracadabra'));
console.log(g(''));
console.log(g('zvioz'));
console.log(g('alfalfa'));
console.log(g('aaaa'));


1

CoffeeScript + ES6, 77 byte

Stesso approccio della mia risposta JavaScript.

f=(s,e=i=s.length)->s+=s[i..].repeat !(e=!s.endsWith s[...i])*i while--i&&e;s

0

C

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    char *str   = NULL;
    char *p     = NULL;
    int len     = 0 ;
    int i       = 0;
    int j       = 0;
    int k       = 0;
    int loop    = 0;

    if (argc == 1 )
        return 0;

    str = argv[1];
    len = strlen(str);

    if (len %2) {
        loop = len/2 + 1;
    }
    else {
        loop = len/2;
    }


    p = &str[len/2];
    for (i = 0; i < loop ; i++) {
        if (str[k] == *(p++)) {
            k++;
        }
        else
            k = 0;
    }

    printf("k = %d\n", k);
    printf("%s", str);
    p = &str[k];
    for (j =0; j < k ; j++) {
        printf("%s", p);
    }
    return 0;
}

Golfato: 195 byte - GCC

main(int c,char**a){
char *s=a[1],*p;int i=0,j=0,k=0,z,l=strlen(a[1]);
z=l%2?-~(l/2):l/2;p=&s[l/2];
for(;i<z;i++)k=s[k]==*(p++)?-~k:0;
printf("k=%d\n",k);puts(s);p= &s[k];
for(;j<k;j++)puts(p);}

5
Benvenuti in Puzzle di programmazione e Code Golf! Questa domanda è il golf del codice, quindi ti suggerisco di "golfare" il tuo codice rimuovendo spazi bianchi non necessari, ecc., Quindi includi il conteggio dei byte del tuo codice nel titolo del tuo post insieme alla lingua.
Lirtosiast,

1
Fatto. Grazie per la direzione. Lo terrò a mente la prossima volta.
Alam,

Non è troppo tardi per "giocare a golf". Se fai clic sul pulsante "modifica" sotto la risposta, puoi comunque rimuovere lo spazio bianco non necessario e aggiungere un conteggio di byte.
DJMcMayhem

Non è intimplicito in (versioni sufficientemente vecchie di) C?
Ripristina Monica il

0

Groovy 75 57 55 byte

f={w->x=w;w.find{x-=it;!w.indexOf(x)};w+(w-x)*x.size()}

Incredibile come tornare a qualcosa il giorno dopo possa aiutare

Ungolfed:

f = {w ->

//Set x equal to w
    x=w

//Loop through the characters of w until we return true
    w.find {

//set x equal to x minus the first instance of the current character, i.e.     the word minus the first character
        x-=it

//Returns the index of the first occurance of the string of chars x, when this is 0 (false) we want to return true, so negate it
        !w.indexOf(x)
    }

//When we've escaped the loop, if we've found a match return the word plus the word minus the match multiplied by the lengh of the match.
    w+(w-x)*x.size()     
}

-1

Nel caso in cui qualcuno abbia bisogno del codice in JS per testarlo. Nota: ho attraversato la stringa dall'estremità per aumentare l'efficienza:

"use strict";

var garlandify = function(inputString){
    var stringLength = inputString.length;  
    var savedString = inputString;

    for( var i=1; i<stringLength; i++ ){
         var endIndex = Math.abs(i) * -1;       
         if( inputString.startsWith( inputString.substr(endIndex) ) ){
              for( var j=1; j<=i; j++){
                  savedString += inputString.substr(i, stringLength );
              }
              console.log(savedString);         
         }  
    }
};

garlandify("onion");

4
Benvenuti allo scambio di stack di programmazione Puzzle & Code Golf! Non devi preoccuparti dell'efficienza del code-golf , ma solo della lunghezza del tuo programma. Quindi la versione lenta e inefficiente potrebbe essere la migliore qui (può fare un cambiamento rinfrescante dal "vero lavoro"!). Quindi rimuovi gli spazi bianchi non necessari e usa nomi di variabili a lettera singola, quindi leggi Suggerimenti per giocare a golf in JavaScript . Penso che ci sia molto che puoi fare per giocare a golf, ma ci piace vedere la versione non commentata e commentata se il tuo algoritmo è intelligente. Divertiti!
Toby Speight,
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.