Número palíndromo en PSeInt

Más ejercicios resueltos

Si deseas revisar más ejercicios resueltos, haz click en el siguiente botón. 

A continuación presentamos 3 alternativas de solución al problema de verificar si un número es palíndromo o capicúa en PSeInt. Si deseas ver el enunciado del problema, haz click en el siguiente enlace

A continuación presentamos la primera alternativa de solución al problema de número capicúa. Usaremos para su resolución el paradigma de programación modular y la técnica de diseño descendente. Asumiremos que algunos módulos ya existen y luego nos preocupamos de su implementación. 

La primera versión que revisaremos es la más clásica de todas. Se basa en invertir los dígitos del número. Veremos a continuación el módulo principal.

Módulo Principal

El objetivo del módulo principal es realizar la lectura del dato de entrada, en este caso el número \texttt{n}. Con el dato leído se invoca al módulo \texttt{es\_palindromo}, para determinar si es número en cuestión es palíndromo o no. En este módulo, no nos preocupamos en cómo implementar \texttt{es\_palindromo}, asumimos que ya existe y luego veremos cómo implementarla.

Dado que el enunciado indicaba que el número \texttt{n} era del tipo entero, es posible que el usuario ingrese números negativos. Por este motivo, antes de realizar la invocación, utilizamos la función \texttt{abs} para asegurar que no se invocará al módulo con número negativos.

palíndromo versión 1 módulo principal
Módulo Principal

Módulo palíndromo

El módulo \texttt{es\_palindromo} tiene por objetivo determinar si determinado número es palíndromo o no. Recibe como parámetro el número \texttt{n}. Se asume que este parámetro \texttt{n} es mayor o igual a cero. El módulo retorna \texttt{Verdadero} en caso el número sea palíndromo y \texttt{Falso} en caso contrario.

En realidad el algoritmo es bastante sencillo. Se basa en invertir el número \texttt{n} y si el número invertido es igual a \texttt{n}, entonces estaremos ante el caso de un número palíndromo.  Para invertir el número usamos el módulo \texttt{invierte\_numero}. Como estamos aplicando la técnica de diseño descendente, en este módulo no nos preocupamos por la implementación de \texttt{invierte\_numero}. Asumimos que este módulo existe y luego la implementaremos. De esta forma estamos encapsulando la complejidad del problema.

palíndromo versión 1 módulo es_palindromo
Módulo palíndromo

Módulo número invertido

En esta parte, nos dedicaremos a implementar el módulo \texttt{numero\_invertido}. Este módulo tiene por objetivo invertir las cifras de determinado número. Recibe como parámetro el número \texttt{n}. Se asume que este parámetro \texttt{n} es mayor o igual a cero. El módulo retorna un número que contiene las mismas cifras de \texttt{n} pero en orden inverso. Por ejemplo, si se recibe el número 123, retornará el número 321.

Para implementar este módulo, utilizaremos una estructura algorítmica iterativa con entrada controlada. La cual procedemos a explicar paso a paso.

Control de flujo

El control de flujo para el módulo \texttt{invierte\_numero} se basa en la división sucesiva entre 10. El control de flujo busca repetir el conjunto de instrucciones, tantas veces como cifras existan en el número. Por tal motivo, se utiliza el mismo parámetro \texttt{n} como variable de control de flujo. No es necesario realizar ninguna inicialización puesto que el parámetro ya viene con valor asignado.

La condición de la iteración es \texttt{n>0}. Lo que significa que se repetirá la iteración mientras el número sea mayor que cero. Por lo que se asume que no hay más cifras para sacar del número cuando \texttt{n} tome el valor de cero.

¿Cómo actualizamos la variable de control? Pues, como es habitual, lo hacemos al final del ciclo iterativo. A \texttt{n} le debemos quitar una crifra. La forma más sencillo de hacerlo es dividiéndolo entre 10. Dado que PSeInt no posee la operación de división entera, usamos la división real y al resultado le aplicamos la función \texttt{trunc}. La función \texttt{trunc} truncará el valor pasado como parámetro eliminando la parte decimal.

palíndromo versión 1 módulo invierte número paso 1
Control de flujo

Formando número invertido

Lo que sigue es formar el número invertido. Para eso utilizamos la variable \texttt{numero\_invertido}. En esta variable iremos formando el valor que retornaremos en este módulo.

Básicamente lo que se hace en cada iteración es:

  1. Obtener el dígito del número. Para obtener el dígito del número, el dígito que está más a la derecha, utilizamos el resto o módulo de la división entera entre 10. Como en cada iteración al número se le divide entre 10, en cada iteración se obtendrá una cifra diferente. Por ejemplo si \texttt{n} tuviera el valor de 123, al operar \texttt{123 mod 10} obtenemos como resultado \texttt{3}, que justamente es la cifra que está más a la derecha. Para la siguiente iteración, \texttt{n} tendrá el valor de 12, al operar \texttt{12 mod 10} obtenemos como resultado \texttt{2}, la cifra que está más a la derecha ahora. De esta manera vamos obteniendo todos las cifras del número. 
  2. Formar el número invertido. Una vez obtenida la cifra, vamos formando el número invertido. ¿Cómo hacemos esto? Multiplicando por 10 y sumándole el dígito obtenido. Al multiplicar por 10 estamos incrementando una potencia de 10 al número, lo que hace que todas las cifras se muevan a la izquierda, dando espacio para sumarle el dígito obtenido. Al inicio \texttt{numero\_invertido} se le inicializa con el valor de \texttt{0}. Si el número a procesar fuese el número \texttt{123}, la primera cifra a sacar sería \texttt{3}. \texttt{numero\_invertido} se multiplica por \texttt{10} y se le suma \texttt{3}. Al final queda con el valor de \texttt{3}. La siguiente cifra a sacar es \texttt{2}. \texttt{numero\_invertido} se multiplica por \texttt{10} lo que resulta en el valor de \texttt{30}, a este resultado le sumamos \texttt{2} quedando \texttt{numero\_invertido} con el valor de \texttt{32}. La última cifra a sacar es es \texttt{1}. \texttt{numero\_invertido} se multiplica por \texttt{10} lo que resulta en el valor de \texttt{320}, a este resultado le sumamos \texttt{1} quedando \texttt{numero\_invertido} con el valor de \texttt{321}. De esta manera formamos el número invertido.
palíndromo versión 1 módulo invierte número paso 2
Formando número invertido

Módulo palíndromo: versión alternativa

Veremos ahora una versión alternativa. ¿Cómo podremos verificar si el número es palíndromo sin invertir las cifras del número? Pues comparando pares de cifra. En esta versión lo que haremos será sacar la cifra que está más a la izquierda, luego sacar la cifra que está más a la derecha y compararlas, si son iguales, continuaremos comparando los dos siguientes pares de cifras. Para que el número sea capicúa, todos los pares de cifras deben ser todos iguales. 

Control de flujo

Al igual que en el caso anterior, la solución es iterativa. Como compararemos pares de cifras, entonces la cantidad de iteraciones que realizaremos se reduce a la mitad que en el caso anterior. Para calcular la cantidad de dígitos usamos el módulo \texttt{cuenta\_digitos}. No nos preocupamos por como implementar este módulo, luego lo analizaremos.

Para el control de flujo, usaremos como variable de control\texttt{i} la cual la inicializamos con el valor de 1. La condición de iteración es \texttt{i<=mitad}, siendo \texttt{mitad} la mitad de dígitos que contiene el número. En el caso de la variable \texttt{mitad}, al momento de hacer la división, tomamos la parte entera. Al final de la iteración, actualizamos la variable de control incrementándola en 1.

palíndromo versión 2 módulo es palíndromo paso 1
Control de flujo

Gestionando el factor

Ya vimos en la versión anterior que para sacar el dígito que está más a la derecha, basta con dividir sucesivamente entre 10. Pero, ¿cómo hacemos para sacar el dígito que está más a la izquierda? Para esto se requerirá de un factor. Este factor permitirá obtener el dígito que está más a la izquierda. Usaremos la variable \texttt{factor} y la inicializamos con 10 elevado a la cantidad de dígitos del número menos 1.

Por ejemplo si el número en cuestión fuera  \texttt{123}, la cantidad de dígitos es 3, por lo que el factor será 10^2, es decir 100. De esta manera es muy simple obtener el dígito que está más a la izquierda, basta dividir el número entre el factor. El cociente de la división entera, será el dígito que está más a la izquierda. 123 dividido entre 100 retorna 1, justamente el dígito buscado.

La gestión del factor supone su inicialización así como su actualización para la extracción del siguiente dígito. Ya vimos su inicialización, pero, ¿cómo lo actualizamos? Dado que en cada iteración se retiran dos pares de dígitos, el factor se debe dividir entre 100.

Por su lado, el numero \texttt{n} también debe ser actualizado. Esta actualización posee dos fases, primero lo actualizamos con el resto del número entre factor, con esto eliminamos el dígito más a la izquierda. Luego, hacemos una división entera entre 10. Con esto eliminamos el dígito que está más a la derecha.

palíndromo versión 2 módulo es palíndromo paso 2
Gestionando el factor

Comparación de dígitos

Ya se ha realizado lo más complicado de esta versión: el control de flujo y la gestión del factor. Ahora procederemos a comparar los pares de dígitos. Este paso es relativamente simple, el dígito de la derecha se obtiene por medio del resto del número entre 10. El dígito que está más a la izquierda se obtiene del cociente entero de la división del número entre 10.

Con los dos dígitos obtenidos, el siguiente paso es compararlos. ¿Qué hacemos si son diferentes? Pues si son diferentes, lo que hacemos es actualizar una variable, comúnmente llamada de bandera o flag, que permita determinar si el número es palíndromo o no. La variable que hemos usado se ha identificado con el nombre de \texttt{verifica\_palindromo}. La hemos inicializado con el valor de \texttt{Verdadero}. La lógica a usar es la siguiente: asumimos que el número es palíndromo y si encontramos un par de dígitos diferentes, actualizamos esta variable con el valor de \texttt{Falso}.

palíndromo versión 2 módulo es palíndromo paso 3
Comparación de dígitos

Incluyendo bandera en el control de flujo

Podemos optimizar aún más el algoritmo, por lo que podemos usar una bandera para acortar el ciclo iterativo. Esto pues no tiene sentido seguir iterando si es que ya hemos encontrado un par de dígitos diferentes. Para este fin usamos la bandera \texttt{termino} la cual la hemos inicializado con el valor de \texttt{Falso}. Esta bandera indicará si debemos terminar de iterar. Cuando tenga el valor de \texttt{Verdadero} deberemos de terminar la iteración, independiente del valor de \texttt{i}. Para ello actualizamos la condición de la iteración por \texttt{i<=mitad y no termino}.

palíndromo versión 2 módulo es palíndromo paso 4
Incluyendo bandera en el control de flujo

Módulo cantidad de dígitos

Para encontrar la cantidad de dígitos usamos el módulo \texttt{cuenta\_digitos}. En el artículo «Cantidad de dígitos de un número en PSeInt» explicamos al detalles varias alternativas para contar la cantidad de dígitos de un número, explicando cada una de ellas como es de costumbre. En esta oportunidad, hemos usado una de las versiones, empleando logaritmos.

palíndromo versión 2 cantidad de dígitos
Módulo cantidad de dígitos

Versión recursiva

Finalmente procederemos a implementar una versión recursiva la cual se basa en la versión anterior.

Módulo palíndromo

La versión recursiva la implementamos mediante dos módulos, uno que realiza la llamada recursiva y el otro es la recursión en si. El módulo \texttt{es\_palindromo} básicamente lo que hace es inicializar la variable \texttt{factor} pues la utilizamos al momento de realizar la invocación a la recursión.

palíndromo versión 3 módulo es palíndromo
Módulo palíndromo

Modúlo recursivo

La versión recursiva es muy similar a la versión anterior, pero con algunas claras diferencias:

  1.  El caso base se da cuando el número pasado como parámetro tiene un solo dígito. En este caso se retorna \texttt{Verdadero}.
  2. Si los pares de dígitos son diferentes, se retorna \texttt{Falso}.
  3. Si los pares de dígitos son iguales, se actualiza \texttt{n} y el  \texttt{factor} y se invoca recursivamente al módulo.
palíndromo versión 3 módulo recursivo
Modúlo recursivo

Conclusión

Hemos presentado en este artículo, 3 propuestas de solución al problema de verificación si un número es palíndromo o capicúa en PSeInt. Se ha utilizado para el diseño algorítmico la técnica del diseño descendente y se ha controlado  el flujo en los módulos usando estructuras selectivas e iterativas. Podrá descargar la solución propuesta en el repositorio GitHub de iterando++ a través del siguiente enlace

Hemos preparado otros artículos adicionales en donde describimos al detalle la implementación de este problema en lenguajes de programación. Te invitamos a leer los siguientes artículos de iterando++

Si te interesa profundizar más sobre diseño algorítmico, te recomendamos el libro Foundations of Programming Languages de Kent D. D. Lee. En este libro encontrarás además información detallada sobre la programación orientada a objetos, funcional y lógica.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *