Héctor Daniel Jacales Rojas@danjacales

En el sitio de competencias y retos de programación CodeSignal, encontré un reto que me resulto interesante. No por su complejidad como por su naturaleza para poder explicar algunos conceptos de programación funcional.

Me gusta esta plataforma por que permite usar muchos de los lenguajes de programación más populares ( y no tan populares) . Lo que permite practicar y desempolvarse en los lenguajes que uno elige.

Para este reto, elegí Clojure, un lenguaje funcional que llevo algo de tiempo practicando y estudiando. Aunque no lo he utilizado para crear algún proyecto serio.

Me gusta por que usa una sintaxis completamente distinta a los lenguajes convencionales (Java,PHP,Ruby,Python,etc...) Y al seguir el paradigma funcional de manera estricta es necesario plantear los problemas de manera diferente a si se usara un lenguaje procedimental ( donde se indica de forma explicita lo que se tiene que hacer) . Para usar el paradigma funcional se requiere un enfoque más “matemático” . Pensar en funciones, como aquellas herramientas que damos un valor y nos regresan un resultado. Tal como en las clases de Cálculo I,II y III.

El reto básicamente consiste en lo siguiente.

Tenemos a nuestro cuidado una planta, que parte de una altura 0. (cm). Cada día crece n centímetros ( upSpeed ) y por la noche, por falta de luz decrece m centímetros ( downSpeed ) . Lo que queremos calcular es cuantos días se requieren para alcanzar una altura deseada ( desiredHeight ).

La función a desarrollar seria la siguiente.

growingPlant(upSpeed, downSpeed, desiredHeight )

Primera Parte

En este caso se necesita iterar a partir de dos variables iniciales, day y actual . Day es el día, empezamos en el día cero. Al igual que actual, que representa la altura inicial.

En este caso sabemos que debemos detenernos cuando la altura “actual” sea igual o mayor que la altura deseada. Y debemos regresar el valor de “day” que tiene el numero de días que han transcurrido desde que la planta ha crecido.

En caso contrario necesitamos hacer uso de recur. Una función especial en Clojure. Que por un lado incrementa por cada llamada a “day” en una unidades. Despues hace uso de una función “calcGrow” que lo que hace es asignar su valor de regreso a la variable “actual”. Lo que hace esta función se detalla en la segunda parte.

Segunda Parte

calcGrow recibe cuatro parametros

a => altura actual de la planta, al inicio del día.

u => cuanto crece la planta en un día

d => cuanto decrece la planta en la noche

g => cuanto esperamos que la planta crezca.

Y la función nos devuelve dos posibles resultados.

En caso de que la altura inicial mas el crecimiento del dia sea mayor o igual a la altura deseada. Se regresa la altura deseada, ya que se ha alcanzado nuestro objetivo.

En caso contrario se incrementa a el valor actual y se le resta el valor de decrecimiento de la noche.

Resultados

Como se puede observar el código ha pasado todos los casos de prueba. Lo que es una gran ayuda en herramientas como CodeSignal. Ya que suelen ser pruebas que cubren todo tipo de escenario posible. Y se va formando el habito de escribir código de calidad.


Escribe una respuesta