Mismo ejercicio, diferentes lenguajes

Hace tiempo hice una pequeña función php que, dado un número NIF, permite calcular la letra del DNI de esa persona. Lo hice en php por el simple hecho de familiarizarme ligeramente con su sintaxis y curiosear con cómo operar con los datos de un formulario en una página web; pero creo que es un gran ejercicio para poner en práctica de nuevo nuestros conocimientos de programación y ejercitar un poco las neuronas y nuestra memoria. Por eso voy a intentar transformar estas operaciones en un programa escrito en tres lenguajes altamente distintos: Pascal, Ocaml y Java. Desgranemos un poco el algoritmo…

El algoritmo
Basicamente se parte de una cadena de caracteres conocida que es la siguiente: “TRWAGMYFPDXBNJZSQVHLCKE”. No están todas las del abecedario, pero su longitud es 23 (un número primo, por otra parte).
Supongamos el DNI número 12341234. Si calculamos el resto de la división de ese número entre 23, obtenemos el número 9. La letra en la novena posición de nuestra cadena de caracteres es la letra “D” (comenzando a numerar por el cero).

Implementación en Pascal
Es muy sencillo: solo necesitamos dos constantes para la cadena y para el numero 23. En una variable leemos el número que introduce el usuario y mostramos simplemente la letra en la posición que sea el resultado del módulo. Solo hay una ligera complicación, Pascal comienza a numerar las letras de un string con el número 1, así que habrá que sumar 1 tambien al resto de la división…
La función que extrae un caracter de un string es “substr” y se utiliza:
substr (cadena_de_caracteres, posicion_inicial, numero_de_caracteres_extraidos)
Estrictamente devuelve otro string, porque podríamos extraer más de un caracter aumentando el valor del tercer parámetro, pero en nuestro caso nos es indiferente…
program dni (input, output);
 
const
   cadena = 'TRWAGMYFPDXBNJZSQVHLCKE';
   modulo = 23;
 
var
   nif: integer;
 
begin
   write ('Introduzca su NIF: ');
   readln (nif);
   writeln ('La letra de su DNI es: ', substr (cadena, (nif mod 23) + 1, 1) );
end.

Implementación en Ocaml
Ésta es mi favorita 🙂
Con una única función podemos resolver todo el problema. Para proteger el string, lo definiremos de forma local. Por seguir la notación habitual de Ocaml, la he llamado “dni_of_int”…
let dni_of_int x = let letras = "TRWAGMYFPDXBNJZSQVHLCKE"
                   in letras.[(x mod 23)];;

¡Poco más de una única línea! ¡Brillante! 😀

Implementación en Java
Probablemente, la implementación en Java se puede parecer mucho a la de Pascal, solamente modificando un par de cosas… Tambien será muy similar a la de otros lenguajes como C, C++, C#, …
Las diferencias vienen dadas por la forma en que es tratada la entrada de datos por teclado en java que nos obliga a capturar una excepción de tipo IOException y a convertir un String leido (el nif) a Integer y de ahí a int, que es el tipo de dato que usa nuestro programa.
De todas formas, aun siendo engorroso, es un buen ejemplo de como leer por teclado y cómo acceder a chars de un string en java…
import java.io.*;
 
class Dni {
 
  static final String cadena = "TRWAGMYFPDXBNJZSQVHLCKE";
  static final int modulo = 23;
 
 
  public static void main (String[] args){
    BufferedReader inp = new BufferedReader (new InputStreamReader (System.in));
 
    try {
      System.out.print ("Escriba su NIF: ");
      int nif = Integer.parseInt(inp.readLine());
      System.out.println ("La letra de su DNI es: "+(cadena.charAt(nif % modulo)));
    }
    catch (IOException exn){
      System.out.println ("Se produjo un error leyendo datos");
    }
 
  }
 
}

Algunos refinamientos e ideas…
En el caso de java, controlar una posible excepción ya es algo obligatorio, pero no estaría de más hacerlo siempre tambien en los otros lenguajes. Incluso, controlar que el NIF fuese un número entero comprendido entre 0 y 99999999.
Por último, si este fuese un programa que utilizásemos continuamente (lo dudo :P) estaría bien dotarlo de algunas comodidades. Por ejemplo, crear un bucle para que no hubiese que arrancarlo cada vez y estuviese siempre esperando un nuevo número nif. Se podría cerrar con una combinación de teclas (Ctrl+C o Ctrl+D, por poner dos ejemplos), o introduciendo un número clave (por ejemplo, el -1), etc. etc.
Incluso, la solución que yo veo más práctica, sería poder invocar el cálculo desde la línea de comandos, y que el usuario viese algo como esto:
$ ./dni 12341234
  Letra D
$

¿Quieres proponer alguna solución más? ¿O transportar esta utilidad a otro lenguaje de programación? Deja un comentario!

Anuncios

2 pensamientos en “Mismo ejercicio, diferentes lenguajes

  1. Pingback: Segundo año « Emilio

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s