Rétrograder à un palindrome

47

Étant donné une chaîne s, retourne la plus petite sous-chaîne contiguë que vous pouvez supprimer pour créer un palindrome.


Exemples:

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

Suggestions de cas de test des utilisateurs (si vous trouvez un cas de bord non répertorié, merci de poster un commentaire):

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

Règles

  • Seuls les caractères ASCII imprimables apparaîtront dans l'entrée (pas de nouvelle ligne, restez simple).
  • Pas vraiment une règle, mais notez <>, /\, (), []et {}ne sont pas palindromes.

C'est le , le plus petit nombre d'octets gagnés.


+ 100 primes ont été réclamées par Adnan

Urne Magique De Pieuvre
la source
3
Affaire Tesf:aabaab
Zgarb
14
Je pense que cela aidera à garder les questions accessibles à plus de visiteurs si l'on évite le jargon du groupe tel que "CMC" (en le regardant, cela semble signifier "mini défi", ce qui, je suppose, signifie un petit défi affiché dans la salle de discussion associée à ce site).
ShreevatsaR
N'est-ce pas [[]]un palindrome?
Carl
4
@Carl Ça peut en avoir l'air, mais quand vous inversez les caractères, vous obtenez ]][[. Considérez que aabbc'est la même chose, juste des personnages différents.
Conor O'Brien
1
" (sera attribué 7/12) " hein?
Erik the Outgolfer

Réponses:

8

Gelée , 16 octets

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

Essayez-le en ligne!

Comment ça fonctionne

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.
Dennis
la source
10

J , 24 octets

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

Essayez-le en ligne!

Explication

(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
milles
la source
Peut-être voudrez-vous peut-être choisir (;&quote f)&>le verbe harnais de test?
Conor O'Brien
7

Wolfram Language (Mathematica) , 53 51 octets

Le nombre d'octets suppose le codage CP-1252.

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

Essayez-le en ligne!

Définit un opérateur unaire ±(ou une fonction PlusMinus). L'entrée et la sortie sont des listes de caractères. La suite de tests effectue la conversion depuis et vers les chaînes réelles pour plus de commodité.

Martin Ender
la source
Est- Reversece que la comparaison de l'inverse de l'original est plus courte que PalindromeQ? Je ne connais pas Mathematica, alors aucune idée.
Urne magique Octopus
Bonne réponse, mais ne devrait-on pas prendre en compte le fractionnement des chaînes et leur réunion dans le décompte de vos personnages? Characters@#/.{a___,Shortest@b___,c___}/;PalindromeQ[a<>c]:>b~~""&
Kelly Lowder
@MagicOctopusUrn Reverse[x={a,c}]==xest deux octets plus long. Je ne sais pas s'il existe une alternative plus courte.
Martin Ender
@KellyLowder Les listes de caractères sont des représentations valides de chaînes sur PPCG. C'est un peu gênant dans Mathematica, où vous n'utiliseriez pas normalement cette représentation, mais qui reste valable. Je vais chercher un meta post.
Martin Ender
1
@ KellyLowder Je pense que c'est la politique acceptée . La principale raison pour laquelle il est gênant dans Mathematica est que Mathematica n’a pas de type de caractère réel, de sorte que les caractères finissent par être des chaînes singleton.
Martin Ender
5

05AB1E , 18 octets

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

Utilise le codage 05AB1E . Essayez-le en ligne!

Adnan
la source
Utilisation intéressante du filtre ici ... Nous essayions de faire une transaction de type "a sans b", mais s'il y avait deux occurrences de la sous-chaîne, nous obtiendrions de faux négatifs. On se sent trop compliquer maintenant que je vois ce lol. Noice, je te donnerai une prime de 100 en 2 jours.
Urne Magique Octopus
ǝétait sérieusement génie cependant.
Urne Magique Octopus
4

Python 3 , 97 octets

f=lambda s,p='	':min([s][:p[::-1]in p+p]+(s and[f(s[1:],p+s[0]),f(s[:-1],s[-1]+p)]or[p]),key=len)

Essayez-le en ligne!

Dennis
la source
3

Python 2 , 116 octets

def f(i):R=range(len(i)+1);print min([i[y:k+1]for y in R for k in R if(i[:y]+i[k+1:])[::-1]==i[:y]+i[k+1:]],key=len)

Essayez-le en ligne!

Enregistré quelques octets avec l'aide de Halvard Hummel !

M. Xcoder
la source
117 octets
Halvard Hummel
@HalvardHummel Merci, je prévoyais de changer cela aussi, mais je n'avais pas de connexion Internet depuis 2 heures.
M. Xcoder
2

Japt , 26 22 octets

¬£¬ËUjEY ꬩUtEY
c æ+0

Testez-le en ligne! Essayer de comprendre comment mapper falseà quelque chose de faux et n'importe quelle ficelle à quelque chose de vrai dans un octet. Actuellement , je suis en utilisant +0...

ETHproductions
la source
2

Bash , 108 octets

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

Prend l'entrée comme argument de ligne de commande.

Essayez-le en ligne! avec des guillemets imprimés autour de la sortie pour visualiser les espaces de début / fin.

Justin Mariner
la source
2

Prolog , 271 octets

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]|_]).

À un moment donné, j'ai réalisé que cela allait être énorme en termes de code-golf, alors j'ai gardé quelques espaces vierges supplémentaires pour préserver la ressemblance avec la version non obfusquée. Mais je pense toujours que cela pourrait être intéressant car c'est une approche différente du problème.

La version non-obscurcie:

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] | _]).
wvxvw
la source
2

C ++, 254 248 246 octets

-6 octets grâce à Zacharý -2 octets grâce à 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"";}

Alors...

  • J'ai utilisé Tcomme définition de macro parce que faire R""comme un autre effet sur le littéral chaîne (c'est un préfixe utilisé pour définir les littéraux chaîne bruts, voir cppreference pour plus d'informations) qui n'est pas là quand je le faisT""
  • Les définitions de préprocesseur ne peuvent pas être sur la même ligne et doivent avoir au moins un espace entre le nom et le contenu de la définition
  • 2 fonctions: p(std::string)tester si la chaîne est un palindrome. Si c'est le cas, il retourne 1qui jette à true, sinon il retourne 0, qui jette àfalse
  • L'algorithme parcourt toute la chaîne en testant s'il s'agit d'un palindrome lors de l'effacement d'un élément à chaque fois, puis teste l'effacement de 2 éléments (boucles sur celle-ci jusqu'à la taille maximale de la chaîne), du premier index à the last index - number of erased char. S'il trouve que l'effacement d'une partie est un palindrome, alors, il revient. Par exemple, lorsque vous transmettez la chaîne en "aabcdbaa"tant que paramètre, les deux cet dsont une réponse valide, mais ce code sera renvoyé ccar l'effacement et la vérification si c'est un palindrome vient avant de vérifier si l'effacement est correct det si c'est toujours le cas.
  • Voici le code à tester:

    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';
        }
    }
HatsuPointerKun
la source
Cela fonctionnerait-il pour la dernière ligne? 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ý
Peut- /2on l'omettre? Itérer sur toute la longueur ne fera que répéter les tests que nous avons effectués, ce qui devrait être sans danger. Vous voudrez peut-être développer ce que vous entendez par "autre effet" R""(c’est-à-dire qu’il est analysé comme un littéral de chaîne brute).
Toby Speight
J'ai modifié cela et ajouté le résultat comme réponse personnelle .
Toby Speight
1

Gelée , 33 octets

r/ḟ@J}ị
“”µJp`ç³$ŒḂ$Ðfạ/ÞḢr/ịµŒḂ?

Essayez-le en ligne!

HyperNeutrino
la source
1

PHP 104 + 1 octets

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

Exécuter en pipe -nRou essayer en ligne .

Titus
la source
1

Haskell , 109 105 octets

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

Essayez-le en ligne!

EDIT: Merci @ H.PWiz pour avoir décollé 4 octets! Je dois aller mieux avec ces monades!

utilisateur1472751
la source
1

JavaScript, 90 octets

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

Essayez-le en ligne!


la source
1

Perl 5, 72 +1 (-p) octets

$\=$_;/.*(?{$,=$`.$';$\=$&if length$&<length$\&&$,eq reverse$,})(?!)/g}{

Essayez-le en ligne

Nahuel Fouilleul
la source
1

JavaScript (ES6), 91 78 octets

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

L'entrée et la sortie sont des listes de caractères.

Supprime récursivement une coupe de plus en plus grande de l'entrée jusqu'à ce qu'un palindrome soit trouvé.

Fragment:

Rick Hitchcock
la source
1

TSQL (2016) 349B

Pas la solution la plus compacte mais la plus simple:

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
Jan Drozen
la source
Vous pouvez utiliser @comme variable pour quelques octets. Dans le CTE, vous pouvez utiliser where''=value)pour un autre et vous n'avez pas besoin de revenir Cdans le résultat.
MickyT
1

Coque , 18 octets

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

Essayez-le en ligne!

Explication

◄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"
Zgarb
la source
1

Haskell , 98 94 81 80 octets

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

Essayez-le en ligne! Exemple d'utilisation: ""#0 $ "aabaab"rendements "b".

Edit: -1 octet grâce à Ørjan Johansen.

Laikoni
la source
1
Vous pouvez remplacer le dernier ""par t.
Ørjan Johansen
1

C ++, 189 186 176 167 octets

J'ai commencé avec la réponse de HatsuPointerKun , modifiant le test pour simplement comparer l'égalité avec une chaîne inversée; alors j'ai changé la façon dont nous énumérons les chaînes candidates. Suite à cela, les macros n’ont été utilisées qu’une ou deux fois, et il était plus court de les aligner.

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

Explication

Code lisible équivalent:

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'énumération des candidats commence par initialiser une chaîne avec les premiers wcaractères omis, puis en copiant les caractères successifs de l'original pour déplacer l'espace. Par exemple, avec la chaîne foobaret w== 2:

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

La première passe (avec w== 0) est un no-op, donc la chaîne complète sera considérée encore et encore. C'est bien, le golf l'emporte sur l'efficacité! La dernière itération de cette boucle accédera à l'index du passé. Il me semble que je m'en sors avec GCC, mais strictement, c'est un comportement indéfini.

Programme de test

Une réponse directe de la réponse de 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';
        }
    }
}
Toby Speight
la source
0

REXX, 132 octets

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
idrougge
la source
0

Rubis , 86 84 octets

->s{l=i=0
(l+=(i+=1)/z=s.size-l+1
i%=z)while(w=s[0,i]+s[i+l..-1])!=w.reverse
s[i,l]}

Essayez-le en ligne!

  • 2 octets sauvés grâce à Cyoce
Rétablir Monica iamnotmaynard
la source
Vous n'avez pas besoin de parenthèses z=s.size-l+1.
Cyoce
@ Cyoce Merci. J'ai du mal à me souvenir de tous les précédents des opérateurs.
Rétablir Monica iamnotmaynard
0

C (gcc) , 307 octets

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

Essayez-le en ligne!

R. Kap
la source