Esegui il downgrade a un Palindrome


47

Data una stringa s, restituisce la sottostringa contigua più piccola che è possibile rimuovere per creare un palindromo.


Esempi:

800233008   -> 2
racecarFOOL -> FOOL
abcdedcba   -> (empty string)
ngryL Myrgn -> "L " (or " M")
123456789   -> 12345678 (or 23456789)
aabcdbaa    -> c (or d)
[[]]        -> [[ (or ]])
a           -> (empty string)

Testare i suggerimenti dei casi dagli utenti (se trovi un caso limite non elencato, pubblica un commento):

aabaab      -> b    | Suggested by Zgarb, some returned "aa".

Regole

  • Nell'input appariranno solo caratteri ASCII stampabili (nessuna nuova riga, mantieni la semplicità).
  • Non proprio una regola, ma nota <>, /\, (), []e {}non sono palindromi.

Questo è , vince il conteggio dei byte più piccolo.


+100 taglia è stata richiesta da Adnan


3
Caso Tesf:aabaab
Zgarb,

14
Penso che aiuterà a mantenere le domande accessibili a più visitatori se si evita il gergo ingroup come "CMC" (guardando in alto, sembra significare "mini sfida chat", che immagino significhi una piccola sfida pubblicata nella chat room associata a questo sito).
ShreevatsaR,

Non è [[]]un palindromo?
Carl

4
@Carl Può sembrare uno, ma quando inverti i personaggi, ottieni ]][[. Considera che aabbè la stessa cosa, solo personaggi diversi.
Conor O'Brien,

1
" (verrà assegnato il 7/12) " eh?
Erik the Outgolfer,

Risposte:


8

Gelatina , 16 byte

Ḣ;Ṫµ=Ṛ
0,0jŒṖÇÞṪ

Provalo online!

Come funziona

0,0jŒṖÇÞṪ  Main link. Argument: s (string)

0,0j       Join [0, 0], separating by s. This prepends and appends a 0 to s.
    ŒṖ     Build all partitions of the resulting array.
      ÇÞ   Sort the partitions by the helper link.
           As a side effect, this will remove the first and last element of each
           partition. The 0's make sure that not removing any characters from s
           will still remove [0] from both sides.
        Ṫ  Tail; extract the last one.


Ḣ;Ṫµ=Ṛ     Helper link. Argument: A (array/partition)

Ḣ          Head; yield and remove the first chunk of A.
  Ṫ        Tail; yield and remove the last chunk of A.
 ;         Concatenate head and tail.
   µ=Ṛ     Compare the result, character by character, with its reverse.
           A palindrome of length l will yield an array of l 1's, while a
           non-palindrome of length l will yield an array with at least one 0 among
           the first l/2 Booleans. The lexicographically largest result is the one
           with the longest prefix of 1's, which corresponds to the longest
           palindrome among the outfixes.

10

J , 24 byte

(0{::(-:|.)\.#&,<\)~i.@#

Provalo online!

Spiegazione

(0{::(-:|.)\.#&,<\)~i.@#  Input: array of chars S
                       #  Length of S
                    i.@   Range, [0, 1, ..., len(S)-1]
(                 )~      Dyadic verb on range and S
           \.               For each outfix of S of size x in range
        |.                    Reverse
      -:                      Matches input (is palindrome)
                <\          Box each infix of S of size x in range
             #&,            Flatten each and copy the ones that match
 0{::                       Fetch the result and index 0 and return

Forse potresti voler scegliere (;&quote f)&>come verbo del cablaggio di prova?
Conor O'Brien,

7

Wolfram Language (Mathematica) , 53 51 byte

Il conteggio dei byte presuppone la codifica CP-1252.

±{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:={b}

Provalo online!

Definisce un operatore unario ±(o una funzione PlusMinus). Input e output sono elenchi di caratteri. La suite di test esegue la conversione da e verso stringhe effettive per comodità.


Il Reverseconfronto tra questo inverso e l'originale è più breve di PalindromeQ? Non conosco Mathematica, quindi non ne ho idea.
Magic Octopus Urn,

Buona risposta, ma non si dovrebbe spiegare la divisione delle stringhe e unirle nuovamente nel tuo personaggio? Characters@#/.{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:>b~~""&
Kelly Lowder,

@MagicOctopusUrn Reverse[x={a,c}]==xè più lungo di due byte. Non so se ci siano alternative più brevi.
Martin Ender

@KellyLowder Gli elenchi di caratteri sono rappresentazioni valide di stringhe su PPCG. È un po 'imbarazzante in Mathematica, dove normalmente non useresti quella rappresentazione, ma è comunque valido. Cercherò un meta post.
Martin Ender,

1
@KellyLowder Penso che questa è la politica accettato . Il motivo principale per cui è imbarazzante in Mathematica è che Mathematica non ha un tipo di carattere reale, quindi i personaggi finiscono per essere stringhe singleton.
Martin Ender,


5

05AB1E , 18 byte

ā<Œ¯¸«ʒRõsǝÂQ}éнèJ

Utilizza la codifica 05AB1E . Provalo online!


Interessante utilizzo del filtro lì ... Stavamo provando a fare un tipo di affare "a senza b", ma se ci fossero due casi di sottostringa, avremmo ottenuto falsi negativi. Sembra che stessimo complicando troppo adesso che vedo questo lol. Noice, ti darò una taglia 100 in 2 giorni.
Magic Octopus Urn

ǝera seriamente geniale però.
Magic Octopus Urn,



2

Japt , 26 22 byte

¬£¬ËUjEY ꬩUtEY
c æ+0

Provalo online! Cercando di capire come mappare falsequalcosa di falso e qualsiasi stringa a qualcosa di vero in un byte. Attualmente sto usando +0...


2

Bash , 108 byte

for((j=0;;j++)){
for((i=0;i<${#1};i++)){
r=${1:0:i}${1:j+i}
[[ $r = `rev<<<$r` ]]&&echo "${1:i:j}"&&exit
}
}

Accetta input come argomento della riga di comando.

Provalo online! con le virgolette stampate attorno all'output per visualizzare gli spazi iniziali / finali.


2

Prolog , 271 byte

p([_]).
p([X,X]).
p([X|Y]):-append([P,[X]],Y),p(P).

s(P,M,S,R,N):-p(P),append([M,S],N).
s(P,M,S,S,N):-p(S),append([P,M],N).
s(P,M,S,P,M):-append([P,S],X),p(X).

d(Y,P,N):-
    findall([A,B,C],(append([R,M,X],Y),s(R,M,X,B,C),length(B,A)),S),
    sort(1,@>,S,[[_,P,N]|_]).

Ad un certo punto mi sono reso conto che questo sarebbe stato enorme per gli standard del code-golf, quindi ho mantenuto alcuni spazi extra per preservare la somiglianza con la versione non offuscata. Ma penso ancora che potrebbe essere interessante dal momento che si tratta di un approccio diverso al problema.

La versione non offuscata:

palindrome([_]).
palindrome([X, X]).
palindrome([X | Xs]) :-
    append([Prefix, [X]], Xs),
    palindrome(Prefix).

palindrome_split(Prefix, Mid, Suffix, Prefix, N) :-
    palindrome(Prefix),
    append([Mid, Suffix], N).
palindrome_split(Prefix, Mid, Suffix, Suffix, N) :-
    palindrome(Suffix),
    append([Prefix, Mid], N).
palindrome_split(Prefix, Mid, Suffix, P, Mid) :-
    append([Prefix, Suffix], P),
    palindrome(P).

palindrome_downgrade(NP, P, N):-
    findall(
        [La, Pa, Na],
        (append([Prefix, Mid, Suffix], NP),
         palindrome_split(Prefix, Mid, Suffix, Pa, Na),
         length(Pa, La)),
        Palindromes),
    sort(1, @>, Palindromes, [[_, P, N] | _]).

2

C ++, 254 248 246 byte

-6 byte grazie a Zacharý -2 byte grazie a Toby Speight

#include<string>
#define S size()
#define T return
using s=std::string;int p(s t){for(int i=0;i<t.S;++i)if(t[i]!=t[t.S-i-1])T 0;T 1;}s d(s e){if(!p(e))for(int i,w=1;w<e.S;++w)for(i=0;i<=e.S-w;++i){s t=e;t.erase(i,w);if(p(t))T e.substr(i,w);}T"";}

Così...

  • Ho usato Tcome definizione macro perché fare R""come un altro effetto sul valore letterale di stringa (è un prefisso utilizzato per definire valori letterali di stringa non elaborati , vedere cppreference per ulteriori informazioni) che non è presente quando lo faccioT""
  • Le definizioni del preprocessore non possono trovarsi sulla stessa riga e devono avere almeno uno spazio tra il nome e il contenuto nella definizione
  • 2 funzioni: p(std::string)per verificare se la stringa è un palindromo. Se lo è, ritorna a 1chi lancia true, altrimenti ritorna a 0chi lanciafalse
  • L'algoritmo esegue il ciclo dell'intera stringa test se è un palindromo quando si cancella ogni volta 1 elemento, quindi si prova a cancellare 2 elementi (passa da quello alla dimensione massima della stringa), dal primo indice a the last index - number of erased char. Se trova che cancellare una parte è un palindromo, allora ritorna. Ad esempio, quando si passa la stringa "aabcdbaa"come parametro, entrambe ce dsono una risposta valida, ma questo codice restituirà cperché la cancellazione e il test se è un palindromo vengono prima del test se la cancellazione de il test se è il palindromo
  • Ecco il codice da testare:

    std::initializer_list<std::pair<std::string, std::string>> test{
        {"800233008","2"},
        { "racecarFOOL","FOOL" },
        { "abcdedcba","" },
        { "ngryL Myrgn","L " },
        { "123456789","12345678" },
        { "aabcdbaa","c" },
        { "[[]]","[[" },
        { "a","" },
        { "aabaab","b" }
    };
    
    for (const auto& a : test) {
        if (a.second != d(a.first)) {
            std::cout << "Error on : " << a.first << " - Answer : " << a.second  << " - Current : " << d(a.first) << '\n';
        }
    }

Funzionerebbe per l'ultima riga? using s=std::string;int p(s t){for(int i=0;i<t.S/2;++i)if(t[i]!=t[t.S-i-1])T 0;T 1;}s d(s e){if(!p(e))for(int i,w=1;w<e.S;++w)for(i=0;i<=e.S-w;++i){s t=e;t.erase(i,w);if(p(t))T e.substr(i,w);}T"";}
Zacharý,

Si può /2omettere? L'iterazione per tutta la lunghezza ripeterà semplicemente i test che abbiamo fatto, che dovrebbe essere innocuo. Potresti voler espandere ciò che intendi per "altro effetto" di R""(cioè è analizzato come una stringa grezza letterale).
Toby Speight,

Ho modificato questo e ho aggiunto il risultato come una mia risposta .
Toby Speight,


1

PHP 104 + 1 byte

while(~($s=$argn)[$e+$i++]?:++$e|$i=0)strrev($t=substr_replace($s,"",$i,$e))==$t&&die(substr($s,$i,$e));

Esegui come pipe -nRo provalo online .


1

Haskell , 109 105 byte

snd.minimum.([]#)
p#s@(a:b)=[(i,take i s)|i<-[0..length s],(==)<*>reverse$p++drop i s]++(p++[a])#b
p#_=[]

Provalo online!

EDIT: Grazie @ H.PWiz per il decollo di 4 byte! Devo migliorare con quelle monadi!


1

JavaScript, 90 byte

a=>a.map((_,p)=>a.map((_,q)=>k||(t=(b=[...a]).splice(q,p),k=''+b==b.reverse()&&t)),k=0)&&k

Provalo online!



1

JavaScript (ES6), 91 78 byte

(s,i=0,j=0,S=[...s],b=S.splice(i,j))=>S+''==S.reverse()?b:f(s,s[++i]?i:!++j,j)

Input e output sono elenchi di caratteri.

Rimuove ricorsivamente una porzione sempre più grande dall'input fino a trovare un palindromo.

Frammento:


1

TSQL (2016) 349B

Non la soluzione più compatta ma semplice:

DECLARE @i VARCHAR(255)='racecarFOOL'
;WITH DAT(v,i,l)AS(SELECT value,(ROW_NUMBER()OVER(ORDER BY value))-1,LEN(@i)FROM STRING_SPLIT(REPLICATE(@i+';',LEN(@i)+1),';')WHERE value<>'')
SELECT TOP 1C,S
FROM(SELECT LEFT(D.v, D.i)+SUBSTRING(D.v,D.i+E.i+1,D.l)C,SUBSTRING(D.v,D.i+1,E.i)S
FROM DAT D CROSS APPLY DAT E)C
WHERE C=REVERSE(C)
ORDER BY LEN(C)DESC

È possibile utilizzare @come variabile per pochi byte. Nel CTE è possibile utilizzare where''=value)per un altro e non è necessario restituire Cil risultato.
MickyT,

1

Buccia , 18 byte

◄LfmS=↔†!⁰ṠM-Qŀ⁰Q⁰

Provalo online!

Spiegazione

◄LfmS=↔†!⁰ṠM-Qŀ⁰Q⁰  Input is a string, say s="aab"
              ŀ⁰    Indices of s: x=[1,2,3]
             Q      Slices: [[],[1],[1,2],[2],[1,2,3],[2,3],[3]]
          ṠM-       Remove each from x: [[1,2,3],[2,3],[3],[1,3],[],[1],[1,2]]
       †!⁰          Index into s: ["aab","ab","b","ab","","a","aa"]
   mS=↔             Check which are palindromes: [0,0,1,0,1,1,1]
  f             Q⁰  Filter the slices of s by this list: ["aa","aab","ab","b"]
◄L                  Minimum on length: "b"

1

Haskell , 98 94 81 80 byte

""#0
(h#n)t|(==)=<<reverse$h++drop n t=take n t|x:r<-t=(h++[x])#n$r|m<-n+1=t#m$h

Provalo online! Esempio di utilizzo: ""#0 $ "aabaab"rese "b".

Modifica: -1 byte grazie a Ørjan Johansen.


1
Puoi sostituire l'ultimo ""con t.
Ørjan Johansen,

1

C ++, 189 186 176 167 byte

Ho iniziato con la risposta di HatsuPointerKun , cambiando il test per confrontare semplicemente l'uguaglianza con la stringa invertita; poi ho cambiato il modo in cui enumeriamo le stringhe candidate. Successivamente, le macro sono state utilizzate solo una o due volte ciascuna, ed è stato più breve per incorporarle.

#include<string>
using s=std::string;s d(s e){for(int i,w=0;;++w){s t=e.substr(w);for(i=-1;++i<=t.size();t[i]=e[i])if(t==s{t.rbegin(),t.rend()})return e.substr(i,w);}}

Spiegazione

Codice leggibile equivalente:

std::string downgrade(std::string e)
{
    for (int w=0; ; ++w) {
        std::string t = e.substr(w);
        for (int i=0;  i<=t.size();  ++i) {
            if (t == std::string{t.rbegin(),t.rend()})
                // We made a palindrome by removing w chars beginning at i
                return e.substr(i,w);
            t[i] = e[i];  // next candidate
        }
    }
}

L'enumerazione dei candidati inizia inizializzando una stringa con i primi wcaratteri omessi e quindi copiando i caratteri successivi dall'originale per spostare il divario. Ad esempio, con la stringa foobare w== 2:

foobar
  ↓↓↓↓
  obar
foobar
↓
fbar
foobar
 ↓
foar
foobar
  ↓
foor
foobar
   ↓
foob

Il primo passaggio (con w== 0) è un no-op, quindi l'intera stringa verrà considerata più e più volte. Va bene: il golf ha la meglio sull'efficienza! L'ultima iterazione di questo ciclo accederà all'indice one-past-the-end; Mi sembra di cavarmela con GCC, ma rigorosamente è un comportamento indefinito.

Programma di test

Un passaggio diretto dalla risposta di HatsuPointerKun :

static const std::initializer_list<std::pair<std::string, std::string>> test{
    { "800233008", "2" },
    { "racecarFOOL", "FOOL" },
    { "abcdedcba", "" },
    { "ngryL Myrgn", "L " },
    { "123456789", "12345678" },
    { "aabcdbaa", "c" },
    { "[[]]", "[[" },
    { "a","" },
    { "aabaab", "b" }
};

#include <iostream>
int main()
{
    for (const auto& a : test) {
        if (a.second != d(a.first)) {
            std::cout << "Error on: " << a.first
                      << " - Expected: " << a.second
                      << " - Actual: " << d(a.first) << '\n';
        }
    }
}

0

REXX, 132 byte

a=arg(1)
l=length(a)
do i=1 to l
  do j=0 to l-i+1
    b=delstr(a,i,j)
    if b=reverse(b) & m>j then do
      m=j
      s=substr(a,i,j)
      end
    end
  end
say s


0

C (gcc) , 307 byte

#define T malloc(K)
P(S,i,y,z,k,u,L,K,V)char*S;{char*M,*R,*E;K=strlen(S);M=T;R=T;E=T;for(i=0;i<K;++i){for(y=0;y<=K-i;++y){strcpy(M,S);for(z=y;z<y+i;E[z-y]=M[z],++z);for(k=y;k+i<=K;M[k]=M[k+i],++k);V=strlen(M);strcpy(R,M);for(u=0;u<V/2;L=R[u],R[u]=R[V-u-1],R[V-u-1]=L,++u);if(!strcmp(M,R))puts(E),exit(0);}}}

Provalo online!

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.