viernes, 13 de septiembre de 2013

Números primos

Empiezo un nuevo curso y revisando el material que debo tratar con una de mis alumnas de este semestre me encuentro con un problema clásico, un enunciado que se repite mucho ya que mezcla conceptos de estructuras de control (condicionales e iterativas) y aplica conceptos matemáticos, este post va de los números primos.

El problema busca determinar si un número es primo o no, por lo tanto, preparamos la información del problema:

¿Qué tengo?
Tengo un número entero positivo mayor que 1

¿Que quiero?
Determinar si dicho número es primo o no

¿Cómo lo hago?
Primero debemos tener claro lo que es un número primo, dejamos el enlace a wikipedia, en el que dice: un número primo es un número natural mayor que 1 que tiene únicamente dos divisores distintos: él mismo y el 1. 
Para que quede más claro:
5 es primo, porque sólo es divisible entre 1 y 5, no es divisible entre 2, ni 3 ni 4 y no consideramos evaluar si es divisible entre 6, 7 o más porque el divisor de un número debe ser siempre menor o igual a él.
6 no es primo, porque es divisible entre 2 y 3.

Generalizando, basta con encontrar un número entre 1 y N que sea divisor de N, para decir que N no es primo.

Analizamos, todo lo que hemos dicho hasta ahora:
1. Basta con encontrar un número: esto se traduce en una iteración con condicionante booleana que se detendrá cuando encuentre un divisor.
2. Entre 1 y N: esto se traduce como que la iteración tendrá el condicionante que el divisor buscado debe iterar entre 1 y N.

Planteamos el pseudocódigo:
//asumimos que tenemos una función con parámetro N que es un entero mayor a 1
//definimos la condicionante booleana
bool esPrimo = true; //asumimos que es primo a menos que encontremos un divisor
//definimos variable que itera entre 1 y N buscando un divisor
int iDivisor = 2;
//iteración
mientras(esPrimo AND iDivisor < N)
{
    //condicionante que puede hacer que esPrimo cambie: cuando encuentra un divisor
    SI (N % iDivisor == 0) //la operación % indica que calcula el residuo de la división de N entre iDivisor
    {
      esPrimo = false;
    }fin_SI
    iDivisor++; //incrementa el iDivisor para continuar la búsqueda
}fin_mientras
//puede salir de la iteración porque encontró un divisor, en ese caso esPrimo será falso
//puede salir de la iteración porque no encontró divisor, en ese caso iDivisor es igual a N
//condicionante
SI(esPrimo)
{
   imprime("Es Primo")
}
Caso contrario
{
  imprime("No es primo")
}

Este problema, como todos, se puede resolver de distintas formas, si revisáis el enlace de wikipedia por ejemplo, podréis ver que los números primos cumplen muchas propiedades que pueden aplicarse al programa para mejorar el rendimiento (por ejemplo reducir el número de iteraciones), sobretodo si se quieren evaluar números muy grandes.

1 comentario:

  1. Hago una acotación, está demostrado que si no se encuentra un divisor entero entre 2 y la raíz del número estudiado, el número es primo, por lo que el algoritmo es mucho más eficiente.

    Ej: Si quiero saber si 997 es primo, no necesito 996 iteraciones, sino que basta iterar hasta 31, si no se encuentra un divisor, el número es primo.

    ResponderEliminar