Vamos a programar #40 - Números palindrómicos (ver C#)

Hola de nuevo a todos el día de hoy vamos a tratar de probar otra conjetura usando programación para esto.


Hace poco mientras charlaba con un amigo, por alguna razón empezamos a hablar sobre palíndromos. Para el que no lo sabe, un palíndromo es lo siguiente:

Un palíndromo (del griego palin dromein, volver a ir atrás), también llamado palindromo, palíndroma o palindroma, es una palabra, número o frase que se lee igual adelante que atrás. Si se trata de un numeral, usualmente en notación indoarábiga, se llama capicúa. Habitualmente, las frases palindrómicas se resienten en su significado cuanto más largas son. *Wikipedia/palíndromos*
 En resumidas cuentas, es una frase que se puede leer tanto de izquierda a derecha, cómo de derecha a izquierda.

Adivina ya te opina, ya ni miles origina, ya ni cetro me domina, ya ni monarcas, a repaso ni mulato carreta, caso nicotina, ya ni cita vecino, anima cocina, pedazo gallina, cedazo terso nos retoza de canilla goza, de pánico camina, ónice vaticina, ya ni tocino saca, a terracota luminosa pera, sacra nómina y ánimo de mortecina, ya ni giros elimina, ya ni poeta, ya ni vida. (de Ricardo Ochoa)
Hay que ser bastante creativos para lograr crear una oracion de mas de cinco palabras y que está tenga sentido.

Seguro te preguntarás, y eso que tiene que ver con la imagen de arriba? Mucho, pues al igual que las palabras crean palíndromos, los número son capaces de hacer lo mismo. hay algunos números que se pueden leer al derecho y al revés. Pero no solo eso, además existe una conjetura en la cual se dice que si se siguen ciertas reglas, es posible obtener un número palindrómico.
La conjetura es la siguiente:
"Tomese cualquier número entero postivo, a este hay que sumarle un número que será el mismo pero en orden inverso y se prosigue hasta conseguir el número palíndromo"
De acuerdo a la conjetura anterior, siguiendo ese método, deberíamos de ser capaces de obtener un número palíndromo a partir de cualquiera. Entonce el trabajo del día de hoy, consiste en crear una aplicación que haga los cálculos y no diga si un numero cumple la conjetura o no.

Supongamos que tenemos el numero 281, tendríamos lo siguiente:

  • 281 + 182 = 463
  • 463 + 364 = 827
  • 827 + 728 = 1555
  • 1555 + 5551 = 7106
  • 7106 + 6017 = 13123
  • 13123 + 32131 = 45254 Se cumple!!!
Con eso tenemos que al aplicar la conjetura al número 281, este la cumple en 6 pasos.

El Código

El código en c# que prueba la conjetura de los números palindrómicos es el siguiente.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Numerics;

namespace NumerosPalindromicos
{
	public partial class FrmMain : Form
	{
		private bool IsPalindrome(string Number)
		{
			if (Number.ToString() == ReverseNumber(Number.ToString()))
				return true;
			else
				return false;

		}
		private string ReverseNumber(string NumberIn)
		{
			char[] charArray = NumberIn.ToCharArray();
			Array.Reverse(charArray);
			return new string(charArray);
		}

		private void GetNumber(string Number1, decimal MaxIterations)
		{
			int Iterator = 1;
			if (IsPalindrome(Number1) == true)
				LBResults.Items.Add("0 iteraciones "+ Number1 +" cumple la conjetura");
			else
			{
				BigInteger Result;
				BigInteger.TryParse(Number1,out Result);
				while (IsPalindrome(Result.ToString()) == false)
				{
					Result += BigInteger.Parse(ReverseNumber(Result.ToString()));
					LBResults.Items.Add(Iterator + " iteraciones "+ Result);
					if (Iterator >= MaxIterations)
					{
						break;
					}
					Iterator += 1;
				}

				if (IsPalindrome(Result.ToString()) == true)
					LBResults.Items.Add("La conjetura se cumple");
				else
					LBResults.Items.Add("La conjetura no se cumple.");
			}

		}
		public FrmMain()
		{
			InitializeComponent();
		}
		private void BtnDo_Click(object sender, EventArgs e)
		{
			LBResults.Items.Clear();
			GetNumber(TxtNumberIn.Text, NUDIterator.Value);
		}
	}
}

El código anterior consta de tres funciones, la primera de ellas (en orden de aparición) es "IsPalindrome". Está función del tipo "boolean" y recibe un parámetro del tipo "string"; se encarga de comprobar si el parámetro que se ingresa cumple con la condición que sea un palíndromo, para eso, simplemente invierte el orden de los número del parámetro de entrada usando la función "ReverseNumber".
La funcion "ReverseNumber, al igual que la funcion "IsPalindrome", recibe un parametro del tipo "string", este lo convierte en una matriz del tipo "char" y luego coloca el primer elemento al final y viceversa, con esto obtenemos el parametro de entrada invertido. La funcion regresa un valor del tipo "string".
Finalmente la función "GetNumber", es la que se encarga de hacer los cálculos. Esta función, recibe dos parámetros, el primero del tipo "string" que es la representación del número al cual queremos comprobar la conjetura. El segundo parámetro, es un valor del tipo "decimal" que se usará para determinar cuantas ciclos deben de hacerse antes de que se diga que la conjetura no se cumple.
En la función, lo primero que hacemos, es comprobar si el número no es ya un palíndromo, si lo es solamente agregamos en la lista de resultados que el número ya es palíndromo y que no se hizo ninguna iteración.
Si no es el caso, creamos una variable del tipo "BigInteger" en la que almacenaremos el resultado de la suma.
Luego creamos el bucle principal, la condición para que este siga activo, es que al llamar a la función "IsPalindrome" esta devuelva false.  Luego a la variable "Result" le sumará el resultado de la función "ReverseNumber", luego agregará el resultado a la lista de resultados  y después comprobará que la iteración actual, este dentro de los limites establecidos en el parámetro "MaxIterations"; si no es así, el bucle se interrumpirá y terminará la prueba de la conjetura declarando que no se cumple en el limite establecido (pero eso no significa que no tenga solución); en caso contrario, se incrementará el valor de la variable "Iterator" en uno y el bucle volvería al inicio.

Con el código anterior, podemos probar que el número 28,121,993 no cumple la conjetura, o no dentro de las primeras mil iteraciones (tampoco en 10,000).
Al código anterior, al igual que a varios de los otros proyectos, le faltan algunas optimizaciones (correrlo en un thread diferente para no bloquear la interfaz principal), pero por ahora sirve para dejar la idea en claro, cómo siempre, el código completo lo puedes descargar de mi dropbox para revisarlo.

Por ahora es todo, los leo luego.

No hay comentarios.