# AdjventJS 2023: Day 2 Challenge

The solution to [Challenge #2](https://adventjs.dev/challenges/2023/2) of [AdventJS 2023](https://adventjs.dev/)

[Previous challenge: Day 1](https://alexvalle.dev/adventjs-2023-day-1)

[Next Challenge: Day 3](https://alexvalle.dev/adventjs-2023-day-3)

## **Challenge Description**

In Santa's workshop, the elves have a **gift list** they wish to make and a limited set of materials.

*Gifts are strings of text* and *materials are characters*. Your task is to write a function that, given a list of gifts and the available materials, returns a **list of the gifts that can be made**.

A gift can be made if we have all the necessary materials to make it.

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

manufacture(gifts, materials) // ["tren", "oso"]

const gifts = ['juego', 'puzzle']
const materials = 'jlepuz'

manufacture(gifts, materials) // ["puzzle"]

const gifts = ['libro', 'ps5']
const materials = 'psli'

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

## **Analysis**

We have a string with certain letters that are the materials and an array of words that are the gifts. We must search for the words in which all their letters are found within the string materials.

**Inputs:**

1. **Gifts (**`gifts`): An array of strings, where each string represents a gift.
    
2. **Materials (**`materials`): A string representing the available materials.
    

**Output:**

* An array of gifts that can be made using the available materials.
    

**Considerations**

* Each character in a gift's string represents a necessary material.
    
* It is necessary to verify that all characters of a gift are present in the `materials` string.
    
* Each character in the materials string can be used multiple times, so there is no limit on materials.
    

## **Solution**

To solve this problem, I found two main approaches, iterating over the gifts and materials or using [regular expressions](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_expressions).

### **Iterating**

```javascript
jsxCopy code/**
 * Filters a list of gifts based on the available materials.
 *
 * @param {string[]} gifts - The list of gifts to filter.
 * @param {string} materials - The available materials.
 * @return {string[]} The filtered list of gifts that can be manufactured.
 */
function manufacture(gifts, materials) {
  // Use filter to return only the gifts that contain all the materials
  return gifts.filter((gift) => {

    // Check if each character in the gift is in the materials
    for (const char of gift) {

      // If the character is not in the materials, return false
      // false means that the gift cannot be manufactured
      // this stops checking the rest of the characters for better performance
      if (!materials.includes(char)) {
        return false;
      }
    }

    // If all the characters are in the materials, return true
    return true;
  });
}
```

### **Regex**

This involves creating a regex based on `materials` that match any combination (including repetition) of characters within `materials` and nothing else.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Want to learn how to make regex like this? <a target="_blank" rel="noopener noreferrer nofollow" href="https://regexlearn.com" style="pointer-events: none">regexlearn.com</a> is an excellent resource to learn!</div>
</div>

```javascript
jsxCopy code/**
 * Filters a list of gifts based on the available materials.
 *
 * @param {string[]} gifts - The list of gifts to filter.
 * @param {string} materials - The available materials.
 * @return {string[]} The filtered list of gifts that can be manufactured.
 */
function manufacture(gifts, materials) {
  const regex = new RegExp(`^[${materials}]+$`);
  return gifts.filter((gift) => regex.test(gift));
}
```

### **Community Solutions**

Solution by [SantiMenendez19](https://github.com/SantiMenendez19/adventjs/blob/main/2023/challenge02/solution.js)

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

Solution by [Savecoders](https://github.com/Savecoders/Solve-AdventJS/blob/main/Ad2023/Challenge02/main.js)

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

And that was the challenge for December 2nd and its solutions. Do you have another alternative solution? Leave it in the comments!
