Resolviendo los Desafíos Día a Día del AdventJS 2024: Mejorando en JavaScript

En este blog resuelvo los desafíos diarios del AdventJS 2024, una iniciativa de @midudev para mejorar tus habilidades en JavaScript cada diciembre.

Día 1

Descripción del Reto:

Santa Claus 🎅 ha recibido una lista de números mágicos que representan regalos 🎁, pero algunos de ellos están duplicados y deben ser eliminados para evitar confusiones. Además, los regalos deben ser ordenados en orden ascendente antes de entregárselos a los elfos..

 

Solución:
La tarea es crear una función que reciba una lista de números enteros (que pueden incluir duplicados) y devuelva una nueva lista sin duplicados, ordenada en orden ascendente.

 

Código:

function prepareGifts(gifts) {
  return [...new Set(gifts)].sort((a, b) => a - b);
}

const gifts1 = [3, 1, 2, 3, 4, 2, 5];
const preparedGifts1 = prepareGifts(gifts1);
console.log(preparedGifts1); // [1, 2, 3, 4, 5]

const gifts2 = [6, 5, 5, 5, 5];
const preparedGifts2 = prepareGifts(gifts2);
console.log(preparedGifts2); // [5, 6]

const gifts3 = [];
const preparedGifts3 = prepareGifts(gifts3);
console.log(preparedGifts3); // []

 

Explicación:

  1. Usamos new Set(gifts) para eliminar los duplicados de la lista. Un Set es una estructura de datos que solo permite valores únicos.
  2. Luego, con el operador de propagación (...), convertimos el Set nuevamente en un array.
  3. Finalmente, utilizamos el método .sort() para ordenar los números en orden ascendente. La función de comparación (a, b) => a - b garantiza que los números se ordenen correctamente de menor a mayor.

 

 

 

Día 2

Descripción del Reto:

Santa Claus 🎅 quiere enmarcar los nombres de los niños buenos para decorar su taller 🖼️, pero el marco debe cumplir unas reglas específicas. Tu tarea es ayudar a los elfos a generar este marco mágico.

Reglas:

  • Dado un array de nombres, debes crear un marco rectangular que los contenga a todos.
  • Cada nombre debe estar en una línea, alineado a la izquierda.
  • El marco está construido con * y tiene un borde de una línea de ancho.
  • La anchura del marco se adapta automáticamente al nombre más largo más un margen de 1 espacio a cada lado.

 

Solución:

  1. Determina el largo del nombre más largo para calcular la anchura del marco.
  2. Construye las líneas superior e inferior del marco como una secuencia de * con la longitud requerida.
  3. Recorre los nombres, asegurando que cada línea esté correctamente alineada con espacios adicionales para mantener el ancho uniforme.
  4. Devuelve el marco completo como una cadena unificada.

 

Código:

function createFrame(names) {
    let maxLength = Math.max(...names.map(name => name.length));  
    let frameWidth = maxLength + 2;  
    let topBottomBorder = '*'.repeat(frameWidth + 2);  
    let framedNames = names.map(name => {
        return `* ${name}${' '.repeat(maxLength - name.length)} *`;
    });
    return [topBottomBorder, ...framedNames, topBottomBorder].join('\n');
}

createFrame(['midu', 'madeval', 'educalvolpz'])
// Resultado esperado:
***************
* midu        *
* madeval     *
* educalvolpz *
***************

createFrame(['midu'])
// Resultado esperado:
********
* midu *
********

createFrame(['a', 'bb', 'ccc'])
// Resultado esperado:
*******
* a   *
* bb  *
* ccc *
*******

 

Explicación:

Cálculo de la longitud máxima (maxLength):

  • Usamos Math.max junto con map para obtener el largo del nombre más largo. Esto asegura que el marco se ajuste a todos los nombres correctamente.

Construcción del marco:

  • La anchura del marco (frameWidth) se calcula como maxLength + 2, añadiendo un espacio de margen a cada lado.
  • Las líneas superior e inferior (topBottomBorder) son secuencias de * con una longitud de frameWidth + 2 (para incluir los bordes laterales).

Formateo de los nombres (framedNames):

  • Cada nombre se coloca entre un *, con un espacio antes y después. Los espacios necesarios para completar la línea se calculan como maxLength - name.length.

Unión del marco completo:

  • Combinamos las partes superior, inferior y las líneas con nombres usando join('\n') para formar un bloque de texto.

 

 

Día 3

Descripción del Reto:

Santa Claus 🎅 está revisando el inventario de su taller para preparar la entrega de regalos. Los elfos han registrado los juguetes en un array de objetos, pero la información está un poco desordenada. Necesitas ayudar a Santa a organizar el inventario.

Recibirás un array de objetos, donde cada objeto representa un juguete y tiene las propiedades:

  • name: el nombre del juguete (string).
  • quantity: la cantidad disponible de ese juguete (entero).
  • category: la categoría a la que pertenece el juguete (string).

Escribe una función que procese este array y devuelva un objeto que organice los juguetes de la siguiente manera:

  • Las claves del objeto serán las categorías de juguetes.
  • Los valores serán objetos que tienen como claves los nombres de los juguetes y como valores las cantidades totales de cada juguete en esa categoría.
  • Si hay juguetes con el mismo nombre en la misma categoría, debes sumar sus cantidades.
  • Si el array está vacío, la función debe devolver un objeto vacío {}.

 

Solución:

La mejor manera de abordar este problema es:

  • Crear un objeto para almacenar el inventario organizado
  • Iterar sobre el array de entrada
  • Crear categorías dinámicamente según se necesiten
  • Sumar cantidades para juguetes duplicados
  • Retornar el objeto organizado

 

Código:

function organizeInventory(inventory) {
    const organized = {};

    for (const item of inventory) {
        const { category, name, quantity } = item;

        if (!organized[category]) {
            organized[category] = {};
        }

        if (organized[category][name]) {
            organized[category][name] += quantity;
        } else {
            organized[category][name] = quantity;
        }
    }

    return organized;
}

const inventary = [
    { name: 'doll', quantity: 5, category: 'toys' },
    { name: 'car', quantity: 3, category: 'toys' },
    { name: 'ball', quantity: 2, category: 'sports' },
    { name: 'car', quantity: 2, category: 'toys' },
    { name: 'racket', quantity: 4, category: 'sports' }
  ]
  
  organizeInventory(inventary)
  
  // Resultado esperado:
  // {
  //   toys: {
  //     doll: 5,
  //     car: 5
  //   },
  //   sports: {
  //     ball: 2,
  //     racket: 4
  //   }
  
  const inventary2 = [
    { name: 'book', quantity: 10, category: 'education' },
    { name: 'book', quantity: 5, category: 'education' },
    { name: 'paint', quantity: 3, category: 'art' }
  ]
  
  organizeInventory(inventary2)
  
  // Resultado esperado:
  // {
  //   education: {
  //     book: 15
  //   },
  //   art: {
  //     paint: 3
  //   }
  // }

 

Explicación:

  1. Inicializamos un objeto vacío organized que contendrá nuestro inventario estructurado.
  2. Iteramos sobre cada item del inventario usando un bucle for...of que es más limpio y eficiente para arrays.
  3. Utilizamos destructuring const { category, name, quantity } = item para extraer las propiedades necesarias de cada item de manera más elegante.
  4. Para cada item:
    • Verificamos si la categoría existe (if (!organized[category])). Si no existe, creamos un objeto vacío para esa categoría.
    • Verificamos si el juguete ya existe en esa categoría:
      • Si existe, sumamos la nueva cantidad
      • Si no existe, inicializamos con la cantidad actual
  5. La solución tiene una complejidad temporal de O(n) donde n es el número de items en el inventario, lo que la hace muy eficiente.
  6. Esta implementación es óptima porque:

  7. Solo requiere una única iteración del array
  8. Usa acceso directo a propiedades de objetos (O(1))
  9. Maneja eficientemente la agregación de cantidades
  10. Es escalable para grandes cantidades de datos
  11. Mantiene la estructura de datos solicitada

 

 

 

 

 

puedes ver el repositorio de todos los ejercicios aqui: https://github.com/hebertdev/AdventJS-2024-Solutions

 

Compartir

Si te ha gustado este post, compártelo con tus amigos y de esta manera me ayudas a mantener este sitio web.