Google code jam: ¿impossible?

Este sábado 8 de abril participé en el concurso para programadores Google code jam, que consiste en ir resolviendo problemas algorítmicos utilizando el lenguaje de programación que quieras.

Este año no fue el primero en el que participo en este concurso. Lo que he hecho diferente este año ha sido el utilizar Python en vez de Java, que es el lenguaje de programación que utilizo habitualmente.

La experiencia ha sido muy buena porque como comenté en el artículo anterior, Python te permite el enfocarte en el problema a resolver sin tener que preocuparte por cómo utilizar el lenguaje.

Todos los ejercicios requieren que leamos y escribamos ficheros y resuelta muy fácil con Python. Además la mayoría de los ejercicios tratan de manejar cadenas de caracteres, números binarios y cadenas de objetos y Python es perfecto para ello.

 

La primera ronda consiste en obtener 25 minutos resolviendo ejercicios. Cada ejercicio tiene sus puntos. Había cuatro ejercicios y cada uno con al menos dos partes. La diferencia entre la primera y la segunda es que la segunda debe de estar optimizada para resolverse de forma rápido porque sino no podrás obtener el fichero de salida en el tiempo estimado (creo que son 4 minutos).

Los ejercicios los puedes ver en el enlace siguiente:

https://code.google.com/codejam/contest/3264486/dashboard

 

Me enfoqué en los dos primeros ejercicios porque me parecieron más fáciles al leerlos y me permitían el superar la prueba si los sacaba a tiempo.

El primero se me atragantó y subí varias soluciones que no fueron las acertadas. Al comprobar detenidamente el resultado me dí cuenta que había deletreado mal impossible y que por eso había fallado, al menos en los dos últimos intentos. Esa es la razón por la que he puesto en el título impossible.

Supuré la ronda y ahora toca pasar la primera ronda que consiste en estar entre los mejores 1000 dentro de una de las tres pruebas programadas: Round 1A, Round 1B y Round 1C.

Desearme suerte 🙂

 

Si tienes curiosidad de como resolví los dos problemas a continuación puedes verlo:

Python y Google Code Jam

Imagen de https://i.ytimg.com/vi/Gaj54O90Yak/maxresdefault.jpg

Este es el segundo artículo que hablo sobre Python. Si quieres leer el primer artículo está aquí.

Terminé el curso de Python en CodeAcademy:

https://www.codecademy.com/courses/introduction-to-python-6WeG3

Lo recomiendo. Es muy práctico, fácil de seguir y con buen contenido. El único pero que le pongo es que dentro de poco lo van a cerrar. No recuerdo cuando pero leí que en unos meses van a quitar el curso. Una pena.

Durante el curso estuve pensando lo bueno que sería python para el Google Code Jam porque su forma de manejar cadenas, caracteres, números binarios, listas y arrays es muy intuitiva. Estos elementos se utilizan mucho en el code jam.

Google Code Jam es un competición de programación. Todos los ejercicios se basan en generar cierta lógica que cree un fichero de salida a partir de un fichero de entrada.
Llevo años compitiendo utilizando Java y creo que ya era hora de empezar a usar otro lenguaje.

La competición comienza el 7 de Marzo pero como tengo poca experiencia con Python decidí el hacer algunos ejercicios de prácticas.
En CodeAcademy no necesitaba tener configurado nada en mi ordenador porque el código se ejecutaba en el propio navegador. Pero para la competición me iba a ser útil el tener un entorno de trabajo de Python.
Así que me he configurado un entorno que no es el óptimo pero que es mas que suficiente para lo que quiero. Que es el poder crear y ejecutar pequeños programas de python en mi ordenador.
Tengo instalado python 2.7 y Atom en mi portátil. Dentro de Atom tengo cuatro plugins: atom-python-run, linter, linter-pylama y python-tools. El primer plugin es para poder arrancar ficheros de python en Atom, los de linter para el formateo de código (estilo lint en Javascript) y el último para todo lo demás relativo al lenguaje.

Después me puse a resolver problemas de años pasados de la competición y está siendo muy divertido. He terminado cuatro y estoy con el quinto.
Por si a alguien está interesado a continuación aparece una lista de los problemas y mis soluciones:

Ahora estoy con Revenge of the Pancakes que se me está atascando porque aunque tengo una solución esta no coincide con el esperado.

Método iterativo e incremental

Imagen de Henrik Kniberg

Tu empresa ha externalizado la creación de una aplicación a una empresa en India y a los cuatro meses de la fecha límite entregan una primera versión.
En esa primera versión te das cuenta que tiene bastantes problemas. Como por ejemplo:

  • Los requisitos mínimos no han sido cumplidos.
  • La interfaz de usuario tenía que ser igual a otra aplicación, ya que los usuarios están acostumbrados a esta primera, y no se parece nada.
  • La aplicación no funciona con el número mínimo de usuarios concurrentes que va a tener.
  • Las funcionalidades desarrolladas hacen lo que tiene que hacer, a veces.
  • El código no tiene un mínimo de calidad

Como puedes imaginar, no vas a poder arreglar todos los problemas en solo cuatro meses y los costes en cuanto a tiempo y dinero aumentan con cada mes que no ha entregado el producto, y serán muchos meses.
Además, la gente de negocio tiene que hablar con los clientes sobre estos cambios, ya que no van a estar terminados en la fecha prometida. Lo que bajará la confianza de los clientes en la empresa.
Lo mismo pasa con la gente de marketing y la campaña que tenían pensada hacer para captar nuevos clientes, que tendrán que ser pospuestas. Con el coste adicional que supondrá este cambio.

La forma de desarrollar este producto es en cascada (waterfall) ya que todos los requisitos han sido dados al principios del desarrollo y el producto se entrega cerca de la fecha de entrega.

Imagen de https://www.adictosaltrabajo.com/tutoriales/metodos-agiles

La forma de desarrollar un producto en cascada es la más eficiente porque si los requisitos han quedado claros y no hay problemas durante el desarrollo del producto se han gastado cada céntimo en las cosas necesarias para obtener el producto.
El problema es que en los 10 años que llevo desarrollando software siempre hay “problemas”. Puede ser que sea casualidad o que los problemas no son tal, si no un es algo habitual en el desarrollo de software. Personalmente me decanto por el segundo motivo.

Hay varias alternativas a este tipo de desarrollos en cascada pero voy a hablar del que conozco. Del desarrollo iterativo e incremental.

El desarrollo iterativo e incremental consiste en ir entregando versiones de tu producto que vayan entregando cada vez más valor con cada versión del producto.

Imagen de https://www.adictosaltrabajo.com/tutoriales/metodos-agiles

La ventaja de esta forma de desarrollar un producto es que si hay algo mal, como la lista que he comentado al principio, tenemos tiempo suficiente para poder solucionarlo. O lo que es lo mismo, estamos reduciendo el riesgo que es el entregar un producto al final del desarrollo sin saber si está bien.

Claro que esta forma de desarrollo tiene sus inconvenientes. El más importante es el tiempo que hay que dedicarle a verificar que vamos por el buen camino. El tiempo que dedicamos a hablar con el cliente o con la gente de negocio para comprobar que lo que estamos desarrollando encaja con lo que tenían pensado.
Otro inconveniente importante es que la forma de desarrollar cambia de forma drástica. En cada nueva versión de nuestro producto tenemos que comprobar que las nuevas funcionalidades funcionan de la forma correcta y que las funcionalidades desarrolladas en las versiones anteriores siguen funcionan. Así, con cada nueva versión que se acerca más al producto tenemos que probar muchas cosas: las funcionalidades nuevas y las antiguas.
Como puedes imaginarte llega un momento que este proceso de comprobar que todo lo desarrollo funciona de forma correcta no se puede realizar de forma manual. De forma manual quiero decir de una persona que compruebe un todo funciona.
Por lo que necesitamos algún tipo de proceso automático que nos permita comprobar que lo que hemos desarrollo funciona. Aquí es donde entra en juego los test unitarios, los test de integración y los test de aceptación.
Los test unitarios y de integración comprueban que la aplicación funciona como debe funcionar y los test de aceptación comprueba que la aplicación funciona como el usuario final quiere.

Los cambios de un proceso en cascada a un proceso iterativo e incremental son grandes. Tanto a nivel de negocio como a nivel de desarrollo. La gente de negocio tiene que ayudar a comprobar que lo que que el usuario quiere es lo que se está desarrollando (test de aceptación) y la gente de desarrollo tiene que crear test de integración y unitarios para comprobar que lo que se está creando funciona de forma correcta.
Estos cambios son grandes pero van a permitir a vuestra empresa a reducir los riesgos. Lo que va a permitir a vuestra empresa crecer reduciendo los riesgos en este crecimiento.

Personalmente las ventajas ganan a los inconvenientes en un proceso iterativo e incremental. ¿Tú qué opinas?