Comparing variable to Math.max(...arr) not returning accurate answer - arrays

I'm trying to complete an easy LeetCode question: https://leetcode.com/problems/kids-with-the-greatest-number-of-candies/ but cannot figure out why my code is not working correctly. Here is the question and a correct solution:
Given the array candies and the integer extraCandies, where candies[i] represents the number of candies that the ith kid has.For each kid check if there is a way to distribute extraCandies among the kids such that he or she can have the greatest number of candies among them. Notice that multiple kids can have the greatest number of candies.
Input: candies = [2,3,5,1,3], extraCandies = 3
Output: [true,true,true,false,true]
Here is my current code:
var kidsWithCandies = function(candies, extraCandies) {
let newArr = [];
const max = Math.max(...candies)
for(i=0; i<candies.length; i++) {
let newVal = candies[i] + extraCandies
if (newVal >= max) {
newArr.push('true')
} else {
newArr.push('false')
}
}
return newArr
};
My code is returning [true,true,true,true,true] instead of [true,true,true,false,true].
I've used console.log() to check the values for 'max' and 'newVal' as the loop runs, and they are all correct, so there must be something wrong with my if statement, but I can't figure out what.
Thank you for your help!

You've answered your own question. Nonetheless, this'd also pass on LeetCode:
const kidsWithCandies = (candies, extraCandies) => {
let maxCandies = 0;
const greatest = [];
for (const candy of candies) {
(candy > maxCandies) && (maxCandies = candy);
}
for (let index = 0; index < candies.length; ++index) {
greatest.push(candies[index] + extraCandies >= maxCandies);
}
return greatest;
};

Related

Find all the anagrams of a word from a list

trying to solve a task from codewars:
Write a function that will find all the anagrams of a word from a list. You will be given two inputs a word and an array with words. You should return an array of all the anagrams or an empty array if there are none.
anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']) => ['aabb', 'bbaa']
Here's my solution:
function anagrams(str, arr) {
let newArr = [];
for(let i = 0; i < arr.length; i++) {
let result = str.split('').every(function(letter) {
return arr[i].indexOf(letter) != -1;
});
if(result === true) {
newArr.push(arr[i]);
}
}
return newArr;
}
Which is not working correctly: it displays ["aabb","abcd","bbaa"] when ['aabb', 'bbaa'] is required.
Thank you in advance.
I think you also need to manage the counts of letters. You get abcd in your output because abba is present in it according to this piece of code.
let result = str.split('').every(function(letter) {
return arr[i].indexOf(letter) != -1;
});
Although your function correctly checks that each letter of the word occurs in the potential anagram of it, it does not check that the number of duplicates of that letter is the same.
You could solve this by first determining the count of each distinct letter:
function getCounts(str) {
letterCount = {};
for (let letter of str) {
letterCount[letter] ??= 0;
letterCount[letter]++;
}
return letterCount;
}
function anagrams(str, arr) {
counts = getCounts(str);
return arr.filter(anagram =>
anagram.length === str.length &&
Object.entries(getCounts(anagram)).every(([letter, count]) =>
counts[letter] === count
)
);
}
console.log(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']));

I'm trying to randomize 5 selections from a list of people

This might be less difficult than I'm making it out to be, but I'm trying to make a Discord.JS bot command, that will take however many arguments I have. For example: !randomize 1,2,3,4,5,6,7,8,9,10
And the bot would respond with something like: "I have chosen: 4,2,7,3,9!" Any help?
Current attempt: Not exactly sure what I'm doing.
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}`
`bot.on('message', async msg => {
if(msg.content === "!add") {
//message.member.user.tag
var msgArray = msg.content.split(" ");
var args = msgArray.slice(1);
var user = args[1];
//if(!args[1]) return msg.channel.send("Please specify an argument!");
if(nameList.includes(user)) {
msg.reply("You're already on the list.")
} else {
nameList.push(args[1]);
msg.channel.send(`${args[1]} has been added to the list!\n Current List:` + nameList);
}
}
if(msg.content === "!bonus") {
if(nameList.length === 0) {
msg.reply("Either the list is empty, or I'm not in the mood!");
} else {
shuffleArray(nameList);
var chosenOne = nameList.pop();
nameList = [];
msg.reply(chosenOne + ' has been chosen! Good luck!');
}
}
if(msg.content === "!list") {
if(nameList.length === 0) {
msg.channel.send("Either the list is empty, or I'm not in the mood!");
} else {
msg.channel.send('The current list:' + nameList);
}
});```
Here's some simple steps to select 5 random elements from an array...
Construct an array of possible selections. In this example I've used names for the first 10 letters of the alphabet. In your code, it'll be the command arguments or predefined nameList.
Make a new array to hold the elements picked.
At some point before #3, you should check to make sure the pool the user has provided is large enough to make 5 selections (Array.length).
Use a for loop to execute the next code multiple times.
Generate a random number representing the index of a selected element (Math.random(), Math.floor()/double NOT bitwise operator).
Push the selection into the array.
Remove the chosen element from the original pool (Array.splice()).
Return the results.
const pool = ['Albert', 'Bob', 'Charlie', 'David', 'Edward', 'Francis', 'George', 'Horacio', 'Ivan', 'Jim'];
const selected = [];
for (let i = 0; i < 5; i++) {
const num = ~~(Math.random() * pool.length);
selected.push(pool[num]);
pool.splice(num, 1);
}
console.log(`I have chosen: ${selected.join(', ')}`);
Take this example and manipulate it within your code to suit your purpose.

es6 for loop not looping

I am trying to get a simple ES6 for-loop working but cant figure out why its not running.
I've copied an example from developer.mozilla docs and I've also tried it with the eslinter version which is below:
I have also added a let i = 0; above. All it renders/logs is i = 0 and wont increment.
the eslint version is here: eslint site
for (i = 0; i < 10; i += 1) {
console.log('i', i);
return <p>component {i}</p>;
}
Edit: ok got the values coming back in the log as i=0, i=1, etc... but to get them into a component each? i tried the push into array and mapping through to get the components out but i get no error and nothing appearing, even if i try just getting a value out.
const nbPageArray = [];
let i = 0;
for (i = 0; i < nbPages; i += 1) {
console.log('i', i);
nbPageArray.push(<p>component {i}</p>);
}
console.log('array', nbPageArray);
nbPageArray.map(a => <p>{a.type}</p>);
}
final working version:
const nbPageArray = [];
for (let i = 0; i < nbPages; i += 1) {
nbPageArray.push({ page: i + 1 });
}
return nbPageArray.map(a =>
<li className="page-item"><a className="page-link">{a.page}</a></li>,
);
Main issue is i += 10;
That should be 1 += 1;
And You should return array of elements :
var p_tags = [];
for (i = 0; i < 10; i += 1) {
console.log('i', i);
p_tags.push(<p>component {i}</p>);
}
return p_tags;
Edited question's answer :
First Error:
const nbPageArray = []; should be var nbPageArray = [];
Second You are not returning the array so change your code to this
return nbPageArray.map(a => <p>{a.type}</p>);
If you return from your for loop, you will exit the current function, you are also incrementing i by 10 each trip so you will exit the loop after one round either way.
If you are trying to print a string with the value of i ten times you could try using template string like so:
for (i = 0; i < 10; i += 1) {
console.log('i', i);
console.log(`<p>component ${i}</p>`);
}
you are returning from the loop and also incrementing by 10. The loop will execute only once.
As said in the comments, the return inside the for loop is going to exit from the function at the first iteration.
You can do something like this instead:
const result = Array(10).fill().map((_, i) =>
<p>component {i}</p>
);
Or
const result = [...Array(10)].map((_, i) =>
<p>component {i}</p>
);

Porting c code to actionscript 2

please look at the following link.
Permutation of String letters: How to remove repeated permutations?
I would like to port this to actionscript 2. Here is what i have so far:
var str:String = "AAC";
var arr:Array = str.split("");
permute(0,2);
function swap(i:Number, j:Number)
{
var temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function permute(i:Number, n:Number)
{
var k:Number;
if (i == n)
trace(arr);
else
{
for (k = i; k <= n; k++)
{
swap(i, k);
permute(i+1, n);
swap(i, k);
}
}
}
This is working fine to list all permutations with duplicates, but i would like to remove those and have unique values. So far i haven't managed to port the ticked solution from the above link. Thank You for your help.
Below are two versions, the first is for AS3, the second is for AS2. It is a slightly different algorithm (it is a bit less efficient then the one you have, but I think it will do as an illustration). It is essentially the same algorithmic complexity, so it's OK, the redundancy is in generating intermediate results (shorter arrays), which are later discarded (but you could modify it to reuse those arrays, if this concerns you).
AS3
private function permuteRecursively(input:Array,
hash:Object = null):Array
{
var first:String;
var oldResult:Array;
var newResult:Array;
var times:int;
var current:Array;
var test:String;
if (input.length > 1)
{
first = input.shift();
if (!hash) hash = { };
oldResult = this.permuteRecursively(input, hash);
newResult = [];
for each (var result:Array in oldResult)
{
times = result.length;
while (times >= 0)
{
current = result.concat();
if (times == result.length) current.push(first);
else current.splice(times, 0, first);
test = current.join("");
if (!(test in hash))
{
newResult.push(current);
hash[test] = 1;
}
times--;
}
}
}
else newResult = [input];
return newResult;
}
AS2:
private function permuteRecursively(input:Array,
hash:Object):Array
{
var first:String;
var oldResult:Array;
var newResult:Array;
var times:Number;
var current:Array;
var test:String;
var result:Array;
if (input.length > 1)
{
first = input.shift();
if (!hash) hash = { };
oldResult = this.permuteRecursively(input, hash);
newResult = [];
for (var i:Number = 0; i < oldResult.length; i++)
{
result = oldResult[i];
times = result.length;
while (times >= 0)
{
current = result.concat();
if (times == result.length) current.push(first);
else current.splice(times, 0, first);
test = current.join("");
if (!(test in hash))
{
newResult.push(current);
hash[test] = 1;
}
times--;
}
}
}
else newResult = [input];
return newResult;
}
EDIT:
Actually, now that I think of it, I'm not sure what kind of duplicates you were trying to avoid. The above code treats the permutations of AAC such as AAC and ACA as if they were distinct (even though A is "duplicated" in them), but AAC and AAC are considered the same (even though the first A and the second A may come from different sources in the original array).
If what you wanted to remove duplicated elements of generated arrays, then, obviously, the best strategy would be to remove them from the source first.

Difficulty returning an array of indexes of each element from an array that matches search term

Hi I am really struggling making code for a function that 'returns an array of indexes from an already populated array containing strings, when it matches the search term'.
So if the search term matches a word or characters in the element of the array regardless of its order, it should return the indexes in which those words are apparent in the array. Not using jquery grep feature.
Here is some code to illustrate what I mean.
array_test = ["Today was hot","Tomorrow will be hot aswell", "Yesterday the weather was not so good","o1234 t12345"]
function locateSearch(array_test,searchTerm){
var myArray = [];
for(i=0;i<array_test.length;i++){
if(...) // what should i be testing here, this is where i have been going wrong...
myArray[myArray.length] = i;
}
return myArray;
}
document.write(locateSearch,'ot') //this should return indexes [0,1,2,3]
Sorry If I have not explained this so well, appreciate your help. Thank you.
array_test = ["Today was hot","Tomorrow will be hot aswell", "Yesterday the weather was not so good","o1234 t12345"];
function locateSearch(array_test,searchTerm){
searchTerm = searchTerm.toLowerCase();
var myArray = [];
for(var i = 0; i < array_test.length; i++){
for(var j = 0; j < searchTerm.length; j++) {
if(array_test[i].toLowerCase().indexOf(searchTerm[j]) >= 0) {
myArray.push(i);
break;
}
}
}
return myArray;
}
alert(locateSearch(array_test, 'To').toString());
Also see this jsfiddle.
=== UPDATE ===
If every char has to be in the same string:
array_test = ["Today was hot","Tomorrow will be hot aswell", "Yesterday the weather was not so good","o1234 t12345"];
function locateSearch(array_test,searchTerm){
searchTerm = searchTerm.toLowerCase();
var myArray = [];
var bFound;
for(var i = 0; i < array_test.length; i++){
bFound = true;
for(var j = 0; j < searchTerm.length; j++) {
if(array_test[i].toLowerCase().indexOf(searchTerm[j]) == -1) {
bFound = false;
break;
}
}
if (bFound) {
myArray.push(i);
}
}
return myArray;
}
alert(locateSearch(array_test, 'es').toString());
Also see my updated jsfiddle.
if I understood your question correctly...
if(array_test[i].indexOf(searchTerm).toLowercase() != -1)
myArray.push(i);
You didn't mention if the search was case sensitive, but assuming it is I threw it in there
if you need your test to be case insensitive use the regEx match method instead of indexOf()
so... if(array[i].match(/searchTerm/i) != null){ myArray.push(i) }
Try this:
array_test = ["Today was hot","Tomorrow will be hot aswell", "Yesterday the weather was not so good","o1234 t12345"]
function locateSearch(array_test,searchTerm) {
var myArray = [];
for(i=0;i<array_test.length;i++) {
if(array_test[i].indexOf(searchTerm) != -1) // what should i be testing here, this is where i have been going wrong...
myArray.push(i);
}
return myArray;
}
document.write(locateSearch,'ot') //this should return indexes [0,1,2,3]
This will return indexes of all elements in array_test that contain the search term.

Resources