Comparing 2 arrays to output total integer - javascript

I have 2 arrays of numbers. I want to go through each array and find the number of times 1 number from each array adds up to the particular amount x.
If the particular amount x is reached as many times as another set number n then the function should print 'YES'. If x does not reach the set number of n then the function should print 'NO'.
The values of x , n and both arrays are in a string input. These values have been split into arrays as seen below in the code.
I have set up 2 for loops to run through each array and an if statement that checks for the condition of x meeting n.
The arrays I'm using in this code should print out the result of 'YES' however every time I run the code I'm getting 'NO' ? I've tried tinkering with the code but nothing has worked.
Any idea on where this code is broke and how to fix the problem?
Thanks :)
code:
var input = '2\n3 10\n2 1 3\n7 8 9';
function processData(input) {
var inputArray = input.split('\n');
var n = inputArray[1][0];
var x = inputArray[1].split(' ')[1];
var arrayA = inputArray[2].split(' ');
var arrayB = inputArray[3].split(' ');
var total = 0;
for(var i = 0; i < arrayA.length; i++) {
for(var j = 0; j < arrayB.length; j++) {
if(arrayA[i] + arrayB[j] == x) {
total = total + 1;
} if (total == n) {
return 'YES';
}
}
}
return 'NO';
}
console.log(processData(input));

arrayA[i] and arrayB[j] are strings, so arrayA[i] + arrayB[j] will be the concatenation of them (ex: '2' + '3' === '23').
If your logic is correct (i didn't quite understand what you are trying to do), it should be enough to convert them to numbers before adding them, using parseInt or some other method:
if(+arrayA[i] + (+arrayB[j]) == +x) { // used unary + to convert to number
total = total + 1;
} if (total == n) {
return 'YES';
}
PS: A cleaner version would be to convert each string in the array to number, but that involves more than adding 3 characters to your code.
PS2: You have a weird way of getting the input data. If you get it from another place in your JS code, you could simply pass it as an object with the relevant structure, otherwise you could pass it around in a more ... common format, like JSON.

Related

How to add sum of currency values of an array in javascript

how to add currency values of an array like this
array = [ '$0',
'$0',
'$14,792',
'$152,445',
'$1,581,033',
'$2,988,978',
'$4,226,419',
'$7,254,960',
'$10,726,945',
'$12,657,402',
'$35,215,787',
'$37,968,368',
'$7,648,445',
'$364,237',
'$390,395',
'$306,080',
'$3,641,253',
'$4,328,363',
'$1,360,664' ]
here is my method defined, the only problem i am facing is in the second for array_sum is not adding the values that i am getting from data variable.
exports.GetMonthsFWSeasonFullSeasonValues = () => {
var promises = [];
var array_sum = 0;
for(var month_index = 9; month_index <= 27 ; month_index++){
const elm_xpath = utils.GetXpathForSubCategory(chosen_season_index, month_index);
promises.push(element(by.xpath(elm_xpath)).getText());
}
return Promise.all(promises).then(function(data){
if(data != null) {
for (var array_index = 0; array_index < data.length; array_index++){
array_sum += data[array_index];
console.log('sum of values from months',array_sum);
}
} else {
return null;
}
});
};
The problem here is that you are trying to add two strings. The + operator is overloaded in JS, so with numbers it adds them, but with strings it concatenates them. You need to convert them to ints or floats by using parseInt or parseFloat, and get rid of the commas and $ signs out of it, something like:
var num = '$1,100'
parseInt(num.replace(/[$,]/g, ''))
Which would give 1100 if you printed it. After they are in number format, you can sum them.
Or if you have the choice to store the numbers in your array as numbers, without the string formatting to start off with, go with that. So much easier.

Combine an array with other arrays, push each combination Javascript

I'm trying to take an array, and compare each value of that array to the next value in the array. When I run my code, components that should match with more than one array only return one match, instead of all of them. I'm probably doing something wrong somewhere, but for the life of my I don't seem to be able to figure it out.
This is my code:
INPUT
minterms = [["4",[0,1,0,0]],
["8",[1,0,0,0]],
["9",[1,0,0,1]],
["10",[1,0,1,0]],
["12",[1,1,0,0]],
["11",[1,0,1,1]],
["14",[1,1,1,0]],
["15",[1,1,1,1]]];
Function
function combineMinterms(minterms) {
var match = 0;
var count;
var loc;
var newMin = [];
var newMiny = [];
var used = new Array(minterms.length);
//First Component
for (x = 0; x < minterms.length; x++) {
if(minterms[x][1][minterms[x][1].length - 1] == "*") {
newMin.push(minterms[x].slice());
continue;
};
//Second Component
for (y = x + 1; y < minterms.length; y++) {
count = 0;
//Compare each value
for (h = 0; h < minterms[x][1].length; h++) {
if (minterms[x][1][h] != minterms[y][1][h]) {
count++;
loc = h;
}
if (count >= 2) {break; };
}
//If only one difference, push to new
if (count === 1) {
newMin.push(minterms[x].slice());
newMiny = minterms[y].slice();
newMin[match][1][loc] = "-";
while(newMin[match][0].charAt(0) === 'd') {
newMin[match][0] = newMin[match][0].substr(1);
}
while(newMiny[0].charAt(0) === 'd') {
newMiny[0] = newMiny[0].substr(1);
}
newMin[match][0] += "," + newMiny[0];
used[x] = 1;
used[y] = 1;
match++;
continue;
}
}
//If never used, push to new
if(used[x] != 1) {
newMin.push(minterms[x].slice());
newMin[match][1].push("*");
match++;
}
}
return newMin;
}
Desired Output
newMin = [["4,12",[-,1,0,0]],
["8,9",[1,0,0,-]],
["8,10",[1,0,-,0]],
["8,12",[1,-,0,0]],
["9,11",[1,0,-,1]],
["10,11",[1,0,1,-]],
["10,14",[1,-,1,0]],
["12,14",[1,1,-,0]],
["11,15",[1,-,1,1]],
["14,15",[1,1,1,-]]];
It will combine term 8, with 9 but won't continue to combine term 8 with 10, 12
Thanks in advance for the help.
Array.prototype.slice performs a shallow copy.
Each entry in minterms is an array of a string and a nested array.
When you slice the entry, you get a new array with a copy of the string and a copy of the Array object reference. But that copy of the Array reference still points to the array contained in an element of minterms.
When you update the nested array
newMin[match][1][loc] = "-";
you are updating the nested array within the input. I never fathomed the logic of what you are doing, but I believe this is the problem, with solution of cloning the nested array (as well) when cloning an input array element.
A secondary issue you will probably wish to fix is that not all variables were declared: var x,y,h; or equivalent inline declarations are missing.
let minterms = [4,8,9,10,12,11,14,15];
let newMin = [];
minterms.map((value, index) =>{
minterms.reduce((accumulator, currentValue, currentIndex, array) => {
accumulator = value;
let out = (accumulator ^ currentValue).toString(2);
if(out.split('').filter(n=>n==="1").length == 1) newMin.push([value, currentValue]);
}, value);
});
console.log(newMin);
There is a better approach (in 10 lines of code). Since you're working with binary representations, you might want to consider using BitWise operators. When coupled with array operators it makes most of this straight forward.
For instance:
Given a match means only a single bit differs between two binary numbers:
The bitwise XOR operator returns 1 for each bit that doesn't match. So:
0100 XOR 1000 results in 1000
Now, we need to count the number of '1' digits in the binary number returned. We can use the length property of an array to do this. To turn 1000 into an array, first we turn the binary into a string:
The binary representation of the integer 4 is easily retrieved with:
num.toString(2)
So if num === 4, the output above is the string "0100".
Now we use str.split() to turn the string into an array. Remove everything from the array that is not a '1'. Now simply get the length property. If the length === 1, it is a match.
I put together a solution like this for you. It is close to your use case. I didn't use the funny dash style in the output because that was not part of your question.
https://jsbin.com/xezuwax/edit?js,console

JavaScript to check which one of the given numbers differs from other

I am stuck on a problem. I want to print the index of an array which differs from other elements of that array in evenness. To be more specific the input would be like 5 even numbers and 1 odd number. So print the position(index+1) of odd number.
My code
function Test(numbers){
var e = 0; //number of even numbers
var o = 0; //number of odd numbers
console.log(numbers.length);
for(var i = 0; i < numbers.length; i++){
if(numbers[i] % 2 == 0){
e++;
var pose = i; //index of even no
}
else{
o++
var poso = i; //index of odd number
}
}
if(e==1){ //only one even number
console.log(pose+1);
}
else if(o==1){ //only one odd number
console.log(poso+1);
}
else{
console.log("no number differs");
}
}
Test("2 4 7 8 6");
Expected output = '3';
The console prints :
"no number differs".
I have debugged and I found the problem. The console.log(numbers.length); is printing 9. That is it is including blank spaces as well. Same if we put comma ',' in between the numbers. Also if there is a two digit number it treats them as 2 separate elements.
Now I know that i can add code at the beginning to check if i=1,3,5... to break the loop but I would like to know if there is a better solution. Also if the solution is passing array in different format I would like to know how can we correct the code if we want to pass as above.
Pass an array as an argument like below.
function Test(numbers){
var e = 0; //number of even numbers
var o = 0; //number of odd numbers
console.log(numbers.length);
for(var i = 0; i < numbers.length; i++){
if(numbers[i] % 2 == 0){
e++;
var pose = i; //index of even no
}
else{
o++
var poso = i; //index of odd number
}
}
if(e==1){ //only one even number
console.log(pose+1);
}
else if(o==1){ //only one odd number
console.log(poso+1);
}
else{
console.log("no number differs");
}
}
var x = [2,4,7,8,6];
Test(x);
Your Program is absolutely fine.
I guess the problem is with how you are passing data to your function Test.
You are passing a string instead of array.
it should be like:
Test([2,4,7,8,6]);
Also If you want to pass it as string just make sure you split the String with ',' comma and make an array of the numbers and then feed it to your for loop.
In your code you are passing the argument as a string, but I guess you may need to pass an array.
If it is so then you can look into array#forEach method
Hope this snippet will be useful
function Test(numbers) {
// looping through the array
numbers.forEach(function(item, index) {
//checking if it is odd or even
if (item % 2 == 0) {
console.log("current number is Even & its index is " + index);
} else {
//updating index
var modIndex = index+1;
console.log("current number is Odd & its modified index is " + modIndex);
}
})
}
var num = ['2','4','7','8','6']
Test(num);
DEMO

Sorting odd and even numbers with the remainder operator Javascript

If a number, when divided by two, has a remainder that is not equal to 0, this number must be odd. I'm trying to use that logic in my if statement to keep only odd values, and get rid of even ones. I'm not sure how I'm doing this wrong, but myArray is returning even values as well as odd. Any ideas?
function sumFibs(num) {
var myArray = [1,1];
// Create fibonacci sequence
// Stop creating fibonacci numbers at num
// Push odd numbers to oddNums array
for (var i = 0; i < myArray.length; i++) {
if (myArray[i+1] + myArray[i] <= num && myArray[i+1] + myArray[i] % 2 !== 0) {
myArray.push(myArray[i+1] + myArray[i]);
}
} // End loop.
console.log(myArray);
// Summation of oddNums array.
return myArray.reduce(function(a,b) {
return a + b;
});
} // End function.
sumFibs(1000);
You are trying to filter odd values while generating your fib sequence, which probably not the best approach. If you wrap the modulo expression in parentheses,
(myArray[i+1] + myArray[i]) % 2
Your array will not contain the values necessary to continue generating the sequence. Ideally you should generate the full fib series and then filter:
var myArray = [1,1];
for (var i = 0; i <= num; i++) {
myArray.push(myArray[i+1] + myArray[i]);
} // End loop.
myArray = myArray.filter(function(a){ return a%2 !== 0 })
or save some reference to the even values so that they can be used to calculate the desired subset of the series.

Project Euler -- Largest palindrome product

There seems to be a problem with this code as in it doesn't check for the largest palindrome. I mixed it with the example they showed of largest palindrome from two digit numbers (The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99) and it worked. I've looked around, but I still don't understand exactly why my code doesn't show the final product. If someone is willing to explain instead of just giving the answer, that would be quite helpful
for(var i = 100; i < 1000; i++) {
for(var j = 100; j < 1000; j++) {
var total = String(i*j);
var regularI = total.substring(0, Math.floor(total.length/2));
var regularJ = total.substring(total.length/2,total.length);
var reversedJ = regularJ.split("").reverse().join("");
if(regularI === reversedJ) {
console.log("SUCCESS\nTotal: " + (i*j) + "\nI: " + i + "\nJ: " + j);
}
}
}
993 * 913 = 906609
995 * 583 = 580085
Suppose the first number in the multiplication corresponds to i, and the second to j. In your nested for-loop with i and j, the result of the former multiplication will be output before the latter. You can see this if you look at the end of your code's output. Therefore, the final success that is output is not guaranteed to be the largest palindrome. It's possible that the largest palindrome appears earlier in your output.
One straightforward method of fixing this problem is to keep a list of palindromes you've found in an array. After the nested for-loop completes, you can sort the array by number value and get the largest number by looking at the last position:
var palindromes = [];
for(var i = 100; i < 1000; i++) {
for(var j = 100; j < 1000; j++) {
var total = String(i*j);
var regularI = total.substring(0, Math.floor(total.length/2));
var regularJ = total.substring(total.length/2,total.length);
var reversedJ = regularJ.split("").reverse().join("");
if(regularI === reversedJ) {
palindromes.push(Number(total));
}
}
}
// sorts the array in-place
// "default sort order is according to string Unicode code points" - Mozilla docs
// so we'll need to pass in a comparison function.
palindromes.sort(function(a, b) {
return a - b;
});
console.log(palindromes[palindromes.length-1]);
If you do this, you'll see that the largest palindrome is indeed 906609, a number that appeared third-to-last (and once more, earlier) in your nested for-loop.
Another way of solving this would be to dedicate a variable, say maxSoFar, to keeping track of the highest palindrome value you've seen.
There are other ways of solving this problem, but I'll leave that up to you to discover.

Categories

Resources