Mostrar si un número es primo con Kotlin

Los números primos son todos aquellos números que solo tienen dos divisores, el 1 y él mismo; por ejemplo, el número 7 es primo ya que solo se puede dividir por 1 y por 7. Este programa escrito en Kotlin cuenta con las siguientes 4 características:

  1. Evalúa el número ingresado por el usuario.
  2. Nos muestra los divisores que tiene ese número.
  3. Nos muestra cuántos divisores tiene ese número.
  4. Nos muestra si un número es o no es primo.
package numeroprimo

fun main(arg: Array<String>) {
    var NumPrimo: Int?
    var Cont = 0
    var Lim = 0

    print("Por favor, ingrese el numero a evaluar: ")
    NumPrimo = readLine()?.toIntOrNull()

    println()
    println("Numero ingresado:\t$NumPrimo")
    print("$NumPrimo es divisible por:\t")
    (1 .. NumPrimo!!).forEach { div ->
        if(NumPrimo % div == 0) {
            print("$div - ")
            Cont++
            Lim++
            if(Lim == 10) {
                print("\n\t\t\t")
                Lim = 0
            }
        }
    }
    println("Fin!!")

    when(Cont) {
        2 -> println("Si es un numero primo, tiene $Cont divisores")
        else -> println("No es un numero primo, tiene $Cont divisores")
    }
}

En Kotlin la sentencia package es opcional; pero es recomendado usar dicha sentencia asignando un nombre de paquete al archivo fuente cuando se trabaja en programas más grandes que serán divididos en diferentes archivos con el fin de facilitar la importación desde otros archivos fuente. En este caso lo he puesto para explicar esta parte ya que no es necesario por ser un pequeño programa.



Función main() en Kotlin:
fun main(arg: Array<String>) {
    println("Esto es un programa básico en Kotlin")
}

El Kotlin la función main() es requerida y cumple exactamente la misma labor que en otros lenguajes como C, C++, Go y Java; es la unica funcion que se ejecuta de forma automática cuando el programa está en ejecución, todo lo que se encuentre en su interior será ejecutado incluyendo funciones, objetos e instancia de objetos.

A diferencia de su homologo Java, en Kotlin no es obligatorio declarar una clase con el mismo nombre que el archivo fuente y en su interior declarar la función main(). Por ejemplo:

public class ProgramaBasico {
    public static void main(String[] args) {
        System.out.println("Esto es un programa básico en Java");
    }
}
Declarando e inicializando variables:
var NumPrimo: Int?
var Cont = 0
var Lim = 0

Aunque este es un lenguaje de tipado estático, existen dos forma para declarar variables como se muestra en este fragmento de código; la primera es indicando el tipo de dato explícitamente como se hace en la primera línea en donde se indica que la variable es de tipo Int?, mientras que en la segunda forma se hace mediante la inferencia de tipos como se hace en la segunda y tercer línea que se inicializan con un valor de cero, siempre y cuando el tipo se pueda inferir desde el contexto.

Advertencia: una vez que una variable toma un tipo, este no se puede cambiar a otro o tomar un dato de otro tipo ya que genera un error en tiempo de compilación.

Función readLine() y .toIntOrNull(), leyendo datos por teclado:
print("Por favor, ingrese el numero a evaluar: ")
NumPrimo = readLine()?.toIntOrNull()

Este fragmento de código es el responsable de la interacción directa entre el usuario y el programa como tal. En Kotlin existen varias formas de ingresar datos por teclado con la función readLine(), aquí se usa junto con la función .toIntOrNull(). En la primera línea se le solicita al usuario que ingrese un numero entero cualquiera; en la segunda línea el programa espera a que el usuario ingrese dicho número y presione Enter, luego de ser leído el número entonces pasa a ser evaluado por la función .toIntOrNull() y devolverá dicho valor convertido a tipo Int si el contenido ingresado es válido o en caso contrario devuelve null y es asignado a NumPrimo.

Mostrando información básica al usuario:
println()
println("Numero ingresado:\t$NumPrimo")
print("Es divisible por:\t")

Este fragmento de código es el más sencillo, simplemente le muestra al usuario información de interés como el “Numero ingresado:” junto con un espacio tabulador y mediante la interpolación $NumPrimo el número ingresado por el usuario; también el mensaje “Es divisible por:” y junto a él, los divisores del número.

Función forEach {}, iterando en un rango:
(1..NumPrimo!!).forEach { div ->
    if (NumPrimo % div == 0) {
        print("$div ")
        Cont++
        Lim++
        if (Lim == 10) {
            print("\n\t\t\t")
            Lim = 0
        }
    }
}
println("Fin!!")

La función forEach {} basicamente es un bucle pero al estilo funcional y recibe como único argumento una expresión lambda, esta función va a iterar en un rango desde 1 hasta el valor de NumPrimo!!, el parámetro div toma cada número de dicho rango y lo pasa al cuerpo de la expresión lambda. Aquí hay un detalle que falta por explicar, la variable NumPrimo va acompañada con el operador de aserción !!; dicho operador es obligatorio ya que se le debe indicar al compilador que dicha variable no es null.

Hay dos sentencias if() pero la segunda está anidada, la primera basicamente va a verificar si el residuo de NumPrimo!! modulo (%) div es igual a cero, si es verdadero, entonces imprime el valor de div e incrementa los valores de Cont y Lim en 1; el if anidado va a verificar si el valor de Lim es igual a 10, si es asi entonces da un salto de línea con el carácter “\n” partiendo la lista de divisores, luego los alinea con la lista anterior dando 3 espacios tabulados con el carácter “\t” y reinicia a Lim con un valor de cero.

Al ejecutar el programa, este fragmento de código nos produce el siguiente resultado:

Es divisible por:    1 2 11 22 53 59 106 118 583 649 
                     1166 1298 3127 6254 34397 68794 Fin!!

Aquí se observa más en detalle lo que ocurre cuando la cantidad de divisores llega a 10 y la palabra “Fin!!” es impresa la última línea de código println(“Fin!!”).

Sentencia when(), ¿es o no es número primo?:
when (Cont) {
    2 -> println("Si es un numero primo, tiene $Cont divisores")
    else -> println("No es un numero primo, tiene $Cont divisores")
}

Breve descripción: la sentencia when en Kotlin es el reemplazo de la famosa, legendaria y ancestral sentencia switch() que se encuentran en lenguajes como C, C++, Java, Groovy y Go; pero con vitaminas.



La sentencia when() recibe un solo argumento que en este caso es la variable Cont y la compara con cada una de las diferentes opciones hasta encontrar un valor que coincida, si es 2, entonces le informa al usuario que el número es primo con la cantidad de divisores encontrados; pero si Cont tiene otro valor, entonces pasa a la opción else e informa al usuario que el número no es primo con la cantidad de divisores que se encontraron.

Al compilar y ejecutar este programa, nos arroja el siguiente resultado:

[fixedtorres@linuxero]$ kotlinc NumeroPrimo.kt -include-runtime -d NumeroPrimo.jar
[fixedtorres@linuxero]$ kotlin NumeroPrimo.jar
Por favor, ingrese el numero a evaluar: 68794

Numero ingresado:       68794
Es divisible por:       1 2 11 22 53 59 106 118 583 649 
                        1166 1298 3127 6254 34397 68794 Fin!!
No es un numero primo, tiene 16 divisores
[fixedtorres@linuxero]$ 

 

Add a Comment

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