Palindromizando las cuerdas

30

Introducción

Para los que no saben, un palíndromo es cuando una cadena es igual a la cadena al revés (con excepción de la interpunción, espacios, etc.). Un ejemplo de palíndromo es:

abcdcba

Si revierte esto, terminará con:

abcdcba

Que es lo mismo. Por lo tanto, llamamos a esto un palíndromo. Para palindromizar cosas, echemos un vistazo a un ejemplo de una cadena:

adbcb

Esto no es un palíndromo. Para palindromizar esto, necesitamos fusionar la cadena invertida en la cadena inicial a la derecha de la cadena inicial , dejando ambas versiones intactas. Cuanto más corto, mejor.

Lo primero que podemos probar es lo siguiente:

adbcb
bcbda
^^ ^^

No todos los caracteres coinciden, por lo que esta no es la posición correcta para la cadena invertida. Vamos un paso a la derecha:

adbcb
 bcbda
 ^^^^

Esto tampoco coincide con todos los personajes. Vamos otro paso a la derecha:

adbcb
  bcbda

Esta vez, todos los personajes coinciden . Podemos fusionar ambas cadenas dejando el intacto . El resultado final es:

adbcbda

Esta es la cuerda palindromizada .


La tarea

Dada una cadena (con al menos un carácter) que contiene solo letras minúsculas (o mayúsculas, si eso encaja mejor), genera la cadena palindromizada .


Casos de prueba

Input     Output

abcb      abcba
hello     hellolleh
bonobo    bonobonob
radar     radar
hex       hexeh

Este es el , por lo que gana el envío con la menor cantidad de bytes.

Adnan
fuente
3
Relacionado.
Zgarb
66
Debe especificar que la cadena invertida debe fusionarse en la cadena original con la invertida a la derecha. Si puede ir a la izquierda, obonobosería una mejor solución para el caso de prueba.
Level River St el
2
Relacionado 2
Sp3000
2
@LevelRiverSt +1 solo porque "obonobo" es una palabra increíble
Nathaniel
1
@Nathaniel Gracias pero bono b o nobes una oración completa. ¿Cuál es la diferencia entre Dios y Bono? Dios no deambula por Dublín fingiendo ser Bono ;-)
Level River St

Respuestas:

5

Jalea, 11 10 bytes

ṫỤfU$Ḣœ^;U

Pruébalo en línea!

Cómo funciona

ṫỤfU$Ḣœ^;U  Main link. Argument: s (string)

 Ụ          Yield all indices of s, sorted by their corr. character values.
ṫ           Tail; for each index n, remove all characters before thr nth.
            This yields the list of suffixes of s, sorted by their first character,
            then (in descending order) by length.
    $       Combine the two links to the left into a chain:
   U        Upend; reverse all suffixes.
  f         Filter; only keep suffixes that are also reversed suffixes.
            This gives the list of all palindromic suffixes. Since all of them
            start with the same letter, they are sorted by length.
     Ḣ      Head; select the first, longest palindromic suffix.
      œ^    Multiset symmetric difference; chop the selected suffix from s.
         U  Upend; yield s, reversed.
        ;   Concatenate the results to the left and to the right.
Dennis
fuente
15

Pyth (commit b93a874), 11 bytes

.VkI_IJ+zbB

Banco de pruebas

Este código explota un error en la versión actual de Pyth, commit b93a874 . El error es que _IJ+zbse analiza como si fuera q_J+zbJ+zb, que es equivalente a _I+zb+zb, cuando debería (por la intención de diseño de Pyth) analizarse como q_J+zbJ, que es equivalente a _I+zb. Esto me permite guardar un byte: una vez que se solucione el error, se mostrará el código correcto .VkI_IJ+zbJB. Explicaré ese código en su lugar.

Básicamente, el código de fuerza bruta sobre todas las cadenas posibles hasta que encuentra la cadena más corta que se puede agregar a la entrada para formar un palíndromo, y genera la cadena combinada.

.VkI_IJ+zbJB
                z = input()
.Vk             For b in possible strings ordered by length,
       +zb      Add z and b,
      J         Store it in J,
    _I          Check if the result is a palindrome,
   I            If so,
          J     Print J (This line doesn't actually exist, gets added by the bug.
          B     Break.
isaacg
fuente
¿Cómo se te ocurre ese código? Es apenas legible y absolutamente incomprensible para alguien que no está familiarizado con Pyth. ¿Cuál es el propósito de tal lenguaje?
anukul
55
@momo El propósito del lenguaje es escribir código corto en, por diversión. Es una actividad recreativa. Puedo escribirlo porque tengo mucha práctica y porque inventé el idioma. Sé que no es comprensible para alguien que no conoce el idioma, por eso incluí la explicación.
isaacg
13

Python, 46 bytes

f=lambda s:s*(s==s[::-1])or s[0]+f(s[1:])+s[0]

Si la cuerda es un palíndromo, devuélvala. De lo contrario, empareje la primera letra alrededor del resultado recursivo para el resto de la cadena.

Desglose de ejemplo:

f(bonobo)
b  f(onobo) b
b o f(nobo) o b 
b o n f(obo) n o b
b o n obo n o b
xnor
fuente
Creo que puede guardar un byte si usa la condición opuesta ( s!=s[::-1])
aditsu
@aditsu Eso funciona pero usar una multiplicación es aún más corto.
xnor
9

Haskell, 36 bytes

f s|s==reverse s=s|h:t<-s=h:f t++[h]

Más legible:

f s
 |s==reverse s = s
 |(h:t)<-s     = h:(f t)++[h]

Si la cuerda es un palíndromo, devuélvala. De lo contrario, empareje la primera letra alrededor del resultado recursivo para la cola de la cadena.

La cadena sse divide h:ten el segundo guardia, obviando un relleno 1>0para este caso. Esto es más corto que hacer s@(h:t)para la entrada.

xnor
fuente
5

Pyth - 16 12 bytes

4 bytes guardados gracias a @FryAmTheEggman.

FGITW, mucho golf posible.

h_I#+R_Q+k._

Test Suite .

Maltysen
fuente
5

Brachylog , 16 6 5 bytes (no competidor)

:Ac.r

Pruébalo en línea!

Cuando publiqué mi respuesta inicial, todavía estaba en la implementación anterior en Java. Como he reprogramado todo en Prolog, ahora funciona como debería haberlo hecho en primer lugar.

Explicación

(?):Ac.        Output is the concatenation of Input with another unknown string A
      .r(.)    The reverse of the Output is the Output

La retropropagación hace que el primer valor válido para Aél sea el más corto que pueda concatenar a Input para convertirlo en un palíndromo.

Solución alternativa, 5 bytes.

~@[.r

Esto es más o menos lo mismo que la respuesta anterior, excepto que en lugar de decir "Salida es la concatenación de la Entrada con una cadena A", afirmamos que "Salida es una cadena para la cual la Entrada es un prefijo de la Salida".

Fatalizar
fuente
4

JavaScript (ES6), 92 bytes

(s,a=[...s],r=a.reverse().join``)=>s.slice(0,a.findIndex((_,i)=>r.startsWith(s.slice(i))))+r

Calcula y corta la superposición entre la cadena original y su inversión.

Neil
fuente
4

Retina, 29 25

$
¶$_
O^#r`.\G
(.+)¶\1
$1

Pruébalo en línea!

¡Muchas gracias a Martin por 11 bytes guardados!

Esto solo crea una copia invertida de la cadena y los suaviza juntos. La única parte realmente elegante de esto es el método de inversión: O^#r`.\Gque se realiza mediante el modo de clasificación. Ordenamos las letras de la segunda cadena (las que no son líneas nuevas y son consecutivas desde el final de la cadena, gracias a \G) por su valor numérico, que, dado que no hay números, es 0. Luego invierte el orden de los resultados de este tipo estable con la ^opción Todo el crédito por el uso elegante de \Gpertenece a Martin :)

FryAmTheEggman
fuente
3

CJam, 18

q__,,{1$>_W%=}#<W%

Pruébalo en línea

Explicación:

q         read the input
__        make 2 copies
,,        convert the last one to a range [0 … length-1]
{…}#      find the first index that satisfies the condition:
  1$>     copy the input string and take the suffix from that position
  _W%=    duplicate, reverse and compare (palindrome check)
<         take the prefix before the found index
W%        reverse that prefix
          at the end, the stack contains the input string and that reversed prefix
aditsu
fuente
3

Lua, 89 88 bytes

Batí el Javascript! \ o / Guardado 1 byte gracias a @LeakyNun ^^

Es un programa completo, toma su entrada como argumento de línea de comandos.

i=1s=...r=s:reverse()while s:sub(i)~=r:sub(0,#r-i+1)do i=i+1 end print(s..r:sub(#r-i+2))

sin golf

i=1                             -- initialise i at 1 as string are 1-indexed in lua
s=...                           -- use s as a shorthand for the first argument
r=s:reverse()                   -- reverse the string s and save it into r
while(s:sub(i)~=r:sub(0,#r-i+1))-- iterate while the last i characters of s
do                              -- aren't equals to the first i characters of r
  i=i+1                         -- increment the number of character to skip
end
print(s..r:sub(#r-i+2))         -- output the merged string
Katenkyo
fuente
¿Creo que los paréntesis cercanos whilese pueden eliminar?
Leaky Nun
@LeakyNun seguro de que pueden ^^
Katenkyo
No puede hacer i=i+1end?
Erik the Outgolfer
1
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Lamentablemente, no puedo. Intentaría evaluar 1endcomo un número hexadecimal. En general, no se puede usar [abcdef]directamente después de un número sin que se considere hexadecimal. Hay una excepción más 0x.
Katenkyo
3

Prólogo, 43 bytes

a(S):-append(S,_,U),reverse(U,U),writef(U).

Esto espera una cadena de códigos como entrada, por ejemplo, en SWI-Prolog 7: a(`hello`).

Explicación

Esto es básicamente un puerto de mi respuesta Brachylog.

a(S) :-               % S is the input string as a list of codes
    append(S,_,U),    % U is a list of codes resulting in appending an unknown list to S
    reverse(U,U),     % The reverse of U is U
    writef(U).        % Write U to STDOUT as a list of codes
Fatalizar
fuente
3

Octava, 78 75 bytes

¡Guardado 3 bytes gracias a Eʀɪᴋ ᴛʜᴇ Gᴏʟғᴇʀ!

function p=L(s)d=0;while~all(diag(s==rot90(s),d++))p=[s fliplr(s(1:d))];end

ideone todavía falla para las funciones con nombre, pero aquí hay una prueba de ejecución del código como programa.

cubilete
fuente
2

Perl, 37 bytes

Basado en la respuesta de xnor.

Incluye +2 para -lp

Ejecutar con entrada en STDIN, p. Ej.

palindromize.pl <<< bonobo

palindromize.pl:

#!/usr/bin/perl -lp
s/.//,do$0,$_=$&.$_.$&if$_!~reverse
Ton Hospel
fuente
1

J, 20 bytes

,[|.@{.~(-:|.)\.i.1:

Este es un verbo monádico. Pruébalo aquí. Uso:

   f =: ,[|.@{.~(-:|.)\.i.1:
   f 'race'
'racecar'

Explicación

Estoy usando el hecho de que la palindromización de S es S + inversa (P) , donde P es el prefijo más corto de S cuya eliminación da como resultado un palíndromo. En J, es un poco torpe hacer una búsqueda del primer elemento de una matriz que satisface un predicado; De ahí la indexación.

,[|.@{.~(-:|.)\.i.1:  Input is S.
        (    )\.      Map over suffixes of S:
         -:             Does it match
           |.           its reversal? This gives 1 for palindromic suffixes and 0 for others.
                i.1:  Take the first (0-based) index of 1 in that array.
 [   {.~              Take a prefix of S of that length: this is P.
  |.@                 Reverse of P.
,                     Concatenate it to S.
Zgarb
fuente
1

Haskell, 68 bytes

import Data.List
f i=[i++r x|x<-inits i,i++r x==x++r i]!!0
r=reverse

Ejemplo de uso: f "abcb"-> "abcba".

Busque a través initsde la entrada i(p inits "abcb". Ej. -> ["", "a", "ab", "abc", "abcb"]) hasta encontrar una en la que se adjunte al reverso para iconstruir un palíndromo.

nimi
fuente
¿No r=reversetiene que ir antes f i=...?
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ: No, puedes usar cualquier orden.
nimi
Me las arreglé en 46 bytes. Apuesto a que se puede hacer aún mejor.
theonlygusti
@theonlygusti: ver la respuesta de xnor .
nimi
1

MATL , 17 16 bytes

Inspirado libremente en la respuesta CJam de @aditsu .

`xGt@q:)PhttP=A~

Pruébalo en línea!

Explicación

`        % Do...while loop
  x      %   Delete top of stack, which contains a not useful result from the
         %   iteration. Takes input implicitly on first iteration, and deletes it
  G      %   Push input
  t      %   Duplicate
  @q:    %   Generate range [1,...,n-1], where n is iteration index. On the  first
         %   iteration this is an empty array
  )      %   Use that as index into copy of input string: get its first n elements
  Ph     %   Flip and concatenate to input string
  t      %   Duplicate. This will be the final result, or will be deleted at the
         %   beginning of next iteration
  tP     %   Duplicate and flip
  =A~    %   Compare element-wise. Is there some element different? If so, the
         %   result is true. This is the loop condition, so go there will be a 
         %   new iteration. Else the loop is exited with the stack containing
         %   the contatenated string
         % End loop implicitly
         % Display stack contents implicitly
Luis Mendo
fuente
1

Ruby, 44 bytes

Esta respuesta se basa en las soluciones Python y Haskell de xnor .

f=->s{s.reverse==s ?s:s[0]+f[s[1..-1]]+s[0]}
Sherlock9
fuente
No puede hacer ==s?s:?
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ irb lanza un ataque si lo intento. Debe tener algo que ver con cómo se analiza ?entre el ?:ternario y la ?x == 'x'sustitución utilizada desde Ruby 1.9
Sherlock9
1

Oracle SQL 11.2, 195 bytes

SELECT MIN(p)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(p))FROM(SELECT:1||SUBSTR(REVERSE(:1),LEVEL+1)p FROM DUAL WHERE SUBSTR(:1,-LEVEL,LEVEL)=SUBSTR(REVERSE(:1),1,LEVEL)CONNECT BY LEVEL<=LENGTH(:1));

Sin golf

SELECT MIN(p)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(p))
FROM (
       SELECT :1||SUBSTR(REVERSE(:1),LEVEL+1)p 
       FROM   DUAL 
       WHERE  SUBSTR(:1,-LEVEL,LEVEL)=SUBSTR(REVERSE(:1),1,LEVEL)
       CONNECT BY LEVEL<=LENGTH(:1)
     );
Jeto
fuente
1

En serio, 34 bytes

╩╜lur`╜╨"Σ╜+;;R=*"£M`MΣ;░p╜;;R=I.

El último carácter es un espacio que no se rompe (ASCII 127 o 0x7F).

Pruébalo en línea!

Explicación:

╩╜lur`╜╨"Σ╜+;;R=*"£M`MΣ;░p╜;;R=I.<NBSP>
╩                                        push inputs to registers (call the value in register 0 "s" for this explanation)
 ╜lur                                    push range(0, len(s)+1)
     `              `M                   map (for i in a):
      ╜╨                                   push all i-length permutations of s
        "        "£M                       map (for k in perms):
         Σ╜+                                 push s+''.join(k) (call it p)
            ;;R=                             palindrome test
                *                            multiply (push p if palindrome else '')
                      Σ                  summation (flatten lists into list of strings)
                       ;░                filter truthy values
                         p               pop first element (guaranteed to be shortest, call it x)
                          ╜;;R=I         pop x, push s if s is palindromic else x
                                .<NBSP>  print and quit
Mego
fuente
1

C #, 202 bytes

Lo intenté.

class P{static void Main(string[]a){string s=Console.ReadLine(),o=new string(s.Reverse().ToArray()),w=s;for(int i=0;w!=new string(w.Reverse().ToArray());){w=s.Substring(0,i++)+o;}Console.WriteLine(w);}}

Sin golf:

class P
{
    static void Main(string[] a)
    {
        string s = Console.ReadLine(), o = new string(s.Reverse().ToArray()), w = s;
        for(int i = 0; w!=new string(w.Reverse().ToArray());)
        {
            w = s.Substring(0, i++) + o;
        }
        Console.WriteLine(w);
        Console.ReadKey();
    }

}

¿Alguien me puede dar alguna idea para agrupar las dos llamadas a .Reverse (). ToArray ()? Un método separado es más bytes.

SkyPharaoh
fuente
0

QBIC , 41 bytes

;_FA|C=A{a=a+1~C=_fC||_XC\C=A+right$(B,a)

Explicación:

;_FA|    Read A$ from the cmd line, then flip it to create B$
C=A      Set C$ to be A$
{        Start an infinite DO-loop
a=a+1    Increment a (not to be confused with A$...)
~C=_fC|  If C$ is equal to its own reversed version
|_XC     THEN end, printing C$
\C=A+    ELSE, C$ is reset to the base A$, with
right$(B the right part of its own reversal
,a)      for length a (remember, we increment this each iteration
         DO and IF implicitly closed at EOF
Steenbergh
fuente
0

Haskell, 46 bytes

f l|l==reverse l=l|(h:t)<-l=l!!0:(f$tail l)++[l!!0]

Me pregunto si hay una manera de eliminar el paréntesis en (f$tail l)++[l!!0]...

theonlygusti
fuente