Original article: https://www.freecodecamp.org/news/how-to-solve-coding-problems/

Me quedaban 15 minutos, y sabía que iba a reprobar.

Había pasado dos meses estudiando para mi primera entrevista técnica.

Pensé que estaba preparada, pero a medida que la entrevista llegaba a su fin, me di cuenta: no tenía idea de cómo resolver problemas de codificación.

De todos los tutoriales que había tomado cuando estaba aprendiendo a programar, ninguno incluía un enfoque para resolver problemas de código.

Tuve que encontrar un método para resolver problemas; mi carrera como desarrolladora dependía de ello.

Empecé inmediatamente a buscar métodos. Y encontré uno. De hecho, lo que descubrí fue una estrategia invaluable. Era un método de cuatro pasos comprobado que de algún modo pasaba desapercibido en el ecosistema del desarrollador.

En este artículo, repasaré este método de resolución de problemas en cuatro pasos que puedes usar para empezar a resolver problemas de codificación con seguridad.

Resolver problemas de código no es solo parte del proceso de entrevista de trabajo para desarrolladores—es lo que un desarrollador hace todo el día. Después de todo, escribir código es resolver problemas.

Un método para resolver problemas

Este método es del libro How to Solve It de George Pólya. Salió originalmente en 1945 y ha vendido más de un millón de copias.

Su método de resolución de problemas ha sido usado e impartido por muchos programadores, desde profesores de ciencias de la computación (mira el curso de Introduccion a las Ciencias de la Computación de Udacity impartido por el profesor David Evans) hasta modernos maestros del desarrollo web moderno como Colt Steele.

Veamos cómo resolver un problema sencillo de codificación usando el método de resolución de problemas en cuatro pasos. Esto nos permitirá ver el método en acción mientras lo aprendemos. Usaremos JavaScript como nuestro lenguaje de elección. El problema es el siguiente:

Crea una función que sume dos números y devuelva ese valor.

Hay cuatro pasos para el método de resolución de problemas:

  1. Entender el problema.
  2. Diseñar un plan.
  3. Llevar a cabo el plan.
  4. Mirar atrás.

Empecemos con el paso uno.

Paso 1: Entender el problema

Cuando te plantean un problema de código en una entrevista, es tentador el apresurarse a tirar código. Es difícil evitarlo, en especial si tienes un límite de tiempo.

No obstante, trata de contener ese impulso, Asegúrate que de verdad entiendes el problema antes de empezar a resolverlo.

Lee el problema. Si estás en una entrevista, puedes leer el problema en voz alta si eso te ayuda a ir más despacio.

A medida que leas el problema, aclara cualquier parte que no entiendas. Si estás en una entrevista, puedes hacer preguntas a tu entrevistador sobre la descripción del problema. Si estás por tu cuenta, piensa y/o busca en Google las partes de la pregunta que no entiendas.

Este primer paso es vital, ya que con frecuencia no tomamos el tiempo de entender por completo el problema. Cuando no entiendes el problema en su totalidad, te será más difícil resolverlo.

Para ayudarte a entender mejor el problema, pregúntate:

¿Cuáles son los datos de entrada?

¿Qué tipos de datos de entrada tendrá este problema? En este ejemplo, las entradas son los argumentos que tomará nuestra función.

Tan solo de leer la descripción del problema hasta ahora, sabemos que las entradas serán numéricas. Pero para ser más específicos, podemos preguntar:

¿Las entradas siempre serán únicamente dos números? ¿Qué pasaría si nuestra función recibe tres números como entrada?

Aquí podríamos pedirle al entrevistador que nos lo aclare, o examinar la descripción del problema con más detalle.

El problema de codificación puede que tenga una nota que diga, "Solo debes esperar dos entradas para la función." Si es así, ya sabes como proceder. Puedes ser más específico, ya que te darás cuenta de que necesitas preguntar más sobre qué tipo de entradas podrías estar recibiendo.

¿Las entradas siempre serán números? ¿Qué debería hacer nuestra función si recibe las entradas "a" y "b"? Aclara si nuestra función siempre recibirá números o no.

Opcionalmente, puedes escribir las posibles entradas en un comentario de código para hacerte una idea de cómo serán:

//entradas: 2, 4

A continuación, pregunta:

¿Cuáles son los datos de salida?

¿Qué devolverá esta función? En este caso, la salida será un número que es el resultado de los dos números de entrada. Asegúrate de entender cuales serán tus salidas.

Crea algunos ejemplos.

Una vez que tengas claro el problema y conozcas las posibles entradas y salidas, puedes empezar a trabajar en algunos ejemplos concretos.

Los ejemplos también pueden ser usados como controles de cordura para probar tu problema eventual. La mayoría de los editores de retos de código en los que trabajarás (ya sea en una entrevista o usando un sitio como Codewars o HackerRank) tienen ejemplos o casos de prueba ya escritos para ti. Aun así, escribir tus propios ejemplos puede ayudarte a consolidar tu comprensión del problema.

Empieza con uno o dos ejemplos sencillos de posibles entradas y salidas. Regresemos a nuestra función de suma.

Llamemos a nuestra función "sumar."

¿Cuál es un ejemplo de entrada? Uno podría ser:

// sumar(2, 3)

¿Cuál es la salida de esto? Para escribir la salida de ejemplo, podemos escribir:

// sumar(2, 3) ---> 5

Esto indica que nuestra función tomará una entrada de 2 y 3 y devolverá 5 como salida.

Crear ejemplos complejos.

Recorriendo ejemplos más complejos, puedes tomarte el tiempo para buscar casos extremos que puedas necesitar tener en cuenta.

Por ejemplo, ¿qué debemos hacer si nuestras entradas son cadenas en lugar de números? ¿Y si tenemos como entradas dos cadenas, por ejemplo, sumar('a', 'b')?

Puede que tu entrevistador posiblemente te diga que devuelvas un mensaje de error si hay algunas entradas que no sean números. De ser así, puedes agregar un comentario en el código para manejar este caso si te ayuda a recordar que necesitas hacer esto.

// devolver error si las entradas no son números.

Tu entrevistador puede también decirte que asumas que tus entradas siempre serán números, en cuyo caso no necesitas escribir código extra para manejar esta entrada particular de caso extremo.

Si no tienes un entrevistador y solo estás resolviendo este problema, puede que el problema te diga qué pasa cuando introduces entradas inválidas.

Por ejemplo, alguos problemas dirán, "si hay cero entradas, devuelve undefined (indefinido)." Para casos como este, opcionalmente puedes escribir un comentario.

// revisa si no hay entradas.

// si no hay entradas, devuelve undefined.

Para nuestros propósitos, asumiremos que nuestras entradas siempre serán números. Pero en general, es bueno pensar en casos extremos.

El profesor Evans de informática dice que escribamos lo que los desarrolladores llaman código defensivo. Piensa en lo que podría salir mal y en cómo tu código podría defenderse de posibles errores.

Antes de continuar con el paso 2, resumamos el paso 1, entender el problema:

-Lea a fondo el problema.

-¿Cuáles son las entradas?

-¿Cuáles son las salidas?

Crea ejemplos simples, luego crea ejemplos más complejos.

2. Diseñar un plan para resolver el problema.

A continuación, diseña un plan para resolver el problema. A medida que lo diseñas, escríbelo en pseudocódigo.

El pseudocódigo es una descripción en lenguaje llano de los pasos de un algoritmo. En otras palabras, tu pseudocódigo es tu plan paso a paso de cómo resolver el problema.

Escribe los pasos que necesitas tomar para resolver el problema. Para un problema más complicado, tendrías más pasos. Para este problema, podrías escribir:

// Crea una variable suma.

Suma la primer entrada a la segunda entrada usando el operador de suma.

// Guarda el valor de ambas entradas en la variable suma.

// Devuelve como salida la variable suma.

Ahora tienes tu plan paso a paso para resolver el problema.

Para problemas más complejos, el profesor Evans denota, "considera sistemáticamente cómo un humano resuelve el problema." Eso es, olvídate de cómo tu código podría resolver el problema por un momento, y piensa en cómo lo resolverías tú como un humano. Esto te puede ayudar a ver los pasos más claramente.

3. Llevar a cabo el plan (¡Resolver el problema!)

Hand, Rubik, Cube, Puzzle, Game, Rubik Cube

El siguiente paso en la estrategia de resolución de problemas es resolver el problema en sí. Usando tu pseudocódigo como tu guía, escribe tu código real.

El profesor Evans sugiere enfocarse en una solución sencilla y mecánica. Entre más fácil y simple sea tu solución, más probabilidades habrá de que lo programes correctamente.

Tomando nuestro pseudocódigo, ahora podríamos escribir esto:

function sumar(a, b) {
 const suma = a + b;
 return suma;
}

El profesor Evans añade, recuerda no optimizar prematuramente. Eso es, puede que estés tentado a decir, "¡Espera, estoy haciendo esto y va a ser un código ineficiente!"

Primero, solo saca tu solución simple y mecánica.

¿Y si no puedes resolver el problema entero? ¿Y si hay una parte que aún no sabes como resolver?

Colt Steele da un gran consejo aquí: Si no puedes resolver una parte del problema, ignora esa parte difícil que te está deteniendo. En su lugar, enfócate en lo demás que puedas empezar a escribir.

Ignora temporalmente esa parte difícil del problema que no acabas de entender, y escribe las otras partes. Una vez hecho eso, regresa a la parte más difícil.

Esto te permite terminar al menos algo del problema. Y  a menudo te darás cuenta de cómo abordar esa parte más difícil del problema una vez que regreses a ella.

Paso 4: Revisar lo que has hecho.

Una vez que tu solución esté funcionando, toma tu tiempo para reflexionar sobre ella y descubrir cómo hacerle mejoras. Este podría ser el momento de refactorizar tu solución en una más eficiente.

Cuando analices tu trabajo, aquí tienes algunas preguntas que Colt Steele sugiere te hagas para descubrir cómo puedes mejorar tu solución:

  • ¿Puedes obtener el resultado de manera diferente? ¿Qué otros enfoques hay que sean viables?
  • ¿Puedes entenderlo a primera vista? ¿Tiene sentido?
  • ¿Puedes usar el resultado o método para otro problema?
  • ¿Puedes mejorar los rendimientos de tu solución?
  • ¿Puedes pensar en otras maneras de refactorizar?
  • ¿Cómo han resuelto este problema otras personas?

Una manera en que podríamos refactorizar nuestro problema para hacer nuestro código más conciso: remover nuestra variable y usar un retorno implícito:

function sumar(a, b) {
 return a + b;
}

Con el paso 4, tu problema podría que nunca parezca terminado. Incluso grandes desarrolladores aún escriben código que más tarde lo miran y quieren cambiar. Estas son preguntas guía que pueden ayudarte.

Si todavía tienes tiempo en una entrevista, puedes repasar este paso y mejorar tu solución. Si estás escribiendo código por tu cuenta, toma el tiempo para repasar estos pasos.

Cuando estoy practicando el escribir código por mi cuenta, casi siempre me fijo en las soluciones que hay allá afuera que son más elegantes o efectivas que lo que yo he ideado.

Conclusión

En esta publicación, hemos repasado la estrategia de resolución de problemas de cuatro pasos para resolver problemas de codificación.

Repasémoslas aquí:

  • Paso 1: entender el problema.
  • Paso 2: diseñar un plan paso a paso de cómo resolverlo.
  • Paso 3: llevar a cabo el plan y escribir el código real.
  • Paso 4: revisar y posiblemente refactorizar tu solución para mejorarla.

Practicar este método de resolución de problemas me ha ayudado inmensamente  en mis entrevistas técnicas y en mi trabajo como desarrolladora.

Si no te sientes con la confianza a la hora de resolver problemas de escribir código, tan solo recuerda que la resolución de problemas es una habilidad que cualquiera puede mejorar con tiempo y práctica.

¡Buena suerte!

Si tienes comentarios o preguntas sobre esta publicación, siéntete libre de tuitarme @madisonkanna.