AdjventJS 2023: Day 2 Challenge

AdjventJS 2023: Day 2 Challenge

Gifts and materials challenge!

·

3 min read

The solution to Challenge #2 of AdventJS 2023

Previous challenge: Day 1

Next Challenge: 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.

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.

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.

💡
Want to learn how to make regex like this? regexlearn.com is an excellent resource to learn!
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!