Prime Factors
Desarrollando algoritmos
Esta kata demuestra que a medida que los tests se hacen más específicos, el algoritmo se vuelve más general. Pero, aparte de eso, es una kata estupenda para reflexionar sobre la elección de ejemplos y por qué no nos sirven los test que pasan en cuanto los escribimos.
Por otro lado, la kata revela un concepto bastante más intrigante: la premisa de prioridad de las transformaciones, según la cual, del mismo modo que hay refactors que son cambios en la estructura de un código que no alteran su comportamiento, existirían transformaciones que son cambios en código que producen cambios en su comportamiento.
Estas transformaciones tendrían un orden, desde las más sencillas a las más complejas, y una prioridad en su aplicación que dicta que deberíamos aplicar antes las más sencillas.
Historia
La kata fue creada por Robert C. Martin1 cuando escribía un programa para su hijo que calculase los factores primos de un número. Pensando sobre su desarrollo, le llamó la atención el modo en que el algoritmo evoluciona y se simplifica a medida que se hace más general.
Enunciado
Escribir una clase con un método generate que devuelva una lista de los factores primos de un número entero. Si prefieres un enfoque más procedural, o incluso funcional, escribir una función primefactors.
Para no complicar el ejercicio el resultado se puede expresar con un array, lista o colección, con los factores no agrupados en forma de potencia. Por ejemplo:
1 primefactors(2) = [2]
2 primefactors(3) = [3]
3 primefactors(6) = [2, 3]
4 primefactors(8) = [2, 2, 2]
5 primefactors(12) = [2, 2, 3]
Orientaciones para resolverla
Esta kata es muy sencilla, a la vez que muy potente: hacen falta pocos ciclos para llevarla a cabo y, sin embargo, pone en evidencia algunas características de TDD especialmente importantes.
Para comenzar, podemos analizar los ejemplos que querríamos probar. En principio los argumentos serán números naturales. Tenemos tres categorías principales:
- Los que no tienen factores primos, el único caso es el 1.
- Los que son números primos, como 2, 3 o 5.
- Los que son producto de varios números primos, como 4, 6, 8 o 9.
Además, dentro de los números que no son primos, nos encontramos con los que son el producto de 2, 3 o n factores, repetidos o no.
Aplicando las leyes de TDD que ya hemos visto, comenzaremos con un test lo más pequeño posible que falle. Luego escribiremos el código de producción necesario para hacer pasar el test.
Iremos recorriendo los distintos casos escribiendo primero el test y, a continuación, el código de producción que lo hace pasar sin romper los tests anteriores.
Una de las curiosidades de esta kata es que podemos ir tomando ejemplos de la lista de números naturales en orden, desde el 1 hasta donde consideremos que podemos parar. Sin embargo, ¿es esta la mejor estrategia? ¿Puede llevarnos a escoger ejemplos que no nos sirven?