lunes, 20 de marzo de 2017

Averiguar el mayor y el menor de dos números enteros positivos sin usar IF/ELSE

Hace veinte años, por ésta misma época del año, comenzaba a aprender a programar un computador. No estoy seguro de si es un recuerdo borroso de aquellos tiempos o un falso recuerdo, pero añoche apareció en mi pensamiento la idea de calcular el mayor y el menor de dos números enteros positivos sin utilizar sentencias condicionales IF/ELSE. Anoche estaba seguro de que lo había leido o lo había hecho, aunque no lograba recordar cómo. Hoy estoy convencido, acabo de conseguirlo y quiero escribir sobre por qué y cómo lo hice.

¿Por qué?
Resolver problemas sin usar sentencias IF/ELSE es una idea que me surgió al ver a mis estudiantes usarlas inapropiadamente. Para ellos todo problema se resuelve con millones de líneas IF/ELSE, en muchos casos redundantes y en otros, peor aún, inconsistentes. Debido a esta situación he procurado promover en ellos la solución de problemas sencillos, que tradicionalmente requerían de estas sentencias, pero sin explicarlas, sin darlas a conocer. Por ejemplo, en el clásico problema de averiguar el tipo de triángulo dadas las longitudes de sus tres lados, les pedí declarar tres variables lógicas (boolean usando lenguaje Java), cada variable llamada esEquilatero, esEscaleno y esIsosceles. El algoritmo a implementar simplemente debe dejar las tres variables con el valor correcto (true / false) según corresponda. Sencíllamente estoy priorizando el aprendizaje de las expresiones e instrucciones antes de pasar a estudiar las estructuras de control, a veces se hace el paso muy rápido, sin conseguir que el estudiante realmente apropie los conceptos básicos de operadores, operandos y expresiones.

¿Cómo?
La solución sin IF/ELSE para calcular el mayor y menor de dos números enteros positivos se reduce a dos expresiones aritméticas que aprovechan el comportamiento del operador de la división entera "/": Para dos números "a" y "b", si a > b se cumple que a/b > 0 y b/a==0. Simétricamente, si a < b se cumple que a/b ==0 y b/a>0. Éste comportamiento permite anular uno de los dos números "a" o "b" al multiplicarlo por a/b o b/a, según sea la relación de orden (mayor o menor). A continuación las dos expresiones y, por ahora, dejo el resto al análisis de los interesados:
mayor = (  a*(a/b)   +   b*(b/a)  )  /  (  (a/b)   +   (b/a)  );
menor = (  b*(a/b)   +   a*(b/a)  )  /  (  (a/b)   +   (b/a)  ); 

Los paréntesis son muy importantes en las expresiones (a/b) y (b/a).

Ahora queda como tarea generalizar la solución para todos los números enteros, no únicamente números positivos. También para números reales. En Internet se encuentra una solución para números enteros usando valor absoluto, sumas y restas:

mayor = ( ABS ( a + b ) + ABS ( a - b ) ) / 2
menor = ( ABS ( a + b ) - ABS ( a - b ) ) / 2


Sin embargo, la función ABS no cuenta como expresión simple. La tarea consiste en usar únicamente aritmética elemental...

ConTICtualizando, es muy importante que los estudiantes conozcan, comprendan y acepten que en Programacion de Computadores no existen soluciones únicas, radicales, dogmáticas, mejores o peores. Saber programar un computador implica explorar todas las alternativas de solución y evaluarlar según lo que se requiera. Para éste caso el requerimiento es no usar IF/ELSE, así que se trata de desarrollar habilidades de pensamiento, más que habilidades de memorización y repetición.