Eliminar una letra para hacer un palíndromo

15

Problema

Digamos que una palabra es casi un palíndromo si es posible eliminar una de sus letras para que la palabra se convierta en un palíndromo. Su tarea es escribir un programa que, para una palabra determinada, determine qué letra eliminar para obtener un palíndromo.

El código más corto para hacer esto en cualquier lenguaje de programación gana.

Entrada

La entrada consiste en una palabra de letras mayúsculas de 2 a 1000 caracteres de longitud.

Salida

Imprima la posición indexada 1 (la letra más a la izquierda tiene la posición 1, la siguiente tiene la posición 2 y así sucesivamente) de la letra que debe eliminarse. Si hay opciones posibles que conducen al palíndromo, envíe cualquiera de esas posiciones. Tenga en cuenta que debe eliminar una letra incluso si la palabra dada ya es un palíndromo. Si la palabra dada no es casi un palíndromo, salida -1.


Ejemplo

La entrada:

racercar

podría producir la salida:

5

porque quitando la 5letra th produce racecar, que es un palíndromo.

Además, la entrada

racecar

todavía puede producir la salida

4

porque eliminar la 4letra th para producir raccartodavía es un palíndromo.

Usuario011001
fuente
55
No hay ejemplos publicados? ¿Y qué generar si no es posible hacer la entrada en un Palindrome?
ProgramadorDan
3
@ Arm103 todavía te faltan los ejemplos a los que te refieres
Martin Ender
27
Advertencia: "(ver ejemplo 3)". Esto sugiere que esto es tarea ya que nunca se publicaron ejemplos.
Justin
3
@Quincunx Asegúrese de leer el hilo en la presentación de Mathematica, también. :-)
Chris Jester-Young
3
Esta pregunta parece estar fuera de tema porque falta el ejemplo 3 de la pregunta.
devnull

Respuestas:

10

J - 31 25 char

(_1{ ::[1+[:I.1(-:|.)\.])

Tarifa estándar en gran medida para J, así que solo señalaré los bits geniales.

  • El adverbio \.se llama Outfix . x u\. yquita cada infija de longitud xa partir de yy se aplica ual resultado de cada suspensión. Aquí, xes 1, yes la cadena de entrada y ues (-:|.)una prueba de si la cadena coincide con su reverso. Por lo tanto, el resultado de esta aplicación \.es una lista de booleanos, 1 en lugar de cada carácter cuya eliminación hace que la entrada sea un palíndromo.

  • I.crea una lista de todos los índices (origen 0) desde arriba donde había un 1. Agregar 1 con 1+hace que estos índices de origen 1. Si no hay índices 1, la lista está vacía. Ahora, tratamos de tomar el último elemento con _1{. (¡Se nos permite enviar cualquiera de las letras extraíbles!) Si esto funciona, volveremos. Sin embargo, si la lista estaba vacía, no había elementos en absoluto, por lo que {arroja un error de dominio que atrapamos ::y devolvemos el -1 con [.

Uso (recuerde que NB.es para comentarios):

   (_1{ ::[1+[:I.1(-:|.)\.]) 'RACECAR'    NB. remove the E
4
   (_1{ ::[1+[:I.1(-:|.)\.]) 'RAACECAR'   NB. remove an A
3
   (_1{ ::[1+[:I.1(-:|.)\.]) 'RAAACECAR'  NB. no valid removal
_1
Algoritmo de tiburón
fuente
Debo aprender J. ¿Algún tutorial para un programador de Python?
Aprıʇǝɥʇuʎs
1
@Synthetica la oficial es buena
John Dvorak
2
@Synthetica Nada específicamente para Pythoners, pero J for C Programmers es un gran recurso para cualquiera que migre de la programación imperativa.
Algoritmo de tiburón
10

Python no PHP (73):

[a[:g]+a[g+1:]==(a[:g]+a[g+1:])[::-1] for g in range(len(a))].index(1)

Donde a es la cadena que desea verificar. Esto, sin embargo, arroja un error si no puede convertirlo en un palíndromo. En cambio, podrías usar

try:print [a[:g]+a[g+1:]==(a[:g]+a[g+1:])[::-1] for g in range(len(a))].index(True)
except ValueError:print -1

EDITAR: No, espera, ¡funciona!

try: eval("<?php $line = fgets(STDIN); ?>")
except: print [a[:g]+a[g+1:]==(a[:g]+a[g+1:])[::-1] for g in range(len(a))].index(1)

Gracias, esto realmente aumenta el contenido de php de este script en aproximadamente un 25% (eso es lo que quieres, ¿verdad?)

ɐɔıʇǝɥʇuʎs
fuente
10
+1 para "No PHP";)
Martin Ender
1
<? php $ line = fgets (STDIN); ?>
User011001
2
@ User011001 ¿Dónde encajaría eso?
Aprıʇǝɥʇuʎs
1
Puede guardar un personaje cada uno escribiendo en 1>0lugar de Truey eliminando el espacio entre ]y foren...[::-1] for g...
Kaya
1
@Kaya Simplemente puede usar en 1lugar de Truetambién. 1 == True, después de todo.
arshajii
5

Mathematica, 106 98 87 91 caracteres

Supongo que estoy un poco discapacitado por los nombres largos de funciones, pero problemas como este son bastante divertidos en Mathematica:

f=Tr@Append[Position[c~Drop~{#}&/@Range@Length[c=Characters@#],l_/;l==Reverse@l,{1}],{-1}]&

Lanza algunas advertencias, porque el l_patrón también coincide con todos los caracteres dentro, que Reverseno pueden funcionar. Pero oye, ¡funciona!

Algo sin golf:

f[s_] := 
  Append[
    Cases[
      Map[{#, Drop[Characters[s], {# }]} &, Range[StringLength[s]]], 
      {_, l_} /; l == Reverse[l]
    ], 
    {-1}
  ][[1, 1]]
Martin Ender
fuente
2
@ Arm103 Podría, pero se lo dejaré a otra persona. ;)
Martin Ender
2
@ Arm103 espera, ¿es esta tu tarea?
John Dvorak
2
@ JanDvorak ¿Hay cursos de CS que usan PHP? Eso daría miedo.
Chris Jester-Young
2
@ Arm103 no. No puedes ;-)
John Dvorak
44
@ JanDvorak hmmm, ¿qué es un programa en Mathematica?
Martin Ender
5

GolfScript, 28 26 caracteres

:I,,{)I/();\+.-1%=}?-2]0=)

Gracias a Peter por acortar en 2 personajes. Pruebe los casos de prueba en línea :

> "RACECAR" 
4
> "RAACECAR" 
2
> "RAAACECAR" 
-1
> "ABCC1BA" 
5
> "AAAAAA" 
1
> "ABCDE" 
-1
> "" 
-1
> "A" 
1
Howard
fuente
Supongo que debe haber un camino más corto pero no lo encontré.
Howard
RACECARsigue siendo un palíndromo con la E. ¿Es necesario especificar un carácter para eliminar, cuando la palabra ingresada ya es un palíndromo?
Unclemeat
@unclemeat, sí. Penúltima oración de la especificación.
Peter Taylor
¿Por qué -2]$-1=)? Al comienzo de ese bloque, tienes como máximo un elemento en la pila, por lo que puedes acortarlo fácilmente -2]0=). (O por la misma longitud, ]-2or)he aprendido a amar orlos casos especiales).
Peter Taylor
2
@Howard Si tuviera un centavo por cada vez que me sentí de esa manera sobre Golfscript ...
algorithmshark
3

Rebol (81)

r: -1 repeat i length? s[t: head remove at copy s i if t = reverse copy t[r: i]]r

Ejemplo de uso en la consola Rebol:

>> s: "racercar"
== "racercar"

>> r: -1 repeat i length? s[t: head remove at copy s i if t = reverse copy t[r: i]]r
== 5

>> s: "1234"
== "1234"

>> r: -1 repeat i length? s[t: head remove at copy s i if t = reverse copy t[r: i]]r 
== -1


Arriba devuelve el índice del último palíndromo encontrado. Una solución alternativa (85 caracteres) que devuelve cada palíndromo encontrado sería:

collect[repeat i length? s[t: head remove at copy s i if t = reverse copy t[keep i]]]

Entonces para "racercar"esto volvería la lista [4 5].

draegtun
fuente
Si utilizó el dialecto Rebmu, la primera solución tiene solo 37 caracteres, a pesar de ser básicamente el mismo código :-) Invocar como rebmu / args "Rng01rpNl? A [ThdRMatCYaNieTrvCYt [Rn]] r" "racecar" . Tenga en cuenta que la documentación de Rebmu se ha mejorado, y los cambios recientes la han endurecido un poco ... todavía están buscando comentarios antes de que todos y su D comiencen a usarla. :-)
HostileFork dice que no confíes en SE
3

C #, 134 caracteres

static int F(string s,int i=0){if(i==s.Length)return-1;var R=s.Remove(i,1);return R.SequenceEqual(R.Reverse())?i+1:F(s,i+1);}

Sé que pierdo :( pero aún así fue divertido : D

Versión legible:

using System.Linq;

// namespace and class

static int PalindromeCharIndex(string str, int i = 0)
{
    if (i == str.Length) return -1;
    var removed = str.Remove(i, 1);
    return removed.SequenceEqual(removed.Reverse()) 
        ? i+1
        : PalindromeCharIndex(str, i + 1); 
}
Will Newton
fuente
3
Yay divertido !!!!! :)
Almo
1
En la versión de golf, ¿dónde se Rdefine y se usa?
Cepillo de dientes
oh sí, debería decir var R = s. Remover (i, 1). buena captura
Will Newton
3

Stax , 8 10 bytes

ú·àA÷¡%5Ñ╙

Ejecutar y depurarlo

Este programa muestra todos los índices basados ​​en 1 que se pueden eliminar de la cadena para formar un palíndromo. Y si no hay ninguno, muestra -1.

recursivo
fuente
2
Esto genera el último índice en lugar de -1 si no se encuentra un palíndromo (es decir, aaabbsalidas en 5lugar de -1).
Kevin Cruijssen
1
@KevinCruijssen: Tienes razón. Lo arreglé al costo de 2 bytes.
recursivo el
2

Rubí (61):

(1..s.size+1).find{|i|b=s.dup;b.slice!(i-1);b.reverse==b}||-1

Aquí, ten una solución de rubí. Devolverá la posición del personaje a eliminar o -1 si no se puede hacer.

No puedo evitar sentir que hay mejoras con la sección de duplicación y corte, pero Ruby no parece tener un método de cadena que elimine un carácter en un índice específico y devuelva la nueva cadena -__-.

Editado según el comentario, ty!

Mike Campbell
fuente
1
Puede ahorrar algo de espacio no envolviendo una función / método. Sin embargo, su código actualmente devuelve un índice basado en 0 (debe estar basado en 1) y también debe regresar -1si no se encuentra un palíndromo.
draegtun
Arreglado el -1, gracias. Sin embargo, no estoy seguro de lo que tienes en mente para sacarlo de un método, lo pensaré.
Mike Campbell
Ok, tomé tu consejo a bordo y lo reescribí :), ty.
Mike Campbell
¡De nada! Ahora eso es mucho mejor :) +1
draegtun
2

05AB1E , 10 bytes

gL.Δõs<ǝÂQ

Pruébelo en línea o verifique algunos casos de prueba más .

Explicación:

g           # Get the length of the (implicit) input-string
 L          # Create a list in the range [1,length]
          # Find the first value in this list which is truthy for:
            # (which will output -1 if none are truthy)
    õ       #  Push an empty string ""
     s      #  Swap to get the current integer of the find_first-loop
      <     #  Decrease it by 1 because 05AB1E has 0-based indexing
       ǝ    #  In the (implicit) input-String, replace the character at that index with
            #  the empty string ""
        Â   #  Then bifurcate the string (short for Duplicate & Reverse copy)
         Q  #  And check if the reversed copy is equal to the original string,
            #  So `ÂQ` basically checks if a string is a palindrome)
            # (after which the result is output implicitly)
Kevin Cruijssen
fuente
2

No Python PHP ,85 83 81 bytes

while($argn[$x])$s!=strrev($s=substr_replace($argn,'',$x++,1))?:die("$x");echo-1;
  • -2 bytes gracias a @ Night2!

Pruébalo en línea!

Innecesariamente recursivo:

PHP , 96 bytes

function f($a,$b='',$d=1){return$a?$c==strrev($c=$b.$e=substr($a,1))?$d:f($e,$b.$a[0],$d+1):-1;}

Pruébalo en línea!

640 KB
fuente
1

Haskell, 107 caracteres:

(x:y)!1=y;(x:y)!n=x:y!(n-1)
main=getLine>>= \s->print$head$filter(\n->s!n==reverse(s!n))[1..length s]++[-1]

Como una función ( 85 caracteres ):

(x:y)!1=y;(x:y)!n=x:y!(n-1)
f s=head$filter(\n->s!n==reverse(s!n))[1..length s]++[-1]

versión original sin golf:

f str = case filter cp [1..length str] of
          x:_ -> x
          _   -> -1
    where cp n = palindrome $ cut n str
          cut (x:xs) 1 = xs
          cut (x:xs) n = x : cut xs (n-1)
          palindrome x = x == reverse x
John Dvorak
fuente
1

C # (184 caracteres)

Admito que este no es el mejor lenguaje para hacer golf de código ...

using System.Linq;class C{static void Main(string[]a){int i=0,r=-1;while(i<a[0].Length){var x=a[0].Remove(i++,1);if(x==new string(x.Reverse().ToArray()))r=i;}System.Console.Write(r);}}

Formateado y comentado:

using System.Linq;

class C
{
    static void Main(string[] a)
    {
        int i = 0, r = -1;
        // try all positions
        while (i < a[0].Length)
        {
            // create a string with the i-th character removed
            var x = a[0].Remove(i++, 1);
            // and test if it is a palindrome
            if (x == new string(x.Reverse().ToArray())) r = i;
        }
        Console.Write(r);
    }
}
Mormegil
fuente
1

C # (84 caracteres)

int x=0,o=i.Select(c=>i.Remove(x++,1)).Any(s=>s.Reverse().SequenceEqual(s))?x:-1;

Sentencia LINQpad esperando que la variable icontenga la cadena de entrada. La salida se almacena en la ovariable.

Oskar Sjöberg
fuente
1

Haskell, 80

a%b|b<1=0-1|(\x->x==reverse x)$take(b-1)a++b`drop`a=b|1<2=a%(b-1)
f a=a%length a

Llamado así:

λ> f "racercar"
5
Flonk
fuente
1

Japt , 8 bytes

a@jYÉ êS

Intentalo

a@jYÉ êS     :Implicit input of string
a            :Last 0-based index that returns true (or -1 if none do)
 @           :When passed through the following function as Y
  j          :  Remove the character in U at index
   YÉ        :    Y-1
      êS     :  Is palindrome?
Lanudo
fuente
0

Haskell, 118C

m s|f s==[]=(-1)|True=f s!!0
f s=[i|i<-[1..length s],r s i==(reverse$r s i)]
r s i=let(a,_:b)=splitAt (i-1) s in a++b

Sin golf:

fix s
    |indices s==[] = (-1)
    |True = indices s!!0
indices s = [i|i<-[1..length s],remove s i==(reverse$remove s i)]
remove s i = let (a,_:b) = (splitAt (i-1) s) in a++b
danmcardle
fuente
0

Jalea , 17 14 bytes

ŒPṖLÐṀṚŒḂ€TXo-

Pruébalo en línea!

           X      A random
          T       truthy index
ŒP                from the powerset of the input
  Ṗ               excluding the input
   LÐṀ            and all proper subsequences with non-maximal length
      Ṛ           reversed
       ŒḂ€        with each element replaced with whether or not it's a palindrome,
            o-    or -1.

Como cambié mi enfoque lo suficientemente rápido como para que la versión anterior no apareciera en el historial de edición, fue esto: ŒPṚḊŒḂ€TṂ©’<La®o-

Cadena no relacionada
fuente
0

Brachylog , 24 bytes

{l+₁≥.ℕ₂≜&↔⊇ᶠ↖.tT↔T∨0}-₁

Pruébalo en línea!

Se siente demasiado tiempo.

Podría ser dos bytes más corto si la salida pudiera ser indexada en 2 :

l+₁≥.ℕ₂≜&↔⊇ᶠ↖.tT↔T∨_1

Dos iteraciones anteriores e incluso peores:

ẹ~c₃C⟨hct⟩P↔P∧C;Ȯ⟨kt⟩hl<|∧_1
l>X⁰ℕ≜<.&{iI¬tX⁰∧Ih}ᶠP↔P∨_1

El uso de una variable global por parte de este último requiere un encabezado de prueba diferente .

Cadena no relacionada
fuente
0

Python 3 , 71 bytes

def f(s,i=1):n=s[:i-1]+s[i:];return(n==n[::-1])*i-(i>len(s))or f(s,i+1)

Pruébalo en línea!

Devuelve el carácter indexado 1 si la operación se puede realizar y de lo -1contrario.

Jitse
fuente
0

C (gcc) , 180 168 159 157 140 139 bytes

f(char*s){int j=strlen(s),m=j--/2,p=-1,i=0;for(;p&&i<m;)p=s[i++]^s[j--]&&!++p?s[i]-s[j+1]?s[i-1]-s[j]?p:j--+2:i++:p;return p<0?m+1:p?p:-1;}

Pruébalo en línea!

2 16 17 bytes recortados gracias a ceilingcat! Y 3 bytes más, ya que las reglas establecen que la longitud mínima de la entrada es de 2 caracteres, por lo que no tiene que buscar cadenas vacías.

Sin golf:

f(char *s) {
  int j = strlen(s);             // j = length of input
  int m = j-- / 2;               // m = midpoint of string,
                                 // j = index of right character
  int p = -1;                    // p = position of extra character
                                 //     -1 means no extra character found yet
                                 //     0 means invalid input
  int i = 0;                     // i = index of left character

  for (; p && i < m; i++) {      // loop over the string from both sides,
                                 // as long as the input is valid.
    p = s[i] ^ s[j--]            // if (left character != right character
        && !++p ?                //     and we didn't remove a character yet*)
          s[i + 1] - s[j + 1] ?  //   if (left+1 char != right char)
            s[i] - s[j] ?        //     if (left char != right-1 char)
              p                  //       do nothing,
            :                    //     else
              j-- + 2            //       remove right char.
          :                      //   else
            ++i                  //       remove left char.
        :                        // else
          p;                     //     do nothing, or:
                                 //     *the input is marked invalid 
  } 

  return p < 0 ?                 // if (input valid and we didn't remove a character yet)
           m + 1                 //   return the midpoint character,
         :                       // else
           p ?                   //   if (we did remove a character)
             p                   //     return that character,
           :                     //   else
             -1;                 //     the input was invalid.
}
```
G. Sliepen
fuente
@ceilingcat Eso &&!++pes complicado de explicar :)
G. Sliepen
-1

Python, 84

for i in range(len(s)):
    if s[i]!=s[-(i+1)]:
        if s[i]!=s[-(i+2)]:
            return i+1
        else:
            return len(s)-i

Esto no verifica si la entrada (cadena) es casi palíndromo, pero es eficiente en el tiempo y legible.

nicofmay
fuente
2
s[-(i+1)]se puede acortar a s[-i-1]. Además, no estoy seguro, pero puede reemplazarlo if...else...conreturn i+1 if ... else len(s)-1
user12205
Esto funcionó bien ... ¿Alguien puede explicar la lógica detrás de esto?
Arindam Roychowdhury
El requisito es que genera -1 si la entrada no es un palíndromo con una letra adicional. Entonces, por ejemplo, si s = "abcde", debería devolver -1.
G. Sliepen
-2

Mi primer código de golf.

Java. ~ 1200 caracteres en las funciones principales (y secundarias). Sí bebé.

Clase superior y uso:

public class ElimOneCharForPalindrome  {
   public static final void main(String[] ignored)  {
      System.out.println(getEliminateForPalindromeIndex("racercar"));
      System.out.println(getEliminateForPalindromeIndex("racecar"));
   }

La función principal:

   public static final int getEliminateForPalindromeIndex(String oneCharAway_fromPalindrome)  {
      for(int i = 0; i < oneCharAway_fromPalindrome.length(); i++)  {
         String strMinus1Char = oneCharAway_fromPalindrome.substring(0, i) + oneCharAway_fromPalindrome.substring(i + 1);

         String half1 = getFirstHalf(strMinus1Char);
         String half2Reversed = getSecondHalfReversed(strMinus1Char);

         if(half1.length() != half2Reversed.length())  {
            //One half is exactly one character longer
            if(half1.length() > half2Reversed.length())  {
               half1 = half1.substring(0, (half1.length() - 1));
            }  else  {
               half2Reversed = half2Reversed.substring(0, (half2Reversed.length() - 1));
            }
         }

         //System.out.println(i + " " + strMinus1Char + " --> " + half1 + " / " + half2Reversed + "  (minus the singular [non-mirrored] character in the middle, if any)");

         if(half1.equals(half2Reversed))  {
            return  i;
         }
      }
      return  -1;
   }

Subfunciones:

   public static final String getFirstHalf(String whole_word)  {
      return  whole_word.substring(0, whole_word.length() / 2);
   }
   public static final String getSecondHalfReversed(String whole_word)  {
      return  new StringBuilder(whole_word.substring(whole_word.length() / 2)).reverse().toString();
   }
}

Clase completa:

public class ElimOneCharForPalindrome  {
   public static final void main(String[] ignored)  {
      System.out.println(getEliminateForPalindromeIndex("racercar"));
      System.out.println(getEliminateForPalindromeIndex("racecar"));
   }
   public static final int getEliminateForPalindromeIndex(String oneCharAway_fromPalindrome)  {
      for(int i = 0; i < oneCharAway_fromPalindrome.length(); i++)  {
         String strMinus1Char = oneCharAway_fromPalindrome.substring(0, i) + oneCharAway_fromPalindrome.substring(i + 1);

         String half1 = getFirstHalf(strMinus1Char);
         String half2Reversed = getSecondHalfReversed(strMinus1Char);

         if(half1.length() != half2Reversed.length())  {
            //One half is exactly one character longer
            if(half1.length() > half2Reversed.length())  {
               half1 = half1.substring(0, (half1.length() - 1));
            }  else  {
               half2Reversed = half2Reversed.substring(0, (half2Reversed.length() - 1));
            }
         }

         //System.out.println(i + " " + strMinus1Char + " --> " + half1 + " / " + half2Reversed + "  (minus the singular [non-mirrored] character in the middle, if any)");

         if(half1.equals(half2Reversed))  {
            return  i;
         }
      }
      return  -1;
   }
   public static final String getFirstHalf(String whole_word)  {
      return  whole_word.substring(0, whole_word.length() / 2);
   }
   public static final String getSecondHalfReversed(String whole_word)  {
      return  new StringBuilder(whole_word.substring(whole_word.length() / 2)).reverse().toString();
   }
}
mente mental
fuente
3
Esto no muestra ningún intento de jugar golf en el código.
mbomb007