Garlandificación


38

Palabras de guirnalda

Una palabra de guirnalda es una palabra que se puede unir como una guirnalda, porque termina con las mismas letras con las que comienza. ¡Estos grupos de letras pueden incluso superponerse!

Por ejemplo, undergroundes una palabra de orden de guirnaldas 3, porque comienza y termina con los mismos 3 caracteres und,. Esto significa que podría ser encadenado como undergroundergrounderground....

alfalfa¡es una palabra de guirnalda también! Es de orden 4. Comienza y termina con alfa. Puede ser ensartados este modo: alfalfalfalfa.

Un proceso que llamo guirnalda es cuando una vez que determina el orden nde una palabra de guirnalda, toma la palabra original y agrega el segmento requerido para que se repita como guirnalda nveces. Entonces, dado que oniones una 2palabra de guirnalda de orden , tomaría onion, cortaría las primeras 2letras para obtener iony agregar eso al final de los 2tiempos para obtener onionionion.

Objetivo

Haga un programa o función que tome datos de entrada estándar o un argumento de función e imprima o devuelva la palabra, garlandified.

Todas las palabras serán minúsculas, y el orden más alto posible para una palabra es length(word) - 1.

Ejemplo de E / S

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

Este es el , por lo que gana el menor número de bytes.


2
Cualquier palabra de letra N comienza con las mismas letras N con las que termina. ¿Cuál es el orden máximo que debe considerarse?
feersum

@feersum El orden máximo es la longitud de la palabra: 1. Se agregó a la publicación principal.
Kade

¿Tengo que imprimir solo la guirnalda? ¿o tal vez puedo imprimirlo y una excepción?
DeadChex

@DeadChex No debería haber excepciones.
Kade

1
@LuisMendo Debería funcionar para palabras arbitrariamente largas.
Kade

Respuestas:


12

Pyth, 19 18 bytes

+z*>Kf!xz>zT1zl>zK

Pruébelo en línea: demostración o prueba de arnés

Explicaciones:

+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

Esperaba algo mejor, pero bueno. s.findfunciona perfectamente aquí en lugar de not s.startswith.


12

Retina , 58 bytes

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

Cada línea debe ir a su propio archivo, pero puede ejecutar el código como un archivo con la -sbandera.

Los cuatro pares de sustitución hacen lo siguiente:

  • Duplicar la palabra para que podamos buscar superposiciones también.
  • Agregue la palabra dividida en ordernúmero de caracteres.
  • Añadir las últimas orderveces.
  • Mantenga la palabra original y la última parte adjunta y suelte todo lo demás.

Los estados de cadena para el ejemplo 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

Pruebas:

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

De entrada y salida:

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

Espaciado y con pestañas para facilitar la lectura:

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

Sugerencias bienvenidas.


Como una nota para mí mismo, las operaciones de String se pueden mover al bucle for para guardar un byte o dos en punto
DeadChex

¿por qué no hacerlo i=0;?
overactor

@overactor donde? La razón por la que uso la longitud es porque quiero la cadena completa y luego quiero avanzar hacia ninguna de ellas, con la subcadena no creo que pueda evitar usarla en este método y tomaré la penalización de bytes por ella
DeadChex

2
Tenía la intención de salir del bucle externo.
overactor

8

Sed: 87 84 caracteres

(Código de 83 caracteres + opción de línea de comando de 1 carácter).

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

Ejecución de muestra:

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 de respuesta sed ;-). Siga este consejo para eliminar 2 caracteres de su definición de etiqueta y rama
Digital Trauma

Intenté, pero me temo que el consejo es solo para casos en los que no tienes saltos sin etiqueta al final del código. [Un poco más tarde ...] Ok, pensando de nuevo, ¿por qué intenté procesar varias líneas de entrada a la 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.

Solo para empezar con algo ...

Pruébalo en línea aquí


5

Matlab: 97 89 82 bytes

Función que usa una expresión regular con lookbehind y un grupo de captura:

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

Eso sumes necesario para manejar la entrada de cadena vacía (convertir []en 0).

Ejemplos:

> 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

Utiliza REGXY , un lenguaje basado en la sustitución de expresiones regulares.

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

Descripción general: se aplican varias expresiones regulares. Un ejemplo de ejecución se vería así:

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 #)

Explicación detallada El siguiente es un desglose línea por línea de las expresiones regulares:

//$'#/

Esta es una sustitución de expresiones regulares que coincide con la primera cadena vacía (es decir, el inicio de la cadena) y la reemplaza con todo a la derecha de la coincidencia ( $') seguido de un hash. Por ejemplo, se convertirá onionenonion#onion .

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

Esta línea encuentra la sección que se superpone al buscar un grupo de caracteres que preceden inmediatamente al # ( (.+)) que son los mismos en el otro lado del # ( \1). El \ K simplemente significa 'olvida que hice coincidir cualquier cosa', lo que significa que en realidad no será reemplazado en la sustitución. Esto efectivamente, esto significa que simplemente agregamos un # a la posición después de que se haya encontrado la superposición, convirtiéndose onion#onionen onion#on#ion.

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

La 'a' inicial es solo una etiqueta para la expresión regular. Después de esto, encontramos el primer # seguido de un solo carácter ( .) y capturamos todo después de esto hasta el siguiente # ( .*#). Reemplazamos esto con todo a la derecha del partido, es decir, el último token ($ '), seguido de un # ( $1), seguido del segundo token menos un carácter (tratamos esto como un contador, disminuyéndolo en cada iteración). En el caso de la cebolla # en # ion, las dos fichas a las que hacemos referencia se muestran entre paréntesis, y la sección que coincide con la expresión regular completa se encuentra entre las tuberías:onion|(#)o(n#)|ion . Luego reemplazamos los bits que emparejamos (entre las tuberías) con $'(todo a la derecha del emparejamiento, es decir, 'ion'), luego $ 1 (el #), luego $ 2 (n #), lo que significa que terminamos con onion|(ion)(#)(n#)|ion(los paréntesis muestran los tres tokens en la cadena de reemplazo).

Si la expresión regular no coincide en la primera alternancia (todo antes de la tubería), debemos haber reducido nuestro contador a cero, lo que significa que no hay caracteres dentro de la segunda ficha. En su lugar, nos fijamos en la segunda parte del patrón, #.*. Esto simplemente reemplaza todo después del primer # con $'$1$2. Dado que esta alternancia no crea referencias inversas, y no hay nada a la derecha de la coincidencia ( .*coincide hasta el final de la cadena), terminamos la coincidencia y devolvemos el resultado.

//a

Esto es solo un puntero a la línea anterior, lo que garantiza que continuaremos ejecutando la sustitución de expresiones regulares hasta que ya no coincida.


3

jq 1.5: 91 caracteres

(Código de 87 caracteres + opción de línea de comando de 4 caracteres).

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

Ejecución de muestra:

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

3

rs , 51 48 bytes

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

TOMA ESO, RETINA Y SED !!!!! ;)

Corte 3 bytes gracias a @randomra.

Demostración en vivo y casos de prueba.

Tenga en cuenta que el jackhammercaso de prueba no está allí. Hay un error en el manejo de espacios en la interfaz web que hace que imprima resultados incorrectos. La versión sin conexión de lo rsmaneja correctamente.

Versión de 51 bytes:

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

Demostración en vivo y casos de prueba para el original.


@randomra Actualizado. ¡Gracias!
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}

Manifestación

Firefox solo por ahora:

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)

[Eliminé mi respuesta original, porque ahora aprendí ES6 y estaba interesado en encontrar una solución recursiva para este desafío]

Ejemplo

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

El mismo enfoque que mi respuesta de JavaScript.

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

0

do

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

Golfizado: 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);}

55
¡Bienvenido a Programming Puzzles y Code Golf! Esta pregunta es el código de golf, por lo que le sugiero que "golf" su código eliminando espacios en blanco innecesarios, etc., y luego incluya el recuento de bytes de su código en el título de su publicación junto con el idioma.
lirtosiast

1
Lo tengo. Gracias por la direccion. Lo tendré en cuenta la próxima vez.
Alam

No es demasiado tarde para "jugarlo". Si hace clic en el botón "editar" debajo de su respuesta, aún podría eliminar el espacio en blanco innecesario y agregar un recuento de bytes.
DJMcMayhem

¿No está intimplícito en (versiones suficientemente antiguas de) C?
Restablece a Mónica el

0

Groovy 75 57 55 bytes

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

Es sorprendente cómo volver a algo al día siguiente puede ayudar

Sin golf:

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

En caso de que alguien necesite el código en JS para probarlo. Nota: atravesé la cadena desde el final para aumentar la eficiencia:

"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");

44
¡Bienvenido al intercambio de pila de programación Puzzles y Code Golf! No necesita preocuparse por la eficiencia para el código de golf , solo por la duración de su programa. Por lo tanto, la versión lenta e ineficiente puede ser la mejor aquí (¡puede hacer un cambio refrescante del "trabajo real"!). Elimine los espacios en blanco innecesarios y use nombres de variables de una sola letra, luego lea Consejos para jugar golf en JavaScript . Creo que hay mucho que puedes hacer para jugar golf, pero nos gusta ver la versión no comentada y comentada si tu algoritmo es inteligente. ¡Que te diviertas!
Toby Speight
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.