14 - Ejemplo práctico 5: palíndromos con historial

14.1 Objetivo

Crear una herramienta que verifique si una cadena es un palíndromo ignorando espacios y mayúsculas, y que permita deshacer/rehacer verificaciones para volver rápidamente a resultados previos.

14.2 Limpieza de texto

  • Quitar espacios, signos de puntuación y convertir a minúsculas.
  • Solo los caracteres alfanuméricos forman parte de la verificación.

14.3 Verificación con pilas

Se usa una pila para comparar simultáneamente los extremos. Dos enfoques:

  1. Dividir la cadena en mitad y apilar la primera mitad.
  2. Usar una pila para recorrer de derecha a izquierda y comparar con el recorrido normal.

El ejemplo a continuación opta por el segundo enfoque para mantenerlo simple.

14.4 Historial con undo/redo

Mantenemos dos pilas de cadenas:

  • Resultados: almacena los textos evaluados junto con el veredicto.
  • Redo: permite rehacer cuando se deshace una evaluación.

Cuando se ejecuta una nueva verificación, se límpia la pila Redo.

14.5 Implementación en Python

def normalizar(texto):
  limpio = []
  for c in texto:
    if c.isalnum():
      limpio.append(c.lower())
  return "".join(limpio)


def es_palindromo(texto):
  limpio = normalizar(texto)
  return limpio == limpio[::-1]


class Verificador:
  def __init__(self):
    self.historial = []
    self.redo_stack = []

  def check(self, texto):
    resultado = f'"{texto}" => {"PALINDROMO" if es_palindromo(texto) else "NO PALINDROMO"}'
    self.historial.append(resultado)
    self.redo_stack.clear()
    return resultado

  def undo(self):
    if not self.historial:
      return "Nada para deshacer"
    valor = self.historial.pop()
    self.redo_stack.append(valor)
    return self.historial[-1] if self.historial else "Historial vacio"

  def rehacer(self):
    if not self.redo_stack:
      return "Nada para rehacer"
    valor = self.redo_stack.pop()
    self.historial.append(valor)
    return valor


if __name__ == "__main__":
  v = Verificador()
  print(v.check("Anita lava la tina"))
  print(v.check("Hola mundo"))
  print("Undo ->", v.undo())
  print("Redo ->", v.rehacer())
  print(v.check("Yo hago yoga hoy"))
  print("Top:", v.historial[-1])

14.6 Controles adicionales

  • Añadir una pila separada para mostrar los resultados previos en pantalla.
  • Exportar el historial a un archivo de texto.
  • Agregar soporte para cadenas Unicode con librerías especializadas.