Tuesday, March 28, 2006

Spam Filter

Primero decidi hacer un estilo de plugin para algun cliente de email, especificamente thunderbird.
Pero despues decidi hacer un programa estilo cliente servidor, este se pondra en el medio del cliente mail. De esta manera el cliente puede recibir cualquier mail, filtrar, y despues servir como
servidor para que cualquier cliente que soporte SMTP (...) lo pueda accesar. La implementacion
dependera directamente de escuchar el puerto SMTP (25). De esta manera, teoricamente,
se puede apuntar el cliente de email al localhost y recibir mail (previamente configurado el spam
filter). El mail que se manda se hace de manera direca al servidor de POP3.

Thursday, March 23, 2006

Parcial Laboratorio

1-)

int Length(char *Palabra)
{
int i = 0;
while(Palabra[i] != '\0')
i++;
return ++i;
}

2-)

int SubString(char *Palabra,char *Cadena)
{
int index = -1;
int Valor1 = Length(Palabra);
int Valor2 = Length(Cadena);
if(Valor2>Valor1)
return -1;
int i = 0;
for(i = 0; i < (Valor1);i++)
if(Palabra[i] == Cadena[0])
{
int valido = CheckString(Palabra[i],Cadena,Valor1 - i,Valor2);
if(valido > 1)
return i;
}
return -1;
}

int CheckString(char *Palabra,char *string, int Valor1,int Valor2)
{
if(Valor2>Valor1)
return -1;
int i = 0;
for(i = 0; i < Valor2;i++)
if(Palabra[i] != string[i])
return -1;
return 1;
}

3-)
void Encryptar()
{
char Palabra[255];
scanf("%s",&Palabra); //%s no esta en string.h
int i = 0;
while(Palabra[i] != '\0')
{
Palabra[i] += 5;
printf("%c",Palabra[i]);
i++;
}
}

4-)

int Operacion()
{
char a,b,c;
scanf("%c%c%c",&a,&b,&c);
int x = a - '0';
int y = c - '0';
switch(b)
{
case '+':return x+y;break;
case '-':return x-y;break;
case 'x':return x*y;break;
case '/':return x/y;break;
}
}

Albert:
1) En el primer caso, assigna al valor de ptr1 la hubicacion de memoria de ptr2
2) En este caso assigna la referencia de 'p' al valor de 'c'. Que es el valor de la letra
'A'.

Tuesday, February 21, 2006

Convertidor Decimal

Convertidor Decimal - Binario

#include <stdlib.h>

#include <iostream>



using namespace std;

int main()

{

cout << "Convertidor de Decimal A binario\nEntre el numero que desea convertir:\n";

int numero,i;

int binario[33];

for(i = 0; i<33;i++)

binario[i] = 0;

cin >> numero;

for(i = 0 ; numero != 0; i++)

{

binario[i] = numero % 2;

numero = numero /2;

}

for(int j = i -1; j >=0 ;j--)

{

cout<<binario[j];

}

cout<<endl;

system("PAUSE");

}



Convertidor Decimal - Octal



#include <stdlib.h>

#include <iostream>



using namespace std;

int main()

{

cout << "Convertidor de Decimal A Octal\nEntre el numero que desea convertir:\n";

int numero,i;

int binario[33];

for(i = 0; i<33;i++)

binario[i] = 0;

cin >> numero;

for(i = 0 ; numero != 0; i++)

{

binario[i] = numero % 8;

numero = numero /8;

}

for(int j = i -1; j >=0 ;j--)

{

cout<<binario[j];

}

cout<<endl;

system("PAUSE");

}





Convertidor Decimal - Hexadecimal



#include <stdlib.h>

#include <iostream>



using namespace std;

int main()

{

cout << "Convertidor de Decimal A Hexadecimal\nEntre el numero que desea convertir:\n";

int numero,i;

int binario[33];

for(i = 0; i<33;i++)

binario[i] = 0;

cin >> numero;

for(i = 0 ; numero != 0; i++)

{

binario[i] = numero % 16;

numero = numero /16;

}

for(int j = i -1; j >=0 ;j--)

{

switch (binario[j])

{

case 10: cout<<"A";break;

case 11: cout<<"B";break;

case 12: cout<<"C";break;

case 13: cout<<"D";break;

case 14: cout<<"E";break;

case 15: cout<<"F";break;

default: cout<<binario[j];break;

}

}

cout<<endl;

system("PAUSE");

}



Convertidor Decimal – Romano (3 digitos)





#include <stdlib.h>

#include <iostream>



using namespace std;



int main()

{



string PrimerDigito[] = {"","i","ii","iii","iv","v","vi","vii","viii","ix"};

string SegundoDigito[] = {"","x","xx","xxx","xl","l","lx","lxx","lxxx","xc"};

string TercerDigito[] = {"","c","cc","ccc","cd","d","dc","dcc","dccc","cm"};

string CuartoDigito[] = {"","m","mm","mmm","IV","V","VI","VII","VIII","IX"};

string QuintoDigito[] = {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};

string SextoDigito[] = {"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};

string SeptimoDigito[] = {"","M","MM","MMM"};



int Numero = -1;



cout<<"Convertidor de Decimal A Romano (7 digitos)\nEntre el numero que desea convertir:\n";

cin >> Numero;

while(Numero < 0 || Numero >= 4000000)

{

cout<<"Ese Numero es Invalido, por favor inserte un numero entre 0 y 4,000,000:\n";

cin >> Numero;

}



int Digitos[7];

Digitos[0] = Numero / 1000000; Numero = Numero % 1000000;

Digitos[1] = Numero / 100000; Numero = Numero % 100000;

Digitos[2] = Numero / 10000; Numero = Numero % 10000;

Digitos[3] = Numero / 1000; Numero = Numero % 1000;

Digitos[4] = Numero / 100; Numero = Numero % 100;

Digitos[5] = Numero / 10; Numero = Numero % 10;

Digitos[6] = Numero;





cout<<SeptimoDigito[Digitos[0]];

cout<<SextoDigito[Digitos[1]];

cout<<QuintoDigito[Digitos[2]];

cout<<CuartoDigito[Digitos[3]];

cout<<TercerDigito[Digitos[4]];

cout<<SegundoDigito[Digitos[5]];

cout<<PrimerDigito[Digitos[6]]<<endl;





/*for(int i = 0; i < 7;i++)

cout<<Digitos[i]<<endl;*/



system("PAUSE");

}









Monday, February 13, 2006

Numero Aleatorios

Numeros Aleatorios

Cuando una persona en un programa pide un numero aleatorio, de verdad esta pidiendo un numero arbitrario. Por su definición matemática, actualmente no existen números aleatorios. Un número aleatorio definido matemáticamente es que todos los números tienen la misma probabilidad de salir, para esto ser cierto, el número no puede estar en un rango finito. La definición va aun mas allá de las probabilidades que salga un número sea igual a todos los otros números. Se supone que si pedimos un número aleatorio, se pudiéramos echar el tiempo para atrás y dejar que pidamos el número una vez mas, el número pudriera y debería de ser diferente.

Método Lineal Congruencial:
For i = 2 to N
A[i] = (a[i-1]*b +1) mod m

Este método es muy utilizado, es fácil de implementar y siempre da un número por debajo de m-1. Es una ventaja muy grande para los programadores, podemos limitar el rango del número arbitrario que vamos a tener. Tan simple como se ve, esta es la ecuación para generar números arbitrarios mas estudiada. Cuando uno no desea una secuencia aleatoria sino un número arbitrario, se utiliza a como una variable global y no un arreglo. Se dice que funciona mejer bajo estas circunstancias:
1. m es un número grande, una potencia de 10 o de 2
2. n no es muy grande ni muy pequeño, un digito menos que m
3. El tercer digito de b es par, y termina en 21.

El problema más grande de los generadores de secuencias aleatorias, el algoritmo se agota eventualmente y comienza a repetir la secuencia. Esto se debe a las leyes de las matemáticas, un proceso matemático siempre va a repetir resaltados.

#include
#include

using namespace std;


const static int m = 100000000;
const static int m1 = 10000;
const static int b = 31415821;
int a;
int Mult(int p, int q)
{
int p1,p0,q1,q0;
p1 = p / m1; p0 = p % m1;
q1 = q / m1; q0 = q % m1;
return (((p0*q1+p1*q0) % m1)*m1+p0*q0) % m;
}

int random(int r)
{
a = (Mult(a,b) +1) % m;
return ((a / m1) * r) / m1;
}

int main(int argc, char *argv[])
{

int i,N,r;
cout<<"Cantidad de numeros?\n"; cin >> N;
cout<<"Seed\n"; cin >> a;
cout<<"Rango\n"; cin >> r;
for(i = 0;i
cout<<
system("PAUSE");
return 0;
}

Preguntas:
1. ¿Como simularías el tiro de dos dados, si ambos dados son irregulares y tienen los números 1, 2, 3, 5, 8 y 13?
2. Escriba un programa para producir imágenes de dos dimensiones aleatorios
3. Escriba un programa para que imprima 4 letras aleatorias
4. ¿Que formas tenemos para automatizar la lectura del “seed” (que es la base de la secuencia aleatoria)?
5. ¿Seria buena idea utilizar b = 3 en este algoritmo? ¿Por qué?

Numero Aleatorios

Numeros Aleatorios

Cuando una persona en un programa pide un numero aleatorio, de verdad esta pidiendo un numero arbitrario. Por su definición matemática, actualmente no existen números aleatorios. Un número aleatorio definido matemáticamente es que todos los números tienen la misma probabilidad de salir, para esto ser cierto, el número no puede estar en un rango finito. La definición va aun mas allá de las probabilidades que salga un número sea igual a todos los otros números. Se supone que si pedimos un número aleatorio, se pudiéramos echar el tiempo para atrás y dejar que pidamos el número una vez mas, el número pudriera y debería de ser diferente.

Método Lineal Congruencial:
For i = 2 to N
A[i] = (a[i-1]*b +1) mod m

Este método es muy utilizado, es fácil de implementar y siempre da un número por debajo de m-1. Es una ventaja muy grande para los programadores, podemos limitar el rango del número arbitrario que vamos a tener. Tan simple como se ve, esta es la ecuación para generar números arbitrarios mas estudiada. Cuando uno no desea una secuencia aleatoria sino un número arbitrario, se utiliza a como una variable global y no un arreglo. Se dice que funciona mejer bajo estas circunstancias:
1. m es un número grande, una potencia de 10 o de 2
2. n no es muy grande ni muy pequeño, un digito menos que m
3. El tercer digito de b es par, y termina en 21.

El problema más grande de los generadores de secuencias aleatorias, el algoritmo se agota eventualmente y comienza a repetir la secuencia. Esto se debe a las leyes de las matemáticas, un proceso matemático siempre va a repetir resaltados.

#include
#include

using namespace std;


const static int m = 100000000;
const static int m1 = 10000;
const static int b = 31415821;
int a;
int Mult(int p, int q)
{
int p1,p0,q1,q0;
p1 = p / m1; p0 = p % m1;
q1 = q / m1; q0 = q % m1;
return (((p0*q1+p1*q0) % m1)*m1+p0*q0) % m;
}

int random(int r)
{
a = (Mult(a,b) +1) % m;
return ((a / m1) * r) / m1;
}

int main(int argc, char *argv[])
{

int i,N,r;
cout<<"Cantidad de numeros?\n";
cin >> N;
cout<<"Seed\n";
cin >> a;
cout<<"Rango\n";
cin >> r;
for(i = 0;i cout< system("PAUSE");
return 0;
}

Preguntas:
1. ¿Como simularías el tiro de dos dados, si ambos dados son irregulares y tienen los números 1, 2, 3, 5, 8 y 13?
2. Escriba un programa para producir imágenes de dos dimensiones aleatorios
3. Escriba un programa para que imprima 4 letras aleatorias
4. ¿Que formas tenemos para automatizar la lectura del “seed” (que es la base de la secuencia aleatoria)?
5. ¿Seria buena idea utilizar b = 3 en este algoritmo? ¿Por qué?

Numeros Aleatorios

Numeros Aleatorios

Cuando una persona en un programa pide un numero aleatorio, de verdad esta pidiendo un numero arbitrario. Por su definición matemática, actualmente no existen números aleatorios. Un número aleatorio definido matemáticamente es que todos los números tienen la misma probabilidad de salir, para esto ser cierto, el número no puede estar en un rango finito. La definición va aun mas allá de las probabilidades que salga un número sea igual a todos los otros números. Se supone que si pedimos un número aleatorio, se pudiéramos echar el tiempo para atrás y dejar que pidamos el número una vez mas, el número pudriera y debería de ser diferente.

Método Lineal Congruencial:

For i = 2 to N

A[i] = (a[i-1]*b +1) mod m

Este método es muy utilizado, es fácil de implementar y siempre da un número por debajo de m-1. Es una ventaja muy grande para los programadores, podemos limitar el rango del número arbitrario que vamos a tener. Tan simple como se ve, esta es la ecuación para generar números arbitrarios mas estudiada. Cuando uno no desea una secuencia aleatoria sino un número arbitrario, se utiliza a como una variable global y no un arreglo. Se dice que funciona mejer bajo estas circunstancias:

1. m es un número grande, una potencia de 10 o de 2

2. n no es muy grande ni muy pequeño, un digito menos que m

3. El tercer digito de b es par, y termina en 21.

El problema más grande de los generadores de secuencias aleatorias, el algoritmo se agota eventualmente y comienza a repetir la secuencia. Esto se debe a las leyes de las matemáticas, un proceso matemático siempre va a repetir resaltados.

#include

#include

using namespace std;

const static int m = 100000000;

const static int m1 = 10000;

const static int b = 31415821;

int a;

int Mult(int p, int q)

{

int p1,p0,q1,q0;

p1 = p / m1; p0 = p % m1;

q1 = q / m1; q0 = q % m1;

return (((p0*q1+p1*q0) % m1)*m1+p0*q0) % m;

}

int random(int r)

{

a = (Mult(a,b) +1) % m;

return ((a / m1) * r) / m1;

}

int main(int argc, char *argv[])

{

int i,N,r;

cout<<"Cantidad de numeros?\n";

cin >> N;

cout<<"Seed\n";

cin >> a;

cout<<"Rango\n";

cin >> r;

for(i = 0;i

cout<

system("PAUSE");

return 0;

}

Preguntas:

1. ¿Como simularías el tiro de dos dados, si ambos dados son irregulares y tienen los números 1, 2, 3, 5, 8 y 13?

2. Escriba un programa para producir imágenes de dos dimensiones aleatorios

3. Escriba un programa para que imprima 4 letras aleatorias

4. ¿Que formas tenemos para automatizar la lectura del “seed” (que es la base de la secuencia aleatoria)?

5. ¿Seria buena idea utilizar b = 3 en este algoritmo? ¿Por qué?

Saturday, February 11, 2006

Eliminación Gaussiana

Es un método para resolver sistemas de ecuaciones que consta en hacer un triangulo de 0 debajo de la diagonal de la matriz. Esto se hace sumando, multiplicando, y moviendo las ecuaciones. Una vez se cumple se puede aplicar dos métodos para resolver la ecuación; Gauss-Jordan o Sustitución.

Los sistemas de ecuaciones se pueden representan de la siguiente forma:





Para facilitar el proceso de eliminación Gaussiana se re-escribe de la siguiente manera:





Si le aplicamos el proceso de eliminación Gaussiana al la matriz de arriba nos resultaría la siguiente matriz:








En el caso del algoritmo, no nos devuelve esta misma matriz, sino una equivalente. De este punto en adelante utiliza sustitución para resolver el sistema. El sistema también se puede hacer utilizando Gauss-Jordan, utilizando matrices inversas, y multiplicación de matrices.

Pero este método es el mas rápido, utilizando multiplicación (el segundo mas rapido) el tiempo tomado es aproximadamente n2.81….Este método tiene un tiempo promedio de n3/2,

Donde n es el tamaño de la matriz.


#include cstdlib

#include iostream

using namespace std;

int main(int argc, char *argv[])

{

//Declaracion de los enteros que voy a utilizar

int i,j,k,N,max;

//Este float se utiliza como una variable temporal para cambiar variables

float t;

//Pedir la entrada del tamaño de la matriz

cout<<"Que tan grande quieres la matriz?"<> N;

//se declara float porque las proximas sentencias aritmeticas pueden resultar en decimal

float Gauss[N][N+1];

//Esto pide N columnas de N + 1 numeros

cout<<"Porfavor entre la matriz:"<< k =" 0;k">> temp;

Gauss[j][k] = temp;

}

cout<<"Proxima Columna\n"; } /*los for anidados 2 y 3, son la rutina conocida como "Eliminate" esta rutina se asegura de subir el registro con el primer numero mas alto a la posicion 0 os For 1, 4 y 5 recore la matriz para crear ceros debajo de la diagonal de la matriz*/ /*1*/for(i = 0 ; i < max =" i;" j =" i+1;j"> abs((int)Gauss[max][i])){

max = j;

}

/*3*/for(k = i; k <=N;k++) { t = Gauss[i][k]; Gauss[i][k] = Gauss[max][k]; Gauss[max][k] =t; } /*4*/for(j = i+1;j <= N;j++) { /*5*/for(k = N; k >=i;k--)

{

Gauss[j][k] = Gauss[j][k] - Gauss[i][k] * Gauss[j][i] / Gauss[i][i];

}

}

}

}

/*Este Segmento de codigo es el proceso de sustitucion, funciona de abajo para arriba*/

int x[N];

for(int i = 0 ; i < j =" N">= 0;j--)

{

t = 0.0;

for(k = N-1 ; k >= 0 ; k--)

{

t= t + Gauss[j][k]*x[k]; //Crea una sumatoria de todas la varibales de la matriz multiplicado por las respuestas conocidas

}

x[j]= (Gauss[j][N] + t*-1)/Gauss[j][j]; //Se pasa al otro lado de la igualdad y se divide entre el numero correspondiente

}

/*Esto solo imprime la matriz y las N respuetas*/

for(i = 0; i < j =" 0;" cout=""><<<"Las respuestas X1,X2...Xn:"<<>


Preguntas Para responder:

  1. ¿Por qué se hace la matriz de [N][N+1]?
  2. ¿Cual utiliza más operaciones aritméticas, Gauss-Jordan o Sustitución?
  3. ¿Si cambiamos las columnas de la matriz, como afecta la respuesta?
  4. ¿Cómo podemos verificar por ecuaciones contradictorias o idénticas?
  5. ¿De que uso seria eliminación Gaussiana si tenemos una matriz de M ecuaciones y N desconocidos siendo N <>
  6. De un ejemplo de porque el proceso “Elimínate” , utilizando una computadora mítica, que sus números solo pueden ser de 2 dígitos significativos.
  7. ¿Cuanto tiempo tomaría Eliminación Gaussiana con una matriz N*N, cunado N vale 7?
  8. ¿Porque en el sistema de ecuación siguiente no funciona Eliminación Gaussiana?
    1. 5x+5y+5z = 5

3x+3y+3z = 3

x+y+z = 1

  1. ¿Por qué el cuarto y quinto ‘for’ están dentro del primero y el segundo pero no del tercero?
  2. ¿Porque la ecuación aritmética del quinto ‘for’ crea cero?

Monday, February 06, 2006

Comparacion de velocidad utilizando sizeof()

#include cstdlib
#include iostream
#include stdlib.h
#include time.h
#include stdio.h
#include sys\timeb.h
using namespace std;

timeb Antes, Despues;

static void Generar(int numero)
{
FILE *Archivo;
Archivo = fopen("C:\\Codigo.txt","w");
for(int i = 0 ; i < numero ; ++i)
fprintf(Archivo,"Numeros[%i] = 0;\n",i);
}

int main(int argc, char *argv[])
{
//Generar(500000);
//int Numeros[400000];
ftime(&Antes);
int MAX = 518800;
void *Numeros2;
Numeros2 = malloc(sizeof(int) * MAX);
memset(Numeros2,1,sizeof(int) * MAX);
ftime(&Despues);
//float differencia = (float(difftime(Despues.time,Antes.time))) + (float(abs(Despues.millitm - Antes.millitm))/1000);
float differencia = (float(difftime(Despues.time, Antes.time))) + (float(abs(Despues.millitm - Antes.millitm))/1000);
cout << Despues.millitm << " " << Antes.millitm << endl;
printf("Diferencia de tiempo: %.3f segundos.\n",differencia);
free(Numeros2);
system("PAUSE");
return EXIT_SUCCESS;
}

Una vez mas no pude comprar el arreglo inicializandolo 1 a 1. De esta manera propuesta nunca me dio una diferencia de tiempo cuando la computadora estaba idle. Me llego a dar differencia de .015 y .016 millisegundos, pero solo cuando cargaba la PC con mas tareas.

Me lo encuentro que raro que siempre son .015 y .016 millisegundos, no importa cual metodo utilize. Investigare sobre esta occurencia. Como quiera, la occurencia de differencia de tiempo pasa menos vecez con este metodo que con los anteriores.

Sunday, February 05, 2006

Tipos de Datos Fundamentales

Enteros

Cuando uno hace cualquier proceso aritmético con los Enteros tenemos que tener en mente que tipo de entero estamos utilizando. De esta manera podemos anticipar el error conocido como “Overflow”.

Rangos:

· Signed 8-bit -128 a 127

· Unsigned 8-bit 0 a 255

· Signed 16-bit -32,768 a 32,767

· Unsigned 16-bit 0 a 65,535

· Signed 32-bit -2,147,483,648 a 2,147,483,647

· Unsigned 32-bit 0 a 4,294,967,295

· Signed 64-bit -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807

· Unsigned 64-bit 0 a 18,446,744,073,709,551,615


Puntos-Flotantes

Esta estructura de datos son aquellos números que son decimales. Estos números son muy peligrosos si uno no sabe como se comportan porque pueden dar resultados erróneos. Esto es porque la PC no entiende decimal, sino que es una simulación.

Comportamiento:

· Divisiones inexactas se redondean a 7 o 15 dígitos

· Aritmética de puntos-flotantes de 32-bits, es propenso a error

· Evitar comparaciones con variables flotantes, es propenso a error

Strings & Caracteres

Strings y caracteres son tipos de datos utilizados para representar caracteres de un estándar, tipo ACII o Unicode. En otras palabras con este tipo de variable podemos poner texto legible en ves de números.

Buena Practica:

· Evitar caracteres mágicos

· Asegúrese del índice que usa de los “substrings” son los correctos

· Saber como el Lenguaje codifica los caracteres

· Tener en mente la diferencia entre punteros String arreglos de caracteres


Variables “Booleanas”

Es difícil mal usar una variable booleana en un programa. De otra manera se utilizan las variables booleanas de una manera que se hace más fácil de interpretar el código

Enumeraciones

Son usadas frecuentemente cuando uno sabe todos los valores posibles de una variable. Como los meses de un año, la cantidad de días en un mes, o los días en una semana.

Buenos usos:

· Permite Modificaciones fáciles

· Poner identificadores del primer y ultimo registro para iteraciones fáciles

· NO brincar valores si son asignados manualmente

Constantes

Una constante es una variable cuyo valor no cambia. Usando constantes es una buena forma de parametrizar un programa, de manera que si deseas cambiar algo solo tiene que modificar la constante. Ej:

· Interés

· Itebis

· Titulo del Programa

Arreglos

Los datos estructurados mas utilizados y los mas simples. Contienen una lista de variables del mismo tipo que son acezados por un índice. Un arreglo siempre esta en un espacio continúo en memoria.

Buena Practica:

· Asegurarse que el índice esta dentro de los limites del arreglo

· Utilice arreglos como datos secuénciales

· Utilice los índices de arreglos bidimensionales en el orden correcto

· Crear un arreglo con un elemento de mas.

· Usar macros y/o funciones para sacar el tamaño de un arreglo

Tipos de Datos no Nativos

Es la herramienta más poderosa que te puede brindar un lenguaje de programación para clarificar tu programa. Esta herramienta permite cambiar la precisión de cualquier cálculo en tu programa solo cambiando un tipo de variable

Estructuras

Es un concepto mejorado del typedef básico. Nos permite varios tipos de datos para encapsularlos y organizar el código mejor. El mejor uso de esta herramienta es para la simulación de un objeto en la realidad

Rutinas de Alta calidad

Antes que comienze, me gustaria defender ambos codigos. Dado que ambos codigos fueron diseñados como algoritmos y no subrutinas o funciones, yo diria que muchos aspectos del capitulo 7 no se deberian de aplicar para el analisis de estos codigos. Ya dicho esto continuo con la evaluación.

Analisis de mi propio codigo para sacar el MCM;
En mi opinion, este algoritmo si tiene que estar puesto en una sub-rutina. Quizas tambien hubiese sido buena decicion hacer una sub-rutina para sacar el Maximo commun factor (MCF). De esta manera el algoritmo estaria mas centrado en la idea de sacar el MCM, y no deducir el MCF primero para sacar el MCM. En este caso el algoritmo hace 2 cosas bien, pero hubiese sido mejor tener 2 algoritmos apartes. Asi tengo 2 algoritmos que hacen 2 cosas bien, y no 1 que hace 2 cosas bien.

El tamaño de la rutina es especificamente el esfuerzo logico que toma, con 1 extra paso para optimizar el codigo. No mucha gente se dieron cuenta, pero el ordenamiento que hago para que Numero1 sea mayor que Numero2 no es estrictamente necesario. En el bucle de la condicion, si el Numero1 es menor que el Numero2, la division modular resultaria en el Numero1 (mas pequeño) . Las proximas sentencias en el codigo intercambiaria los valores, y en la proxima iteracion la respuesta fuera la correcta. De todos modos, pense que antes de hacer esos calculos, era mejor ordenar los numeros.

Como este pedazo de codigo es estrictamente un algoritmo y no una subrutina o función, ningun paramametro fue declarado. Pero en mi opinion, el algoritmo solo utiliza las variables que necesita y estrictamente eso. En caso que hubiese hecho una funcion, solo pasaria los 2 numeros para analizar, en vez de pedirlos como una entrada, y mandaria el resultado como valor de retorno.

Analisis de Codigo para Sacar el Nuemro Primo;
Este codigo esta bien separado, la logica de deducir si el numero es primo o no esta separado de la logica para sumar los primeros 100 numeros. La función (o subrutina, todavia no estoy claro como ella describio su pseudo) EsPrimo tiene un buen nombre, se puede entender que hace la función (o subrutina) cuando se ecucha el nombre. Aunque "Calcular" le falta un sujeto.

Tambien ambas funciones/rutinas hacen solo 1 cosa, y el tamaño de la funciones/rutinas son resultado directo del esfuerzo logico que requieren y nada mas. En los casos de paso de parametros y valores de salida no esta claro el pseudo y prefiero no comentar sobre los mismos. Pero solo estan declaradas las variables que son requeridas y nada mas.

Conclusión;
En mi opinion ambos algoritmos fueron bien diseñados, dado que estaban desarollados como algoritmos y no subrutinas o funciónes. Quizas sea por experiencia previas que intentamos que el pseudo sea mas y mas como codigo de algun lenguaje.

Monday, January 30, 2006

Tarea 2

1)Diferencia de Tiempo;
#include cstdlib
#include iostream
#include stdlib.h
#include time.h
#include sys\timeb.h
using namespace std;

timeb Antes, Despues;

static void Generar(int numero)
{
FILE *Archivo;
Archivo = fopen("C:\\Codigo.txt","w");
for(int i = 0 ; i < numero ; ++i)
fprintf(Archivo,"Numeros[%i] = 0;\n",i);
}

int main(int argc, char *argv[])
{
//Generar(500000);
int Numeros[400000];
int Numeros2[400000];
ftime(&Antes);
for(int i = 0 ; i < 400000; ++i)
Numeros2[i] = 0;
ftime(&Despues);
//float differencia = (float(difftime(Despues.time,Antes.time))) + (float(abs(Despues.millitm - Antes.millitm))/1000);
float timediff = (float(difftime(Despues.time, Antes.time))) + (float(abs(Despues.millitm - Antes.millitm))/1000);
printf("Diferencia de tiempo: %.3f segundos.\n",timediff);

//Hasta aqui me decia el tiempo que tomaba el "for" que en mi caso siempre era de .000 milisegundos.

En la inicializacion por linea no me terminaba de compilar. El IDE me tira error por falta de memoria para compilar. Comoquiera el metodo de For es mucho mas comodo dado que dura mucho menos tiempo compilando. La inicializacion de linea por linea dura demasiado tiempo compilando.

No puedo comprobar mas de 400,000, el programa me da un error desconocido del sistema. Lo mas seguro es por falta de memoria tambien.

2)Analisis de Codigo; Nidia

Sub EsPrimo( ) 'Una subrutina no devuelve valor
Dim numero as Integer
Dim i as Integer
Dim Primo as Boolean
for i = 2 to numero 'numero es igual a 0, no entra en el for
if numero mod i = 0 then
primo = false
'assumiendo que entra al for, el numero que se prueba simpre va a ser primo porque N%N 'siempre es 0.
else
primo = true
end if
next
end sub

sub calcular()
dim i as integer
dim numero as integer
for i = 2 to 541 '...no se que decir
if esprimo(i) then 'sub rutina no devuelve nada, y en este caso no tiene paramentros
esprimo(i) = numero 'asumiendo que esprimo() devuelve un booleana; se esta assignado a un int
dim suma = 0 as integer 'siemre va a dar 541, como es el ultimo numero que se verifica y resetea la suma
suma = suma + numero
end if
next
end sub

P.S.
portando el codigo a mi desktop, me permite un arreglo maximo de 518904.
ya a este nivel se ve que el bucle for toma approximadamente 15 a 16 millisegundos, pero solo cuando hay una diferencia. Mayoria de las veces sale todavia 0 millisegundos de diferencia. Lo mas probable es que se tarde en stack, y por eso se nota la differencia

Sunday, January 22, 2006

Problema #1 Suma de los Primeros 100 numeros Primos
A)
//Bucle For
int resultado = 0;
int count, NumeroActual;
bool EsPrimo = true;
NumeroActual =2;
for(count=0; count<100; NumeroActual++)
{
EsPrimo = true;
for (int i = 2; i<=sqrt(NumeroActual); i++)
if (NumeroActual % i == 0)
EsPrimo=false;
if(EsPrimo)
{
resultado+= NumeroActual;
count++;
}
}
cout << resultado << endl;

B)
//Bucle While
int Resultado = 0;
int Count = 0;
int NumeroActual = 2;
int CountActual = 2;
bool NumeroPrimo = true;
while(Count < 100)
{
NumeroPrimo = true;
while((CountActual) <= sqrt(NumeroActual))
{
if(NumeroActual % CountActual == 0)
{
NumeroPrimo = false ;
}
CountActual++;
}
if(NumeroPrimo)
{
Resultado+= NumeroActual;
Count++;
}

NumeroActual++;
CountActual = 2;
}
cout << Resultado << endl;

C)
En el segundo bucle, se pueden cambiar los limites para que que llegue al numero que se esta
probando, es decir;
for (int i = 2; i<=NumeroActual; i++)

O algo mas efficiente que la anterior, solo se llega a la mitad del numero, es decir;
for (int i = 2; i <= NumeroActuall/2 ; i++)

esto es porque despues de la mitad del numero, el resultado siempre va a ser menor que 2. Porque si divides un numero por un segundo que es mas alto que la mitad del primero, siempre
va a resultar un decimal menor que 2.

D)
En mi opinion ambos bucles hacen lo mismo, solo que en el While uno tiene que hacer el incremento. El for se ve mas limpio, pero en ambos bucles se hacen las mismas operaciones, aumentos, sumatorias, validaciones, y producen el mismo resultado. La unica ventaja es que el for es mas facil de implementar, uno debe de tener en cuenta que la condicion de incremento no tiene que ser la misma que el contador.


Problema #2
Se Utiliza 2 computadoras, una de 3Ghz y la Otra a 800mhz y solo se utiliza para ordenar 1,000,000 de registros de nombres. En que condiciones el segundo equipo seria mas rapido que el primero?

Si el primer computador utiliza el Bubble Sort mal implementado, assumiendo el algoritmo no se entera cuando esta organizado, y el segundo ordenador utiliza el quicksort es casi seguro que el segundo ordenador terminara primero. El algoritmo quicksort utiliza operaciones a nivel de bit (bitwise operators)

Problema #3
int Numero1, Numero2;
cin >> Numero1;
cin >> Numero2;
if (Numero1 < Numero2)
{
int temp = Numero2;
Numero2 = Numero1;
Numero1 = temp;
}
int CopyNumero1 = Numero1;
int CopyNumero2 = Numero2;
int Condicion = 1;
while(Condicion != 0)
{
Condicion = Numero1 % Numero2;
Numero1 = Numero2;
Numero2 = Condicion;
}
cout << CopyNumero1 * CopyNumero2 / Numero1 << endl;

A) 4 formas
I-) Con el Maximo Commun Factor (MCF), Se multiplican ambos numeros y el resultado se divide entre el MCF.
II-)Se divide un de los numero entre el MCF y el resultado se multiplica por el otro numero
III)Se encuentran las portencias mas altas de los factores de los numero y se multiplican.
IV) Dado que utilizamos una computadora podemos hacer hacer un bucle que divida el contador
entre ambos numeros, el primero numero que cumple esta condicion es el minimo commun denominador

B)
Yo diria que la I o la II

C)
Porque que la III requiere mas calculos debe de ser mas lenta, y la
forma IV es simplemente absurda.