The code below only executes through the first for loop once, yet all the other for loops perform as expected. Does anyone know why this is the case? I'm not sure how relevant the bulk of the (inefficient, poorly formatted) code within the loop is but I include it nonetheless.
var numbers = [9795526789839145, 2861747566959730, 4498854833783559, 6301982162016598, 1131197164065322];
for (i = 0; i < numbers.length; i++) {
var current = numbers[i];
var currentStr = current.toString();
var reverseStr = currentStr.split('').reverse().join('');
var reverseArr = [];
for (i = 0; i < reverseStr.length; i++) {
reverseArr.push(reverseStr[i]);
}
var A = 0;
for (i = 0; i < reverseArr.length; i += 2) {
A += Math.round((reverseArr[i]));
}
var evenDigits = [];
for (i = 1; i < reverseArr.length; i += 2) {
evenDigits.push(reverseArr[i]);
}
for (i = 0; i < evenDigits.length; i++) {
evenDigits[i] = evenDigits[i] * 2;
if (evenDigits[i] > 9) {
var temp = evenDigits[i].toString();
var firstInt = Math.round(temp[0]);
var secondInt = Math.round(temp[1]);
evenDigits[i] = firstInt + secondInt;
}
}
var B = 0;
for (i = 0; i < evenDigits.length; i++) {
B += evenDigits[i];
}
var sum = A + B;
if (sum % 10 == 0) {
console.log('Yes');
} else console.log('No');
}
In your code you are using same instance of 'i' variable to iterate all loops.
Solution is to use different index variables to iterate external and internal loops
var numbers = [9795526789839145, 2861747566959730, 4498854833783559, 6301982162016598, 1131197164065322];
var i = 0;
var j = 0;
for (j=0; j < numbers.length; j++) {
var current = numbers[j];
/...
}
JavaScript behaves like this because 'i' is not scoped to block (like in Java od C#). In ES2015 you can use let or const to bind variable to block scope (in this sample to for loop)
Related
This is my code:
// Population
var Gene = function(text){
if(text){
this.text = text;
}
};
Gene.fitness = 0;
Gene.generation = 0;
var word = new Gene('Hello');
// This is where it crashes!!
// Make elements
var genArr = [];
var population = 20;
var mutation = 0;
for(var i = 0; i < population; i++){
var gene = "";
var abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var j = 0; i < word.text.length; j++) {
var element = abc.charAt(Math.floor(Math.random() * abc.length));
gene += element;
}
genArr.push(gene);
}
// Divide them - fitness
// 1/20 - 0.05% each
var fitElements = [];
for (var i = 0; i < genArr.length; i++) {
var score = 0;
var curWord = Array.from(genArr[i]);
for (var j = 0; j < word.text.length; j++) {
if(genArr[j].substr(j, 1) == word.text.substr(j, 1)){
score += 1;
}
}
if(score > 0){
fitElements.push([genArr[i], (score * (1 / population)) ** 2]);
}
}
for (var i = 0; i < fitElements.length; i++) {
console.log('Element: ' + fitElements[i][0] + ', Score: ' + fitElements[i][1]);
}
My problem is that it crashes the page but doesn't gives errors. The idea is to create a simple word register in fitElements Array but I can't see what am I missing?
Thanks in advance.
In your code the nested for loop with variable j's end condition relies on i.
Take a the line:
// VVVV it relies on i instead of j
for (var j = 0; i < word.text.length; j++) {
var element = abc.charAt(Math.floor(Math.random() * abc.length));
gene += element;
}
The new code would look something like
for (var j = 0; j < word.text.length; j++)
var element = abc.charAt(Math.floor(Math.random() * abc.length));
gene += element;
}
The only difference in the entire sample is the i is changed to a j. Cheers!
I have written a function and called another function inside but my tests show that it is not time optimized. How can I make the following code faster?
function maxSum(arr, range) {
function sumAll(array1, myrange) {
var total = 0;
if (Array.isArray(myrange)) {
for (var i = myrange[0]; i <= myrange[1]; i++) {
total += array1[i];
}
return total;
} else return array1[myrange];
}
var mylist = [];
var l = range.length;
for (var n = 0; n < l; n++) {
mylist.push(sumAll(arr, range[n]));
}
return Math.max.apply(null, mylist);
}
Algorithmic optimization: create new array with cumulative sums from index 0 to every index
cumsum[0] = 0;
for (var i = 1; i <= arr.Length; i++) {
cumsum[i] = cumsum[i-1] + arr[i-1]
Now you don't need to calculate sums for every range - just get difference
sum for range (i..j) = cumsum[j+1] - cumsum[i];
in your terms:
function sumAll(array1, myrange) {
return cumsum[myrange[1]+1] - cumsum[myrange[0]];
}
example:
arr = [1,2,3,4]
cumsum = [0,1,3,6,10]
sum for range 1..2 = 6 - 1 = 5
P.S. If your array might be updated, consider Fenwick tree data structure
1) You can define the function sumAll outside of the function maxSum because every time you call maxSum the javascript engine is recreating a fresh new function sumAll.
2) You can define myrange[1] as a variable in the initialiser part to avoid javascript to look for myrange[1] at each iteration.
for (var i = myrange[0]; i <= myrange[1]; i++) {
total += array1[i];
}
become this:
for (var i = myrange[0], len = myrange[1]; i <= len; i++) {
total += array1[i];
}
Full working code based on #MBo's excellent optimization. This passes all the tests at https://www.codewars.com/kata/the-maximum-sum-value-of-ranges-challenge-version/train/javascript, which I gather is where this problem comes from.
function maxSum(arr, ranges) {
var max = null;
var sums = [];
var sofar = 0;
for (var i = 0; i <= arr.length; i++) {
sums[i] = sofar;
sofar += arr[i];
}
for (var i = 0; i < ranges.length; i++) {
var sum = sums[ranges[i][1]+1] - sums[ranges[i][0]];
if (max === null || sum > max) {
max = sum;
}
}
return max;
}
I have this so far, trying to get it to find the sum of each one of any number of inputted numbers with integers and "-"s.
When I run this,
var howM = prompt("How many cards?")
var arr = [];
for (var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
var sumpre = [];
for (var i = 0; i <= howM; i++) {
var sum = 0;
var eXt = arr[i];
eXt = eXt.replace(/-/g, "");
for (i = 0; i < eXt.length; i++) {
sum += parseInt(eXt.substr(i, 1));
}
sumpre.push(sum);
}
console.log(sumpre)
I have also tried
var howM = prompt("How many cards?")
var arr = [];
for (var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
for (var i = 0; i < howM; i++) {
var sum = 0;
var eXt = arr[i]
eXt = eXt.replace(/-/g, "");
for (i = 0; i < eXt.length; i++) {
sum += parseInt(eXt.substr(i, 1));
}
}
console.log(sum);
In both cases I get the sum for the first piece in the array and then undefined. How do I get it to run for each piece? I kind of have an idea of what is wrong with it I just don't quite know how to fix it.
You need to use a second counter for the nested for loop, like so:
var howM = prompt("How many cards?")
var arr = [];
for(var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
var sumpre = [];
for(var i = 0; i < howM; i++) {
var sum = 0;
var eXt = arr[i];
eXt = eXt.replace (/-/g, "");
for (var j = 0; j < eXt.length; j++) {
sum += parseInt(eXt.substr(j, 1));
}
sumpre.push(sum);
}
console.log(sumpre)
Your var sum = 0; inside your for-loop meaning sum variable will not be accessible outside of the loop
var howM = prompt("How many cards?")
var arr = [];
for(var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
for(var i = 0; i <= howM; i++)
var sum = 0;
var eXt = arr[i]
eXt = eXt.replace (/-/g, "");
for (i = 0; i < eXt.length; i++) {
sum += parseInt(eXt.substr(i, 1)); }
console.log(sum);
It tells me this "TypeError: Cannot read property 'replace' of undefined
at eval:13:11" which makes no sense to me because its right above it.
The intetended body of the loop for(var i = 0; i <= howM; i++) is not enclosed in braces {..}. As a result, only the statement var sum = 0; will be executed in the loop. Also, you probably meant to say i < howM. So you want something like this for the loop:
for(var i = 0; i < howM; i++) {
var sum = 0;
var eXt = arr[i]
eXt = eXt.replace (/-/g, "");
for (i = 0; i < eXt.length; i++) {
sum += parseInt(eXt.substr(i, 1));
}
}
console.log(sum);
Check the comments:
var howM = prompt("How many cards?")
var arr = [];
for(var i = 0; i < parseInt(howM); i++)
arr.push(prompt("Enter a card:")); //No curly braces is fine when its a single line. When there's no braces, JS just runs the next line x amount of times
console.log(arr)
var sum = 0; //Create sum out here. Setting it to zero every loop defeats the purpose
for(var i = 0; i < arr.length; i++)//You said "i <= howM". Better to use the length of the array that is being looped through
{ //Use curly braces to show what code to execute repeatedly
var eXt = arr[i]; //Set eXt to the current number
eXt = eXt.replace("-", ""); //No need for regex
sum += parseInt(eXt); //Convert the input to a number, then add it to sum
}
console.log(sum);
The second for loop doesn't have brackets around it. You can MUST use brackets UNLESS it is a one line loop. For example:
This is fine:
for (var i=0;i<100;i++)
console.log(i);
This is NOT:
for (var i=0;i<100;i++)
var x = i;
x++;
console.log(x);
So the second for loop should be this:
for(var i = 0; i <= howM; i++) {
var sum = 0;
var eXt = arr[i]
eXt = eXt.replace (/-/g, "");
for (i = 0; i < eXt.length; i++) {
sum += parseInt(eXt.substr(i, 1));
}
console.log(sum);
}
Also in the first for loop I would use arr[i] = value instead.
I'm playing around with online tests to improve my coding logic and I had a test where I needed to create a sample of a chessboard, where basically the input would be rows and columns of the chessboard, and then generate the output that was asked, but I'm not quite happy with my solution, I wonder if it is possible having the same output without having a temp variable, for example store the input values in a array and using some array functions that keeps looping inside giving me different values in the for loops. Here is my code:
/*
Sample output:
0101010
1010101
0101010
1010101
*/
function chess(m, n) { //7,4
var zero = 0;
var um = 1;
var temp = 0;
for (var i = 0; i < n; i++) {
for (var r = 0; r < m; r++) {
if (temp === 1) {
document.write(um);
temp = 0;
}
else {
document.write(zero);
temp = 1;
}
}
document.write("<br>");
}
}
chess(7, 4);
try
function chess(m,n){ //7,4
var zero = 0;
var um = 1;
var temp = 0;
for(var i = 0; i < n; i++){
for(var r = 0; r < m; r++){
if((i+r)%2 === 1){
document.write(um);
}else{
document.write(zero);
}
}
document.write("<br>");
}
}
chess(7,4);
You can directly compute and print. You do not need to store it in any variable.
function chess(m,n){ //7,4
for(var i = 0; i < n; i++){
for(var r = 0; r < m; r++){
document.write((i+r)%2);
}
document.write("<br>");
}
}
chess(7,4);