Vamos a programar #57 - Los números de Munchhausen (ver. Java android)
Hola de nuevo a todos, el día de hoy vamos a ver cómo probar los números de Munchhausen en java para usarse en dispositivos con android.El código.
Cómo ya vimos cuales son las reglas de los números de Munchhausen en el primer post, ahora pasaremos directamente al código en java para poder usarlo. El código es el siguiente:
package com.mdev.munchhausen;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends Activity {
Button BtnDowork;
TextView TXTMin, TxtMax;
CheckBox CHKShowAll;
ListView ShowResults;
private ProgressDialog progress;
private boolean IsMunchhausenNumber(String Number)
{
int Value = 0;
int CurrentNumber = 0;
char[] Digits = Number.toCharArray();
for (int i = 0; i < Digits.length; i++)
{
CurrentNumber = Digits[i] - 48;
Value += (int)Math.pow(CurrentNumber,CurrentNumber);
}
String CurrentVal = String.valueOf(Value);
if (Number.compareTo(CurrentVal) == 0)
return true;
else
return false;
}
private ArrayList TestNumbers(int BeginNumber, int EndNumber, int ShowAll)
{
ArrayList TempList = new ArrayList();
for (int i = BeginNumber; i <= EndNumber; i++)
{
if (IsMunchhausenNumber(String.valueOf(i)))
TempList.add( "La conjetura se cumple para el número " + i);
else if (ShowAll == 1)
TempList.add( "El número " + i + " no cumple la conjetura");;
}
return TempList;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BtnDowork = (Button)findViewById(R.id.BtnDoWork);
TXTMin = (TextView)findViewById(R.id.TXTInMin);
TxtMax = (TextView)findViewById(R.id.TXTInMax);
CHKShowAll = (CheckBox)findViewById(R.id.CHKShowAll);
ShowResults = (ListView) findViewById(R.id.LVResults);
BtnDowork.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Integer ShowAll = 0;
Integer Min = Integer.valueOf(TXTMin.getText().toString());
Integer Max = Integer.valueOf(TxtMax.getText().toString());
if (CHKShowAll.isChecked())
ShowAll = 1;
else
ShowAll = 0;
new UpdateList().execute(Min,Max,ShowAll);
}
}
);
}
private class UpdateList extends AsyncTask<Integer,Void,ArrayList>
{
@Override
protected void onPreExecute()
{
progress = ProgressDialog.show(MainActivity.this, "Espera...", "Espera...!!!");
}
@Override
protected ArrayList doInBackground(Integer... Limits)
{
ArrayList Lista = new ArrayList();
Lista = TestNumbers(Limits[0],Limits[1],Limits[2]);
return Lista;
}
@Override
protected void onPostExecute(ArrayList result)
{
super.onPostExecute(result);
final ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,android.R.layout.simple_list_item_1, result);
ShowResults.setAdapter(adapter);
progress.dismiss();
}
}
}
El código ha cambiado un poco, en el caso de la función "IsMunchhuasenNumber()", todo se mantiene igual, es decir; se prueba un número y si este cumple la conjetura, la funcion devuelve "true", en caso contrario se devuelve "false".
La función "TestNumbers", es la que sufrido varios cambios. Para empezar, los parámetros que está recibe, los primeros dos se mantienen del tipo "int", pero el tercer parámetro pasa a ser del tipo "boolean" al tipo "int", esto solo hace por practicidad, un poquito más adelante veremos el por qué. Otro de los cambios que sufre, es que ahora pasa a ser una función en vez de un procedimiento. El valor que regresa es un valor del tipo "ArrayList", que es la lista en la cual se van almacenado los valores de salida. Cada vez que se prueba la conjetura para un número, se regresa una cadena de texto similar a "el número n no/cumple la conjetura", en la versión de C#, directamente se usaba el delegado y la función "UpdateList()" para hacerlo pero en este y debido a cómo está estructurado, pensé que era mejor hacerlo así.
A diferencia de los muchos otros códigos que he dicho que voy a "optimizar" (y que no he hecho), este ahora si usa un "Thread" diferente para hacer los cálculos y que no se bloquee la interfaz principal, para eso hacemos uso de la Subclase "UpdateList" que hereda de la clase "AsyncTask" (no se si sea en valido decir "hereda" en java, pero creo que si o si no se entiende). En el post de la semana que viene, veremos cómo usar esta clase para poder brindar un poco de "Multithreading", pero por ahora, al crear la instancia, pasamos tres parámetros que son "<Integer, Void, ArrayList>". Para poder usar la clase "AsyncTask", debemos de sobrecargar algunos de los metodos que la componen, en este caso solo son tres (pero hay más) y son: "onPreExecute()", "doInBackground()" y "onPostExecute()". Respectivamente cada uno hace lo siguiente: Es lo que se ejecutará antes de empezar, la parte principal y que mas tiempo va a consumir y la parte donde se procesaran los resultados.
Con el código anterior podemos probar los números de Munchhausen en un dispositivo con android, en el siguiente post veremos cómo es que funciona la clase "AsyncTask" y cómo nos podra ayudar con tareas en segundo plano. El código cómo de costumbre lo pongo en mi dropbox para que lo descargues, recuerda que a partir de este post, solo ira el código del layout principal y el código java. El APK ya compilado lo puedes descargar de mi dropbox directamente o puedes visitar la seccion de descargas del blog.
Y bien, por ahora es todo, los leo luego.
Vamos a programar #56 - Los números de Munchhausen (ver. Javascript)
Hola de nuevo a todos, el día de hoy vamos a continuar con la prueba de la conjetura de los números de Munchhausen.En el post anterior vimos cuales son las reglas, por lo que ahora pasaremos directamente al código javscript para ver las diferencias entre la versión de C# y esta.
El código.
El código en javascript para probar los números de Munchhausen es el siguiente:
<html>
<head>
<style type="text/css">
.h1M
{
font-size: 16px;
}
.formVigenere{
font: 95% Arial, Helvetica, sans-serif;
max-width: 400px;
margin: 10px auto;
padding: 16px;
background: #F9F9F9;
}
.textareaM
{
width: 100%;
height: 150px;
padding: 2px 5px;
box-sizing: border-box;
border: 2px solid #999;
border-radius: 4px;
resize: none;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
}
.textareaM:focus
{
width: 100%;
height: 150px;
padding: 2px 5px;
box-sizing: border-box;
border: 2px solid #00BB00;
border-radius: 4px;
resize: none;
}
.TextM
{
width: 100%;
box-sizing: border-box;
border: 2px solid #999;
border-radius: 4px;
}
.ButtonM
{
width: 100%;
background-color: #009900;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
}
.ButtonM:hover
{
width: 100%;
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
}
</style>
<script type="text/javascript">
function NumberToDigits(Number){
var Out = [];
for(var i = 0; i < Number.length; i++){
var CodeChar = Number.charCodeAt(i);
Out.push(CodeChar - 48);
}
return Out;
}
function IsMunchhausen(Number){
var Result = 0;
var Digits = NumberToDigits(Number);
for(var i = 0; i < Digits.length; i++){
Result += Math.pow(Digits[i], Digits[i]);
}
if (Number == Result.toString()){
return true;
}
else{
return false;
}
}
function TestNumbers(){
document.getElementById('Result').value = "";
BeginNumber = document.getElementById('MinNumber').value;
EndNumber = document.getElementById('MaxNumber').value;
SHowAll = document.getElementById('ShowAll').checked;
for (var i = BeginNumber; i <= EndNumber; i++){
if (IsMunchhausen(i.toString()))
document.getElementById('Result').value += "La conjetura se cumple para el número " + i + "\n";
else if (SHowAll)
document.getElementById('Result').value += "El número " + i + " no cumple la conjetura\n";
}
}
</script>
</head>
<body>
Utilidad para probar la conjetura de Munchhausen usando javascript.
<form class="formVigenere">
<span class="h1M">Numero de donde empezar:</span>
<br />
<input class="TextM" id="MinNumber" value = "1" type="text"></input><br />
<span class="h1M">Numero hasta donde llegar</span><br /><br/>
<input class="TextM" id="MaxNumber" value = "5000" type="text" /><br />
<br />
<input class="ButtonM" id="Calcula" onclick="TestNumbers()" type="button" value="Calcular" /><br />
<br />
<input type="checkbox" id = "ShowAll" value="Bike">Mostrar Todo<br><br>
<span class="h1M">Resultado</span><br/>
<textarea class="textareaM" id="Result" rows="5"></textarea><br/><br/>
</form>
</body>
<html>
El código anterior solo consta de tres funcione en esta ocasión en la función "NumberToDigits()" al convertir el número de entrada a los dígitos que lo forman, directamente hace la resta de 48 para poder usar el número directamente. Para poder recuperar los valores de cada control, hacemos uso de la función "document.getElementById".
Cómo de costumbre, el código lo dejo en mi dropbox para que lo pruebes, al ser el mismo "concepto" que la versión de C#, no requiere una explicación mayor. La semana que viene, veremos la versión para android.
Los leo luego.
Vamos a programar #55 - Los números de Munchhausen (ver. C#)
Hola de nuevo a todos, el día de hoy vamos a ver los números de Munchhausen y cómo probar la conjetura usando código en C#.Antes que nada, veamos la definicion de los número de Munchhausen segun wikipedia:
El término fue acuñado por el ingeniero de software y matemático holandés Daan van Berkel en 2009. El nombre se debe a que cada dígito está "elevado" por sí mismo, esto evoca la historia de Barón Munchausen que se elevó a sí mismo hacia arriba jalando su propia coleta. Los números narcisistas siguen una regla similar, pero en el caso de los números narcisistas la potencia de los dígitos es fija, siendo elevados a la potencia del número de dígitos en el número.En resumidas cuentas, se trata de tomar un número y separar cada dígito y este a su vez elevarlo a la potencia que será el mismo dígito. Antes de continuar, actualmente solo hay dos números conocidos que cumplen la conjetura. uno de ellos es el número 1 puesto que:
- 1 = 1^1 = 1.
- 3435 = 3^3 + 4^4 + 3^3 + 5^5 = 27 + 256 + 27 + 3125 = 3435.
El código.
El código en C# que sirve para probar la conjetura 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.Threading;
namespace Munchhausen
{
public partial class FrmMain : Form
{
private bool IsBusy = false;
private delegate void UpdateListDelegate(string Value);
private void UpdateList(string Value)
{
if (LBResults.InvokeRequired)
LBResults.Invoke(new UpdateListDelegate(UpdateList), Value);
else
LBResults.Items.Add(Value);
}
private bool IsMunchhausenNumber(string Number)
{
int Value = 0;
int CurrentNumber = 0;
char[] Digits = Number.ToCharArray();
for (int i = 0; i < Digits.Length; i++)
{
CurrentNumber = Digits[i] - 48;
Value += (int)Math.Pow(CurrentNumber,CurrentNumber);
}
if (Number == Value.ToString())
return true;
else
return false;
}
private void TestNumbers(int BeginNumber, int EndNumber, bool SHowAll)
{
for (int i = BeginNumber; i <= EndNumber; i++)
{
if (IsMunchhausenNumber(i.ToString()))
UpdateList("La conjetura se cumple para el número " + i);
if (SHowAll)
UpdateList("El número " + i + " no cumple la conjetura");
}
IsBusy = false;
}
private void RunWork(int Minimum, int Maximun, bool ShowAll = false)
{
Thread DoWork = new Thread(new ThreadStart(() => TestNumbers(Minimum, Maximun,ShowAll)));
IsBusy = true;
DoWork.Start();
}
public FrmMain()
{
InitializeComponent();
}
private void BtnStart_Click(object sender, EventArgs e)
{
LBResults.Items.Clear();
if (!IsBusy)
RunWork(int.Parse(TxtMinNumber.Text), int.Parse(TxtMaxNumber.Text),CHKShowTrue.Checked);
else
MessageBox.Show("Hay una operación en proceso, espera","MDev",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
}
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (IsBusy == true)
{
MessageBox.Show("No se puede salir ahora","MDev", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
e.Cancel = true;
}
}
}
}
El código anterior consta de cuatro funciones, pero solo la función "IsMunchhausenNumber()" es la que hace el trabajo, el resto solo son para poder usar la aplicación y que esta no se bloquee cuando se realice el proceso.
La función "IsMunchhausenNumber" recibe un parámetro del tipo "string" que será la cadena de texto que representa el número que se va a probar; decidí tomar directamente el parámetro cómo un "string" debido a que cuando recuperamos el número de la caja de texto, este sera de ese tipo, entonces convertirlo y luego hacer una conversión más para poder separarlo en los dígitos, significa doble trabajo.
Dentro de la función, convertimos el parámetro ingresado en un "array" del tipo "char", cada elemento representara un dígito del número ingresado. Luego para poder hacer los cálculos con cada dígito, a cada valor del tipo "char" le restamos 48 para obtener su valor real. Hay que recordar que el tipo "char" es esencialmente igual al tipo "byte" por lo que podemos restar (aunque habría que hacer la conversión implícita pero meh). La razón por la que se resta 48, es porque el número cero, esta en el lugar 48, el uno es 49 y así sucesivamente hasta el número nueve. Si intentamos convertir el valor del tipo "char" "0" a uno del tipo "int", este regresará 48, por lo que hacer la resta directamente resulta más fácil.
Después con los numero ya separados se hace la suma siguiendo las reglas de la conjetura y se compara el valor de la variable usada para hacer la suma con el número ingresado cómo parámetro; si estos son iguales entonces la función devuelve un valor del tipo "bool" "true", en caso contrario devuelve "false".
Para probar los número, se hace uso de la función "TestNumbers". Esta función recibe tres parámetros, el primero del tipo "int" que servirá cómo limite mínimo para empezar a probar los números. El segundo parámetro también del tipo "int" sirve para marcar el limite máximo hasta cual se van a probar los números, finalmente el tercer parámetro del tipo "bool", servirá par filtrar los resultados; solo cuando este sea "true", todos los resultados sin importar que cumplan la conjetura, se agregan a la lista de salida, en caso contrario, solo los que la cumplen son agregados.
Y bien, por ahora es todo en futuros post veremos que hacen el resto de las funciones (que de seguro habrás notado que aparecen en varios de los programas del blog) y probablemente al igual que algunos otros de los programas, crearemos versiones para android en java y web en javascript. Cómo de costumbre, puedes descargar el código fuente de mi dropbox para que lo pruebes.
Los leo luego
Suscribirse a:
Entradas
(
Atom
)







No hay comentarios. :
Publicar un comentario