4

# Algoritmos, pueden llevarte a la cima solo si eres [email protected]

Cuando empezamos en programación lo primero que aprendemos son algoritmos por lo general muy simples, y aunque en ese momento
estemos pendiente de como se muestra un botón o de las últimas tendencias en el framework de turno(ya hablaremos sobre frameworks),
es un tipo de conocimiento que debemos llevar hasta el límite.

“Lo que diferencia a los maestros de los amateurs, es el dominio inigualable de los fundamentos”

Si querés entrar a una empresa del big four (Google, Facebook, Amazon, Microsoft) te van a pedir un profundo conocimiento de algoritmos
y no es porque sean fancys o les guste que sepas resolver problemas raros, sino que al ser desarrollos de alto tráfico y de alta
disponibilidad no se pueden dar el lujo de que un proceso tome mucho tiempo en ejecutarse o consuma demasiados recursos.
Lo mismo pasa con cualquier empresa que requiera tener un sistema decente.

“Si para resolver un problema buscas TODO en stack overflow, lógicamente tenés un problema”

El problema que tenés acá es el siguiente: ¿qué va a pasar cuando tengas requerimientos muy específicos?, o que te rechacen el feature por
7 milisegundos de más por request y todo lo que encontras en internet son ciclos anidados o cosas así,la gente con la mejor voluntad puede intentar ayudarte pero el único responsable de ganar esa contienda sos vos.

Todo lo que tenés que hacer para salirte con la tuya ante ese reto, es recordar tus lecciones con el viejo sabio sobre algoritmos.

Si no sabes qué es un Algoritmo estás en el lugar indicado porque voy a explicarte cómo viene la mano.

¿Qué es un algoritmo?

Un algoritmo es un conjunto de operaciones o instrucciones que te permiten encontrar la solución a un problema. Cualquiera sea la índole,
puede ser prepararte un café, salir de tu casa u ordenar un conjunto de números enteros de menor a mayor.
Definir la serie de pasos a seguir para cumplir nuestro cometido es nuestra tarea a la hora de sentarnos a diseñar un algoritmo.

Hasta ahora venimos bien, cualquiera puede diseñar un algoritmo, ahora démosle una breve dosis de realidad. El algoritmo además de existir
tiene que resolver de manera eficiente, no basta con que solo resuelva el problema.

¿Cómo saber qué tan eficiente es un algoritmo?

Ya escribimos un programa que resuelve algo, ahora quiero saber cómo medir su eficiencia:

  • ¿Cantidad de líneas de código? NO
  • ¿Cantidad de tiempo que tarda en ejecutarse? NO.

La cantidad de líneas de código no afecta en nada al rendimiento de un programa y la cantidad de tiempo de ejecución está muy ligada
a la computadora que se use para ejecutar el programa, no es lo mismo probar un software en una PC de los 90 que en una actual.

Normalmente se usa la notación “Big O” en la cual se asumen constantes como cantidad de instrucciones máquina y media de instrucciones
máquina que ejecuta una computadora específica.
Hay mucha teoría para digerir acerca de cómo deducir el Orden de una función y no me voy a adentrar en esas oscuras aguas, de momento me
voy a limitar a enumerar Órdenes comunes

  • O(1) -> var a = arr[3]
  • O(log n) -> Dividir el problema en 2 hasta encontrar la solución
    for(var i = 100; i > 0; i/=2){console.log(i)}
  • O(n) -> Como máximo se ejecutará n veces
var a = 9
varn = 10
for (var i = 0; i<n; i++){
  if (i === a){
    console.log('YEAH LO ENCONTRÉ')
  }
}
  • O(n log n) -> Una instrucción de Órden O(log n) dentro de una O(n)
  • O(n^2) -> Una instrucción de Órden O(n) dentro de otra de Órden(n)
varn = 100
for (var i=n; i<=n; i++){
  for (var j=n; j<=n; j++>){
    console.log(i, j)
  }
}
  • Y hay casos mas extremos como O(n^3), O(2^n), O(n^n), O(n!) pero los voy a desestimar por ser de uso muy limitado

Podés chequear el gráfico comparativo de complejidades en este enlace

Hay algo que me gustaría aclarar “Si sabemos que van a ser pocos datos y eso NUNCA VA A CAMBIAR, da igual el orden del algoritmo que usemos”

Paradigmas

<h3>Fuerza bruta</h3>

Consiste en enumerar todas las posibles soluciones de un problema .

<h3>Voraz (Greedy)</h3>

Se elige la solución óptima actual sin considerar nada a futuro.

<h3>Divide y vencerás</h3>

Dividir el problema en partes más pequeñas hasta encontrar la solución.

<h3>Programación dinámica</h3>

Se divide el problema en subproblemas más pequeños y se usa el resultado de estos subproblemas para resolver el problema principal, por ejemplo una función recursiva.

<h3>Búsqueda hacia atrás (Backtraking)</h3>

Es parecido a Fuerza Bruta, intenta generar todas las soluciones posibles y cada vez que generas una nueva solución preguntás si satisface todas las condiciones, solo en caso
de ser cierto sigue generando soluciones subsecuentes. Sino vuelve atrás e intenta en un camino diferente.

<h3>Ramificación y poda (Branch and Bound)</h3>

Similar al Backtracking solo que se fija si las condiciones no son óptimas deja de adentrarse en los subnodos, vuelve atrás e intenta por otro camino.

El conocimiento sobre algoritmos te va a dar la capacidad de resolver Tipos de problemas de una manera eficiente y te va a hacer un mejor desarrollador

Si querés que publique más artículos con ejemplos hacémelo saber en los comentarios

<El último apaga la luz>

Escribe tu comentario
+ 2
2

Genial! de hecho este artículo me sirvió mucho ya que me levanto el animo, estoy aprendiendo a programar, la verdad ha sido una tarea bastante ardua y en ocasiones estresante y me pongo de mal humor.
sigue realizando artículos como este con ejemplos. Gracias!!!