AdventJS 2023: Día 2
Tags: spanish, javascript, challenge, adventofcode
Published: 2023-12-03 04:59:16

Solución al [reto #2](https://adventjs.dev/es/challenges/2023/2) del [AdventJS 2023](https://adventjs.dev/es)
Solución del [Reto #1](https://dev.to/fenriuz/adventjs-2023-dia-1-2ncc)

{%- # TOC start (generated with https://github.com/derlin/bitdowntoc) -%}

- [Descripción del Reto](#descripción-del-reto)
- [Análisis](#análisis)
- [Solución](#solución)
   * [Iterando](#iterando)
   * [Regex](#regex)
   * [Soluciones de la comunidad](#soluciones-de-la-comunidad)

{%- # TOC end -%}

## Descripción del Reto

En el taller de Santa, los elfos tienen una **lista de regalos** que desean fabricar y un conjunto limitado de materiales.

Los *regalos son cadenas de texto* y los *materiales son caracteres*. Tu tarea es escribir una función que, dada una lista de regalos y los materiales disponibles, devuelva una **lista de los regalos que se pueden fabricar**.

Un regalo se puede fabricar si contamos con todos los materiales necesarios para fabricarlo.

```jsx
const gifts = ['tren', 'oso', 'pelota']
const materials = 'tronesa'

manufacture(gifts, materials)// ["tren", "oso"]
// 'tren' SÍ porque sus letras están en 'tronesa'
// 'oso' SÍ porque sus letras están en 'tronesa'
// 'pelota' NO porque sus letras NO están en 'tronesa'
const gifts = ['juego', 'puzzle']
const materials = 'jlepuz'

manufacture(gifts, materials)// ["puzzle"]
const gifts = ['libro', 'ps5']
const materials = 'psli'

manufacture(gifts, materials)// []
```

## Análisis

Tenemos un string con determinadas letras que son los materiales y un arreglo de palabras que son los regalos. Debemos buscar las palabras en las que todas sus letras se encuentren dentro del string materiales.

**Entradas:**

1. **Regalos (`gifts`):** Un array de strings, donde cada string representa un regalo.
2. **Materiales (`materials`):** Un string que representa los materiales disponibles.

**Salida:**

- Un arreglo de los regalos que se pueden fabricar utilizando los materiales disponibles.

**Consideraciones**

- Cada carácter en la cadena de un regalo representa un material necesario.
- Es necesario verificar que todos los caracteres de un regalo estén presentes en la cadena de materiales.
- Cada carácter en la cadena de materiales puede usarse múltiples veces, por lo que no hay límite de materiales.

## Solución

Para solucionar este problema encontré dos enfoques principales, iterando sobre los regalos y los materiales o usando [expresiones regulares](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_expressions).

### Iterando

```jsx
/**
 * Filtra una lista de regalos basándose en los materiales disponibles.
 *
 * @param {string[]} gifts - La lista de regalos a filtrar.
 * @param {string} materials - Los materiales disponibles.
 * @return {string[]} La lista filtrada de regalos que pueden ser fabricados.
 */
function manufacture(gifts, materials) {
  // Usa filter para retornar solo los regalos que contengan todos los materiales
  return gifts.filter((gift) => {

    // Verifica si cada carácter en el regalo está en los materiales
    for (const char of gift) {

      // Si el carácter no está en los materiales, retorna false
      // false significa que el regalo no puede ser fabricado
      // esto detiene la revisión del resto de los caracteres para mejorar el rendimiento
      if (!materials.includes(char)) {
        return false;
      }
    }

    // Si todos los caracteres están en los materiales, retorna verdadero
    return true;
  });
}
```

### Regex

Consiste en crear una regex en base a `materials` que haga match con cualquier combinación (incluida la repetición) de los caracteres que estén dentro de `materials` y nada más.

<aside>
💡  ¿Quieres aprender a hacer regex cómo esta? ¡[regexlearn.com](https://regexlearn.com/es) es un excelente recurso para aprender!

</aside>

```jsx
/**
 * Filtra una lista de regalos basándose en los materiales disponibles.
 *
 * @param {string[]} gifts - La lista de regalos a filtrar.
 * @param {string} materials - Los materiales disponibles.
 * @return {string[]} La lista filtrada de regalos que pueden ser fabricados.
 */
function manufacture(gifts, materials) {
  const regex = new RegExp(`^[${materials}]*$`);
  return gifts.filter((gift) => regex.test(gift));
}
```

### Soluciones de la comunidad

Solución por [SantiMenendez19](https://github.com/SantiMenendez19/adventjs/blob/main/2023/challenge02/solution.js)

```jsx
function manufacture(gifts, materials) {
    return gifts.filter(gift => [...gift].every(c => materials.includes(c)))
}
```

Solución por [Savecoders](https://github.com/Savecoders/Solve-AdventJS/blob/main/Ad2023/Challenge02/main.js)

```jsx
function manufacture(gifts, material) {
  return gifts.filter((gift) =>
    gift.split("").every((matt) => material.includes(matt))
  );
}
```

Y ese ha sido el reto para el 2 de diciembre y sus soluciones. ¿Tienes otra solución alternativa? ¡Déjala en los comentarios!