Código Morse en Kotlin

Este pequeño programa toma una palabra o texto ingresado por el usuario y luego lo codifica a Código Morse. Vamos a realizar el análisis del programa, como está codificado y veremos el resultado final en pantalla.

Código fuente
  fun String.codigoMorse(): String {
    val mapCode = mapOf<String, String>(
         "a" to ".-", "b" to "-...", "c" to "-.-.", "d" to "-..", "e" to ".", 
         "f" to "..-.","g" to "--.", "h" to "....", "i" to "..", "j" to "·---", 
         "k" to "-.-", "l" to ".-..", "m" to "--", "n" to "-.", "ñ" to "--.--", 
         "o" to "---", "p" to ".__.", "q" to "--.-", "r" to ".-.", "s" to "...", 
         "t" to "-", "u" to "..-", "v" to "...-", "w" to ".--", "x" to "-..-", 
         "y" to "-.--", "z" to "--..",

         "0" to "-----", "1" to ".----", "2" to "..---", "3" to "...--", 
         "4" to "....-", "5" to ".....", "6" to "-....", "7" to "--...", 
         "8" to "---..", "9" to "----.",

         "." to ".-.-.-", "," to "-.-.--", "?" to "..--..", "\"" to ".-..-."
    )

    var aux = ""
    this.toLowerCase().forEach { it ->
        aux += mapCode.getOrDefault(it.toString(), it.toString())
    }

    return aux
}

fun main(args: Array<String>) {
    val texto: String

    print("Ingrese el texto a codificar: ")
    texto = readLine() as String

    println("Texto codificado: ${texto.codigoMorse()}")
}

Recordemos que en Kotlin hay una sentencia package opcional que debe ir en la primera línea y nos permite asignar un nombre de paquete a nuestro archivo fuente según la ubicación en la que se encuentra. Siempre es recomendado usar esta sentencia cuando trabajamos con proyectos grandes, para facilitar el acceso a nuestras al código en nuestros archivos ubicados en diferentes rutas.

Extensión .codigoMorse()
fun String.codigoMorse(): String {
    val mapCode = mapOf<String, String>(
         "a" to ".-", "b" to "-...", "c" to "-.-.", "d" to "-..", "e" to ".",
         "f" to "..-.","g" to "--.", "h" to "....", "i" to "..", "j" to "·---",
         "k" to "-.-", "l" to ".-..", "m" to "--", "n" to "-.", "ñ" to "--.--",
         "o" to "---", "p" to ".__.", "q" to "--.-", "r" to ".-.", "s" to "...",
         "t" to "-", "u" to "..-", "v" to "...-", "w" to ".--", "x" to "-..-",
         "y" to "-.--", "z" to "--..",

         "0" to "-----", "1" to ".----", "2" to "..---", "3" to "...--",
         "4" to "....-", "5" to ".....", "6" to "-....", "7" to "--...",
         "8" to "---..", "9" to "----.",

         "." to ".-.-.-", "," to "-.-.--", "?" to "..--..", "\"" to ".-..-."
    )

    var aux = ""
    this.toLowerCase().forEach { it ->
        aux += mapCode.getOrDefault(it.toString(), it.toString())
    }

    return aux
}

En Kotlin existe algo que se llama Funciones de Extensión, básicamente son funciones que extienden la funcionalidad de una clase sin modificarla ni heredar de ella. Las extensiones funcionan igual que cualquier métodos y se crean como cualquier función, solo hay que anteponer el nombre de la clase que se desea extender.

En este fragmento de código creamos una extensión que no recibe parámetros llamada codigoMorse(), toma cualquier objeto de tipo String y lo codifica a Código Morse caracter por caracter.

Creando mapa con los caracteres y su respectiva Clave Morse.
val mapCode = mapOf<String, String>(
     "a" to ".-", "b" to "-...", "c" to "-.-.", "d" to "-..", "e" to ".",
     "f" to "..-.","g" to "--.", "h" to "....", "i" to "..", "j" to "·---",
     "k" to "-.-", "l" to ".-..", "m" to "--", "n" to "-.", "ñ" to "--.--",
     "o" to "---", "p" to ".__.", "q" to "--.-", "r" to ".-.", "s" to "...",
     "t" to "-", "u" to "..-", "v" to "...-", "w" to ".--", "x" to "-..-",
     "y" to "-.--", "z" to "--..",

     "0" to "-----", "1" to ".----", "2" to "..---", "3" to "...--",
     "4" to "....-", "5" to ".....", "6" to "-....", "7" to "--...",
     "8" to "---..", "9" to "----.",

     "." to ".-.-.-", "," to "-.-.--", "?" to "..--..", "\"" to ".-..-."
)

Creamos un mapa que contiene caracteres alfanuméricos y algunos signos, cada uno con su respectiva Clave Morse después de la palabra «to». Usaremos este mapa más adelante para codificar la información.

Creando auxiliar
var aux = ""

Creamos una variable auxiliar de tipo String que se inicializa con un string vacío, aquí vamos a guardar la información codificada.

Codificando palabra o texto
this.toLowerCase().forEach { it ->
    aux += mapCode.getOrDefault(it.toString(), it.toString())
}

Como en toda clase normal, this representa al objeto actual sobre el cual estamos trabajando, en este caso es un objeto String; por lo tanto, this.toLowerCase() es equivalente a decir String.toLowerCase() y convierte el String a minúscula. Hay que estamos trabajando con una extensión. Con el iterador forEach {} vamos a recorrer el String caracter por caracter, cada uno es asignado a la variable it.

Con el método .getOrDefault() vamos a consultar si cada uno de los caracteres existe con su respectivo valor el mapa. Este método recibe dos argumentos, el primero es el carácter que deseamos consultar en el mapa y el segundo el carácter que deseamos devolver en caso de que el carácter consultado no exista en el mapa; si existe entonces devuelve su correspondiente valor en clave morse y se concatena en la variable aux usando el operador +=. La expresión en la línea dos es equivalente a:

aux = aux + mapCode.getOrDefault(it.toString(), it.toString())
Devolviendo el resultado
return aux

Por último devolvemos la palabra o frase codificada.

Función main()
fun main(args: Array<String>) {
    val texto: String

    print("Ingrese el texto a codificar: ")
    texto = readLine() as String

    println("Texto codificado: ${texto.codigoMorse()}")
}

Como ya se sabe, en Kotlin es obligatoria la función main() y este es el punto de partida de todo programa.

Creando la variable texto
val texto: String

Esta variable recibe el texto o palabra que ingresa el usuario a través del teclado en la terminal.

Solicitando y leyendo la palabra o texto
print("Ingrese el texto a codificar: ")
texto = readLine() as String

Con la función print() le mostramos un mensaje al usuario indicando que ingrese un texto que desee codificar y luego lo leemos usando la función readLine(), pero hay que convertirla a String ya que el valor leído es de tipo String?, o de tipo anulable. Por último almacenamos el texto leído en la variable texto.

Mostrando el resultado
println("Texto codificado: ${texto.codigoMorse()}")

Después de todo el proceso hecho anteriormente, podemos mostrar el resultado. Llamamos a la Función Extensión .codigoMorse() como si fuera un métodos comun y corriente, toma texto o palabra y la codifica en Código Morse; por último mostramos el resultado con la función println() usando interpolación string con los símbolos ${}.

Ejecutando el programa

Al compilar y ejecutar el programa, nos mostrará los resultados de la siguiente forma:

[fixedtorres@linuxero]$ kotlinc -include-runtime CodigoMorse.kt -d CodigoMorse.jar
[fixedtorres@linuxero]$ kotlin CodigoMorse.jar 
Ingrese el texto a codificar: Hoy es: 11/10/2018
Texto codificado: ....----.-- ....: .----.----/.---------/..--------.-------..
[fixedtorres@linuxero]$

Como se dijo anteriormente, el programa respeta los caracteres que no se encuentren en el mapa, tal cual como se puede ver en el resultado en donde los caracteres «/» aparecen sin codificar ni son eliminados.


Añadir un comentario

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