Algorithm - Harmless Ransom Note

Problem :

You have been given two strings. You have to find out whether you can make up the first string with the words present in the second string.

Solution :

 function harmlessRansom(noteText, magazineText) {
	var noteArr = noteText.split(' ');
	var magazineArr = magazineText.split(' ');

	var magazineObj = {};

	magazineArr.forEach(word => {
		if(!magazineObj[word]) magazineObj[word] = 0;
		magazineObj[word]++;
	});
  var noteIsPossible = true;
	noteArr.forEach(word => {
		if(magazineObj[word]){
			magazineObj[word]--;
			if(magazineObj[word] < 0)
				noteIsPossible=false;
		}
		else
			noteIsPossible = false;
	});

return noteIsPossible;
}

var result = harmlessRansom('this is a secret note for you from a secret admirer', 'puerto rico is a place of great wonder and excitement it has many secret waterfall locatoins that i am an admirer of you must hike quite a distance to find the secret places as they are far from populated areas but it is worth the effort a tip i have for you is to go early in the morning when it is not so hot out also note that you must wear hiking boots this is one of the best places i have ever visited');
console.log(result);

Explanation

We will go through the solution line by line. We have to form the string present in the variable noteText from the words present in the string in the variable magazineText.

var noteArr = noteText.split(' ');
var magazineArr = magazineText.split(' ');

The above splits both the strings into array of individual words.

var magazineObj = {};

magazineArr.forEach(word => {
	if(!magazineObj[word]) magazineObj[word] = 0;
	magazineObj[word]++;
});

Then we declared an empty object called magazineObj which was used to store the number of times every word occured in magazineArr. We do this because it will help us later to count down the availability of a word if it is needed multiple times.

var noteIsPossible = true;
noteArr.forEach(word => {
	if(magazineObj[word]){
		magazineObj[word]--;
		if(magazineObj[word] < 0)
			noteIsPossible=false;
	}
	else
		noteIsPossible = false;
});
return noteIsPossible;

The variable noteIsPossible was used as a flag to check whether our forEach loop is run successfully to the end or not. The forEach loop above checks whether the word present in noteArr is also present in magazineObj, and if its present then it reduces the count of that particular word by 1. If the count at any point becomes less than 0, it returns a false. Otherwise it returns true. If the word is not found at all in the magazineObj the false is returned.