Garlandificação


38

Garland Words

Uma palavra de guirlanda é uma palavra que pode ser amarrada como uma guirlanda, porque termina com as mesmas letras com que começa. Esses grupos de letras podem até se sobrepor!

Por exemplo, undergroundé uma palavra de ordem da guirlanda 3, porque começa e termina com os mesmos três caracteres und,. Isso significa que pode ser amarrado juntos undergroundergrounderground....

alfalfatambém é uma palavra guirlanda! É da ordem 4. Começa e termina com alfa. Ele pode ser amarrados juntos assim: alfalfalfalfa.

Um processo que chamo de garlandificação é o local em que, depois de determinar a ordem nde uma palavra da guirlanda, você pega a palavra original e adiciona o segmento necessário para que ela faça um loop como um período da guirlanda n. Portanto, como onioné uma 2palavra de guirlanda de ordem , você deve onioncortar, cortar as primeiras 2letras para obter ione adicionar ao final dos 2tempos onionionion.

Objetivo

Faça um programa ou função que receba entrada da entrada padrão ou de um argumento de função e imprima ou retorne a palavra garlandified.

Todas as palavras serão minúsculas e a ordem mais alta possível para uma palavra é length(word) - 1.

Exemplo de E / S

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

Isso é , portanto, o menor número de bytes vence.


2
Qualquer palavra com letra N começa com as mesmas N letras em que termina. Qual é o pedido máximo que deve ser considerado?
22415 feersum

@feersum O pedido máximo é o tamanho da palavra - 1. Adicionado isso à postagem principal.
Kade

Preciso imprimir apenas a guirlanda? ou posso imprimi-lo e uma exceção?
23815 DeadChex

@DeadChex Não deve haver exceções.
Kade

1
@LuisMendo Deve funcionar para palavras arbitrariamente longas.
Kade

Respostas:


12

Pitão, 19 18 bytes

+z*>Kf!xz>zT1zl>zK

Experimente on-line: demonstração ou equipamento de teste

Explicações:

+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 bytes

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

Estava esperando por melhor, mas tudo bem. s.findfunciona ordenadamente aqui no lugar de not s.startswith.


12

Retina , 58 bytes

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

Cada linha deve ir para seu próprio arquivo, mas você pode executar o código como um arquivo com o -ssinalizador.

Os quatro pares de substituição fazem o seguinte:

  • Palavra duplicada para que possamos procurar sobreposições também.
  • Anexe a palavra dividida no ordernúmero de caracteres.
  • Anexe os últimos ordertempos da peça .
  • Mantenha a palavra original e a parte anexada por último e solte todo o resto.

A cadeia afirma para o exemplo onion:

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

10

Haskell, 64 bytes

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

Testes:

λ: 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 bytes

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

Entrada / Saída:

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

Espaçados e com guias para facilitar a leitura:

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

Sugestões são bem-vindas.


Como uma nota para a minha auto, os ops corda pode ser movido para o loop for para salvar um byte ou dois em ponto e vírgula
DeadChex

por que não fazer i=0;?
overactor

@overactor onde? O motivo pelo qual uso o comprimento é porque quero a String completa e, em seguida, quero avançar em direção a nenhuma, com substring acho que não posso evitar usá-lo nesse método e que será penalizado por byte
DeadChex

2
Eu pretendia sair do circuito externo.
overactor

8

Sed: 87 84 caracteres

(Código de 83 caracteres + opção de linha de comando de 1 caractere.)

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

Exemplo de execução:

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 automático da resposta sed ;-). Siga esta dica para eliminar 2 caracteres da definição e da ramificação de sua etiqueta
Digital Trauma

Tentei, mas tenho medo de que o conselho seja apenas para casos em que você não tenha saltos sem rótulo para o final do código. [Um pouco mais tarde ...] Ok, pensando novamente, por que tentei processar várias linhas de entrada de uma só vez?
manatwork

7

CJam, 24 23 bytes

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.

Só para começar com algo ..

Experimente online aqui


5

Matlab: 97 89 82 bytes

Função que usa uma expressão regular com lookbehind e um grupo de captura:

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

Isso sumé necessário para manipular a entrada de sequência vazia (converter []em 0).

Exemplos:

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

Usa REGXY , um idioma baseado em substituição de regex

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

Visão geral: são aplicadas várias expressões regulares. Um exemplo de execução seria semelhante 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 #)

Explicação detalhada A seguir, é apresentada uma divisão por linha dos regexes:

//$'#/

Esta é uma substituição de regex que corresponde à primeira string vazia (ou seja, o início da string) e a substitui por tudo à direita da match ( $') seguida por um hash. Por exemplo, ele se transformará onionem onion#onion.

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

Essa linha localiza a seção que se sobrepõe, procurando por um grupo de caracteres imediatamente anteriores ao # ( (.+)), que são iguais no outro lado do # ( \1). O \ K significa apenas 'esqueça que correspondi a qualquer coisa', o que significa que na verdade não será substituído na substituição. Isso efetivamente significa que basta adicionar um # à posição após a sobreposição ter sido encontrada, transformando onion#onion- se em onion#on#ion.

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

O inicial 'a' é apenas um rótulo para a regex. Depois disso, encontramos o primeiro # seguido de um único caractere ( .) e capturamos tudo depois disso até o próximo # ( .*#). Substituímos isso por tudo à direita da partida, ou seja, o último token ($ '), seguido de um # ( $1), seguido pelo segundo token menos um caractere (tratamos isso como um contador, diminuindo a cada iteração). No caso de cebola em # # iónica, as duas fichas que backreference são apresentadas entre parêntesis, e a secção de todo o partidas regex é entre os tubos: onion|(#)o(n#)|ion. Em seguida, substituímos os bits com os quais correspondemos (entre os tubos) por $'(tudo à direita da correspondência, ou seja, 'ion'), depois $ 1 (o #), depois $ 2 (n #), o que significa que terminamos com onion|(ion)(#)(n#)|ion(colchetes mostrados os três tokens na cadeia de substituição).

Se a regex falhar na correspondência na primeira alternância (tudo antes do canal), devemos ter diminuído nosso contador para zero, significando que não há caracteres dentro do segundo token. Em vez disso, olhamos para a segunda parte do padrão #.*,. Isso simplesmente substitui tudo após o primeiro # por $'$1$2. Como não há referências anteriores criadas por essa alternância e não há nada à direita da partida ( .*correspondências até o final da sequência), encerramos a correspondência e retornamos o resultado.

//a

Isso é apenas um ponteiro para a linha anterior, garantindo que continuemos executando a substituição de regex até que ela não corresponda mais.


3

jq 1.5: 91 caracteres

(Código de 87 caracteres + opção de linha de comando de 4 caracteres.)

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

Exemplo de execução:

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

3

rs , 51 48 bytes

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

TOMAR ISSO, RETINA E SED !!!!! ;)

Corte 3 bytes graças a @randomra.

Demonstração ao vivo e casos de teste.

Observe que o jackhammercaso de teste não está lá. Há um erro na manipulação de espaços na interface da web que faz com que ela imprima uma saída incorreta. A versão offline do rslida com isso corretamente.

Versão de 51 bytes:

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

Demonstração ao vivo e casos de teste para o original.


@randomra Atualizado. Obrigado!
kirbyfan64sos

2

JavaScript (ES6), 95 bytes

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

Demo

Firefox apenas por enquanto:

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 bytes

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

[Excluí minha resposta original, porque agora aprendi o ES6 e estava interessado em encontrar uma solução recursiva para esse desafio]

Exemplo

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 bytes

A mesma abordagem da minha resposta 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;
}

Golfe: 195 bytes - 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
Bem-vindo à Programação de Puzzles e Code Golf! Essa pergunta é sobre código de golfe, por isso sugiro que você "modifique" seu código removendo espaços em branco desnecessários etc. e inclua a contagem de bytes do seu código no título da sua postagem junto com o idioma.
lirtosiast

1
Consegui. Obrigado pela direção. Vou manter isso em mente na próxima vez.
Alam

Não é tarde demais para "jogar golfe" nele. Se você clicar no botão "editar" abaixo da sua resposta, poderá remover o espaço em branco desnecessário e adicionar uma contagem de bytes.
DJMcMayhem

Não está intimplícito nas (versões suficientemente antigas do) C?
Reinstale Monica

0

Groovy 75 57 55 bytes

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

Incrível como voltar a algo no dia seguinte pode ajudar

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

Caso alguém precise do código em JS para testá-lo. Nota: Passei a corda do final para aumentar a eficiência:

"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
Bem-vindo à troca de pilhas Programming Puzzles & Code Golf! Você não precisa se preocupar com a eficiência do código-golfe , apenas com a duração do seu programa. Portanto, a versão lenta e ineficiente pode muito bem ser a melhor aqui (pode fazer uma alteração refrescante do "trabalho real"!). Portanto, remova o espaço em branco desnecessário e use nomes de variáveis ​​com uma letra - e leia Dicas para jogar golfe em JavaScript . Acho que há muito o que você pode fazer para jogar isso - mas gostamos de ver a versão comentada e não-gasta, se o seu algoritmo for inteligente. Diverta-se!
precisa
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.