The solution to Challenge #2 of AdventJS 2023
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.
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:
Gifts (
gifts
): An array of strings, where each string represents a gift.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.
Iterating
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.
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
jsxCopy codefunction manufacture(gifts, materials) {
return gifts.filter(gift => [...gift].every(c => materials.includes(c)))
}
Solution by Savecoders
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!