tutorial

Cómo aprender a resolver algoritmos y Code Katas (sin frustrarte en el intento)

En algún momento probablemente escuchaste palabras como algoritmos o code katas en programación, y viste cientos de ejercicios donde el objetivo parece ser resolver problemas con la solución más eficiente posible.

Jose Gratereaux

Jose Gratereaux

Author

Cómo aprender a resolver algoritmos y Code Katas (sin frustrarte en el intento)

Muchos desarrolladores creen que resolver algoritmos es cuestión de “ser inteligente” o tener talento natural.

Pero la realidad es otra:

Resolver algoritmos es una habilidad entrenable.

Al igual que aprender un framework, escribir buen código o diseñar arquitectura, mejorar en code katas requiere práctica, estructura y una forma correcta de pensar.

La mayoría de las personas fallan no porque no sepan programar, sino porque intentan resolver el problema directamente sin entender cómo descomponerlo.

¿Qué es un Code Kata?

Un Code Kata es un ejercicio pequeño diseñado para practicar lógica y resolución de problemas.

La idea viene de las artes marciales: repetir ejercicios constantemente hasta desarrollar fluidez.

Sitios populares:

  • Codewars
  • LeetCode
  • HackerRank
  • Exercism

El error más común al resolver algoritmos

La mayoría hace esto:

  • Lee el problema
  • Intenta escribir código inmediatamente
  • Se bloquea
  • Busca la respuesta en Google

Ese flujo mata el aprendizaje.

La mentalidad correcta

Cuando resuelves algoritmos, NO estás programando primero.

Estás pensando primero.

Tu objetivo inicial NO es escribir código elegante.

Tu objetivo es:

  1. entender el problema
  2. dividirlo
  3. detectar patrones
  4. encontrar una estrategia

El código viene después.

Cómo afrontar un algoritmo correctamente

1. Entiende el problema completamente

Antes de escribir código, pregúntate:

¿Qué entra? ¿Qué debe salir? ¿Qué restricciones existen? ¿Qué casos especiales pueden ocurrir? ¿Qué pasa con valores vacíos? ¿Qué pasa con números negativos? ¿Qué pasa si el input es enorme? 2. Resuelve el problema manualmente

Esto es CRÍTICO.

Muchos quieren resolverlo en código sin antes resolverlo como humanos.

Ejemplo:

“Dado un string, retorna la cantidad de vocales.”

Antes del código:

"hello"

h -> no
e -> sí
l -> no
l -> no
o -> sí

resultado = 2

Cuando haces esto, tu cerebro comienza a detectar el patrón.

3. Divide el problema en pasos pequeños

Nunca pienses:

“¿Cómo resuelvo esto?”

Piensa:

“¿Qué pequeña acción debo hacer primero?”

Por ejemplo:

  1. recorrer el texto
  2. verificar si cada letra es vocal
  3. aumentar contador
  4. retornar resultado

Ahora el problema parece muchísimo más simple.

4. Escribe pseudocódigo

Antes de JavaScript:

crear contador

recorrer cada letra

si la letra es vocal
   aumentar contador

retornar contador

Si puedes explicar la lógica en español simple, probablemente ya sabes resolverlo.

5. Ahora sí: escribe código

Aquí recién conviertes la lógica a JavaScript.

Ejemplo completo paso a paso

Vamos a resolver este problema:

Problema

Dado un array de números, retorna el número más grande.

Ejemplo:

findLargest([3, 7, 2, 9, 1])
// 9

Paso 1 — Entender el problema

Input:

[3, 7, 2, 9, 1]

Output:

9

Paso 2 — Resolverlo manualmente

¿Cómo lo haría un humano?

empiezo con 3

7 es mayor que 3
ahora el mayor es 7

2 no es mayor que 7

9 sí es mayor que 7
ahora el mayor es 9

1 no es mayor que 9

Patrón detectado:

  • guardar el mayor actual
  • comparar cada número
  • actualizar cuando aparezca uno más grande

Paso 3 — Pseudocódigo

guardar primer número como mayor

recorrer el array

si el número actual es mayor que el mayor
   actualizar mayor

retornar mayor

Paso 4 — Pasarlo a JavaScript

function findLargest(numbers) {
  let largest = numbers[0];

  for (let i = 0; i < numbers.length; i++) {
    if (numbers[i] > largest) {
      largest = numbers[i];
    }
  }

  return largest;
}

Paso 5 — Pensar como programador

Aquí viene la parte importante.

Cuando yo resuelvo este problema, mi cerebro piensa algo así:

Necesito comparar números.

Para comparar, debo recordar cuál es el más grande hasta ahora.

Entonces necesito una variable.

¿Cómo reviso todos los números?
Con un loop.

¿Qué hago dentro del loop?
Comparar el actual con el mayor.

Si encuentro uno mayor:
actualizo.

Eso es resolver algoritmos.

No es memorizar soluciones. Es entrenar tu capacidad de dividir problemas.

Cómo mejorar realmente en algoritmos

1. Haz problemas pequeños

Muchos empiezan con problemas extremadamente difíciles. Empieza con:

  • strings
  • arrays
  • loops
  • objetos
  • contadores
  • frequency counters
  • two pointers

2. Repite problemas

Resolver un problema una vez NO crea habilidad. Rehacerlo sí.

Un buen ejercicio:

  • resolver hoy
  • repetir mañana sin mirar
  • repetir en 1 semana

3. Aprende patrones

Los algoritmos parecen infinitos… pero no lo son.

Muchos problemas usan los mismos patrones:

  • Sliding Window
  • Two Pointers
  • Hash Maps
  • Recursion
  • Stack
  • Queue
  • Binary Search

Cuando reconoces patrones, comienzas a resolver mucho más rápido.

4. NO memorices soluciones

Memorizar mata el aprendizaje.

En vez de memorizar:

pregúntate:

  • ¿por qué funciona?
  • ¿qué patrón usa?
  • ¿cómo llegaría a esto desde cero?

5. Habla mientras resuelves

Esto ayuda muchísimo.

Literalmente habla:

ok…
necesito recorrer el array…
ahora debo comparar…

Eso obliga a tu cerebro a estructurar lógica.

6. Aprende a tolerar la frustración

Los algoritmos son incómodos.

Y eso es normal.

Parte del proceso es quedarse bloqueado.

La mejora ocurre precisamente ahí.

Un ejercicio excelente para practicar Problema

Retorna true si una palabra es palíndromo.

Ejemplos:

isPalindrome("ana") // true
isPalindrome("radar") // true
isPalindrome("hello") // false

Cómo pensarlo

Paso 1

¿Qué es un palíndromo?

Una palabra que se lee igual al derecho y al revés.

Paso 2

¿Cómo invierto una palabra?

Tal vez:

convertir en array
invertir
unir
Solución
function isPalindrome(word) {
  const reversed = word.split("").reverse().join("");

  return word === reversed;
}
Luego viene la evolución

Después puedes preguntarte:

  • ¿Cómo hacerlo sin reverse()?
  • ¿Cómo optimizar memoria?
  • ¿Cómo hacerlo con two pointers?

Ahí es donde creces como desarrollador.

Consejo importante

NO midas tu progreso por cuántos problemas resuelves. Mídelo por:

  1. cuánto entiendes
  2. cuánto mejoras tu lógica
  3. cuánto dependes menos de Google
  4. cuánto mejor descompones problemas

Mi recomendación para practicar diariamente

Haz esto:

Rutina de 30 minutos
10 min

Leer y entender problema.
10 min

Resolver manualmente y pseudocódigo.
10 min

Implementar y refactorizar.

Haz eso todos los días durante meses. Tu cerebro cambia muchísimo.

Los mejores resolviendo algoritmos normalmente NO son los que más saben sintaxis, son los que mejor piensan.

Conclusión

Aprender algoritmos no se trata de memorizar soluciones complejas.

Se trata de:

  • entender problemas
  • dividirlos
  • detectar patrones
  • practicar consistentemente

Y sobre todo:

aprender a pensar paso a paso.

Porque al final, programar realmente es eso: resolver problemas.

BONUS

Vamos a solucionar una kata de esas que no son tan fáciles.

- Pronic Number

Task:
You have to create a function to check whether the argument passed is a Pronic Number and return true if it is & false otherwise.

Description:
Pronic Number -A pronic number, oblong number, rectangular number or heteromecic number, is a number which is the product of two consecutive integers, that is, n(n + 1).

The first few Pronic Numbers are - 0, 2, 6, 12, 20, 30, 42...

Explanation:
  0 = 0 × 1   // ∴  0 is a Pronic Number
  2 = 1 × 2   // ∴  2 is a Pronic Number
  6 = 2 × 3   // ∴  6 is a Pronic Number
 12 = 3 × 4   // ∴ 12 is a Pronic Number
 20 = 4 × 5   // ∴ 20 is a Pronic Number
 30 = 5 × 6   // ∴ 30 is a Pronic Number
 42 = 6 × 7   // ∴ 42 is a Pronic Number
Note:
Negative numbers are tested as well.


---
funcion que nos dan inicialmente:

function isPronic(n){
  // Happy Coding ^_^
}


---

Test:
	assert.strictEqual(isPronic(5),false,'5 is not a Pronic Number');
	assert.strictEqual(isPronic(6),true,'6 is a Pronic Number');
	assert.strictEqual(isPronic(-3),false,'-3 is not a Pronic Number');
	assert.strictEqual(isPronic(-27),false,'-27 is not a Pronic Number');

y aqui esta la solucion:

El problema

Tenemos que crear una función que determine si un número es un Pronic Number. **Un número pronic es el resultado de multiplicar dos números consecutivos: ** n * (n + 1)

Ejemplos:

0 = 0 × 1

2 = 1 × 2

6 = 2 × 3

12 = 3 × 4

20 = 4 × 5

Entonces:

isPronic(6) // true

isPronic(5) // false

Lo primero que hago: NO programar

El error más común es abrir el editor e intentar escribir código inmediatamente. Primero quiero entender el patrón.

Analizando el patrón

Veo esta secuencia:

0

2

6

12

20

30

42

Y también veo esto:

0 = 0 × 1

2 = 1 × 2

6 = 2 × 3

12 = 3 × 4

Entonces mi cerebro comienza a pensar:

ok...

el número debe poder escribirse como:

x * (x + 1)

o sea:

dos números consecutivos multiplicados

Ahora pienso cómo comprobar eso

Aquí normalmente me hago preguntas.

  • ¿Cómo descubro si un número cumple la regla?
  • ¿Necesito matemática complicada?
  • ¿O simplemente puedo probar números?

Y aquí aparece algo importante:

Muchas veces la solución más simple es suficiente.

Pensando como programador

Si recibo:

6

Yo podría probar:

0 × 1 = 0

1 × 2 = 2

2 × 3 = 6

Encontré coincidencia.

Entonces:

6 sí es pronic

Entonces ya tengo una estrategia

Mi lógica será:

empezar desde 0

multiplicar:

x * (x + 1)

si el resultado es igual al número:

   retornar true

si me paso:
   retornar false
Casos negativos

El problema dice algo importante:

Negative numbers are tested as well.

Y aquí mi cerebro piensa:

espera... ¿puedo multiplicar dos consecutivos y obtener negativo?

Ejemplos:

2 × 3 = 6

3 × 4 = 12

Siempre positivo o cero.

Entonces:

cualquier número negativo automáticamente es false

Eso simplifica muchísimo.

Pseudocódigo

Antes de JavaScript:

si el número es negativo
   retornar false

empezar loop desde 0

mientras el resultado no supere n

   calcular:
   x * (x + 1)

   si es igual a n
      retornar true

retornar false

Ahora sí: JavaScript

function isPronic(n) {
  if (n < 0) {
    return false;
  }

  let current = 0;

  while (current * (current + 1) <= n) {
    if (current * (current + 1) === n) {
      return true;
    }

    current++;
  }

  return false;
}

Explicando el código paso a paso

1. Validamos negativos

if (n < 0) {
  return false;
}

No existen números pronic negativos.

2. Creamos un contador let current = 0;

Este número representará:

x

en:

x * (x + 1)

3. Recorremos posibles combinaciones while (current * (current + 1) <= n)

Aquí estoy diciendo:

mientras no me pase del número seguir intentando

4. Verificamos coincidencia if (current * (current + 1) === n)

Si encontramos exactamente el número:

return true;

5. Probamos el siguiente consecutivo current++;

Cómo pensé realmente este algoritmo Y esta es probablemente la parte más importante.

Mi razonamiento real fue algo así:

No necesito matemática avanzada.
Solo necesito detectar el patrón.

El patrón es:
x * (x + 1)

Entonces puedo probar valores.

Si encuentro coincidencia:
true.

Si me paso:
false.

Eso es resolver algoritmos. Es aprender a descomponer problemas.

Algo importante que debes entender

Muchos developers creen que resolver algoritmos significa encontrar soluciones súper complejas.

Pero en la vida real:

las mejores soluciones normalmente nacen de lógica simple bien pensada.

Resultado final

function isPronic(n) {
  if (n < 0) {
    return false;
  }

  let current = 0;

  while (current * (current + 1) <= n) {
    if (current * (current + 1) === n) {
      return true;
    }

    current++;
  }

  return false;
}

Jose Gratereaux

Jose Gratereaux

I'm a software engineer specialized in Laravel, building modern web applications and sharing what I learn along the way. If you enjoyed this post, consider following me on GitHub.