Palindromizzare le corde


30

introduzione

Per quelli che non lo sanno, un palindromo è quando una stringa è uguale alla stringa all'indietro (ad eccezione di interpunzione, spazi, ecc.). Un esempio di palindromo è:

abcdcba

Se si inverte questo, si finirà con:

abcdcba

Che è lo stesso Pertanto, lo chiamiamo palindromo. Per palindromizzare le cose, diamo un'occhiata a un esempio di stringa:

adbcb

Questo non è un palindromo. Per palindromizzare questo, abbiamo bisogno di unire la stringa invertita nella stringa iniziale alla destra della stringa iniziale , lasciando intatte entrambe le versioni. Più corto, meglio è.

La prima cosa che possiamo provare è la seguente:

adbcb
bcbda
^^ ^^

Non tutti i caratteri corrispondono, quindi questa non è la posizione giusta per la stringa invertita. Facciamo un passo verso destra:

adbcb
 bcbda
 ^^^^

Anche questo non corrisponde a tutti i personaggi. Facciamo un altro passo verso destra:

adbcb
  bcbda

Questa volta, tutti i personaggi corrispondono . Possiamo unire entrambe le stringhe lasciando intatte . Il risultato finale è:

adbcbda

Questa è la stringa palindromizzata .


L'obiettivo

Data una stringa (con almeno un carattere) contenente solo lettere minuscole (o maiuscole, se si adatta meglio), genera la stringa palindromizzata .


Casi test

Input     Output

abcb      abcba
hello     hellolleh
bonobo    bonobonob
radar     radar
hex       hexeh

Questo è , quindi vince l'invio con il minor numero di byte!



6
È necessario specificare che la stringa invertita deve essere unita alla stringa originale con quella invertita a destra. Se può andare a sinistra, obonobosarebbe una soluzione migliore al caso di test.
Level River St


2
@LevelRiverSt +1 solo perché "obonobo" è una parola così sorprendente
Nathaniel

1
@Nathaniel Grazie ma bono b o nobè un'intera frase. Qual è la differenza tra God e Bono? Dio non gira per Dublino fingendo di essere Bono ;-)
Level River St

Risposte:


5

Gelatina, 11 10 byte

ṫỤfU$Ḣœ^;U

Provalo online!

Come funziona

ṫỤ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.

15

Pyth (commit b93a874), 11 byte

.VkI_IJ+zbB

Suite di test

Questo codice sfrutta un bug nella versione corrente di Pyth, commit b93a874 . Il bug è che _IJ+zbviene analizzato come se fosse q_J+zbJ+zb, il che equivale a _I+zb+zb, quando dovrebbe (secondo l'intenzione progettuale di Pyth) essere analizzato q_J+zbJ, che è equivalente a _I+zb. Questo mi permette di salvare un byte - dopo che il bug è stato corretto, sarà il codice corretto .VkI_IJ+zbJB. Spiegherò invece quel codice.

Fondamentalmente, il codice brute impone tutte le stringhe possibili fino a quando non trova la stringa più breve che può essere aggiunta all'input per formare un palindromo e genera la stringa combinata.

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

Come ti viene in mente questo codice? È appena leggibile e assolutamente non comprensibile da qualcuno che non conosce Pyth. Qual è lo scopo di una tale lingua.
Anukul,

5
@momo Lo scopo della lingua è scrivere codice breve, per divertimento. È un'attività ricreativa. Posso scriverlo perché ho molta pratica e perché ho inventato la lingua. So che non è comprensibile a qualcuno che non conosce la lingua, motivo per cui ho incluso la spiegazione.
isaacg,

13

Python, 46 byte

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

Se la stringa è un palindromo, restituirlo. Altrimenti, inserisci la prima lettera attorno al risultato ricorsivo per il resto della stringa.

Esempio di ripartizione:

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

Penso che puoi salvare un byte se usi la condizione opposta ( s!=s[::-1])
aditsu

@aditsu Funziona ma l'utilizzo di una moltiplicazione è ancora più breve.
xnor

9

Haskell, 36 byte

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

Più facilmente:

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

Se la stringa è un palindromo, restituirlo. Altrimenti, inserisci la prima lettera attorno al risultato ricorsivo per la coda della corda.

La stringa sviene suddivisa nella h:tseconda guardia, evitando 1>0in questo caso un riempimento . Questo è più breve di quello s@(h:t)per l'input.


5

Pyth - 16 12 byte

4 byte salvati grazie a @FryAmTheEggman.

FGITW, molto golf possibile.

h_I#+R_Q+k._

Test Suite .


5

Brachylog , 16 6 5 byte (non concorrenti)

:Ac.r

Provalo online!

Quando ho pubblicato la mia risposta iniziale, era ancora sulla vecchia implementazione in Java. Da quando ho riprogrammato tutto in Prolog, ora funziona come dovrebbe in primo luogo.

Spiegazione

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

La backpropagation lo rende tale che il primo valore valido Atrovato sarà il più breve che puoi concatenare a Input per renderlo un palindromo.

Soluzione alternativa, 5 byte

~@[.r

Questo è all'incirca lo stesso della risposta precedente, tranne per il fatto che invece di dichiarare "Output è la concatenazione dell'Input con una stringa A", affermiamo che "Output è una stringa per cui l'Input è un prefisso dell'output".


4

JavaScript (ES6), 92 byte

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

Calcola e taglia la sovrapposizione tra la stringa originale e la sua inversione.


4

Retina, 29 25

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

Provalo online!

Grazie mille a Martin per 11 byte risparmiati!

Questo crea solo una copia invertita della stringa e le smorza insieme. L'unica parte davvero fantasiosa di questo è il metodo di inversione:, O^#r`.\Gche viene fatto utilizzando la modalità di ordinamento. Ordiniamo le lettere della seconda stringa (quelle che non sono newline e sono consecutive dalla fine della stringa, grazie a \G) per il loro valore numerico, che, dato che non ci sono numeri, è 0. Quindi invertiamo ordine dei risultati di questo ordinamento stabile con l' ^opzione. Tutto il merito dell'uso fantasioso di \Gappartiene a Martin :)


3

CJam, 18 anni

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

Provalo online

Spiegazione:

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

3

Lua, 89 88 byte

Ho battuto il Javascript! \ o / Salvato 1 byte grazie a @LeakyNun ^^

È un programma completo, prende il suo input come argomento da riga di comando.

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

ungolfed

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

Credo che le parentesi vicine whilepossano essere rimosse?
Leaky Nun,

@LeakyNun sicuro che possono ^^
Katenkyo,

Non si può fare i=i+1end?
Erik the Outgolfer,

1
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Purtroppo, non posso. Proverebbe a valutare 1endcome un numero esadecimale. In genere, non è possibile utilizzare [abcdef]direttamente dopo un numero senza che sia considerato un esadecimale. C'è un'altra eccezione 0x.
Katenkyo,

3

Prolog, 43 byte

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

Ciò prevede una stringa di codici come input, ad esempio su SWI-Prolog 7: a(`hello`).

Spiegazione

Questa è sostanzialmente una porta della mia risposta su 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

3

Ottava, 78 75 byte

Salvato 3 byte grazie a Eʀɪᴋ ᴛʜᴇ Gᴏʟғᴇʀ!

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

ideone non riesce ancora per le funzioni con nome, ma qui è una prova del codice come programma.


2

Perl, 37 byte

Basato sulla risposta di xnor.

Include +2 per -lp

Esegui con input su STDIN, ad es

palindromize.pl <<< bonobo

palindromize.pl:

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



1

J, 20 byte

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

Questo è un verbo monadico. Provalo qui. Uso:

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

Spiegazione

Sto usando il fatto che la palindromizzazione di S è S + reverse (P) , dove P è il prefisso più corto di S la cui rimozione si traduce in un palindromo. In J, è un po 'goffo fare una ricerca del primo elemento di un array che soddisfa un predicato; da qui l'indicizzazione.

,[|.@{.~(-:|.)\.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.

1

Haskell, 68 byte

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

Esempio di utilizzo: f "abcb"-> "abcba".

Cerca tra i dati initsdi input i(ad es. inits "abcb"-> ["", "a", "ab", "abc", "abcb"]) fino a quando non ne trovi uno in cui è aggiunto il contrario per icostruire un palindromo.


Non r=reversedeve andare prima f i=...?
Erik the Outgolfer,

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ: No, puoi usare qualsiasi ordine.
nimi,

Sono riuscito in 46 byte. Scommetto che può essere fatto ancora meglio.
theonlygusti,

@theonlygusti: vedi la risposta di xnor .
nimi,

1

MATL , 17 16 byte

Liberamente ispirato nella risposta CJam di @aditsu .

`xGt@q:)PhttP=A~

Provalo online!

Spiegazione

`        % 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

1

Rubino, 44 ​​byte

Questa risposta si basa sulle soluzioni Python e Haskell di xnor .

f=->s{s.reverse==s ?s:s[0]+f[s[1..-1]]+s[0]}

Non si può fare ==s?s:?
Erik the Outgolfer,

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ irb si adatta se lo provo. Deve essere qualcosa a che fare con il modo in cui analizza ?tra ?:per ternario e la ?x == 'x'sostituzione utilizzato fin Ruby 1.9
Sherlock9

1

Oracle SQL 11.2, 195 byte

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

Un-golfed

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

1

Scherzi a parte, 34 byte

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

L'ultimo carattere è uno spazio non spezzante (ASCII 127 o 0x7F).

Provalo online!

Spiegazione:

╩╜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

1

C #, 202 byte

Provai.

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

Ungolfed:

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

}

Qualcuno può darmi qualche idea per raggruppare le due chiamate a .Reverse (). ToArray ()? Un metodo separato è più byte.


0

QBIC , 41 byte

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

Spiegazione:

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

0

Haskell, 46 byte

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

Mi chiedo se c'è un modo per rimuovere la parentesi in (f$tail l)++[l!!0]...

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.