How do I have multiple set timeouts running at once? - javascript

This is more of a question on how I should approach my problem, and not what code to use. this is the general framework/simplification of my code. I can provide the actual code if needed. question is below, it is similar to the last question I asked as it is part of the same system that isn't working:
for (i = 0; i < 10; i++) {
var amt = 0;
function checktime() {
console.log(amt + " / " + i);
amt++;
if (amt <= 5) {
setTimeout(checktime, 3000);
}
}
checktime();
}
I want it to have all the set timeouts running at once, for each i. the console results in
0 / 0
0 / 1
0 / 2
...
0 / 8
0 / 9
1 / 10
2 / 10
3 / 10
4 / 10
...
13 / 10
14 / 10
I'd like it to look like this:
0/0
0/1
0/2
0/3
...
0/9
1/0
1/1
...
5/9
5/10
sorry for the long question, but how would I go about doing this?

Have a function inside checktime that runs a loop. Set up your variables, and then pass the count variable into the inner function again with your setTimout.
function checktime() {
// Set the amt variable to zero
let amt = 0;
// Set count to zero if it doesn't exist
function loop(count = 0) {
// Log the new data
console.log(`${amt}/${count}`);
// Increase the count
++count;
// If count hits 10 reset the count
// and increase the amt variable
if (count === 10) {
count = 0;
++amt;
}
// Call the loop function again and pass in the new count
// as a parameter
setTimeout(loop, 1000, count);
}
loop();
}
checktime();

There are 2 ways you can do this.
Using nested loops like this
for(i = 0; i< 10; i++){
for(j = 0; j < 5; j++) {
console.log(i + " / " + j)
setTimeout(3000)
}
}
Using recursion like this:
function setTimeout_recurse(amt, i) {
if (amt < 5) {
console.log(i + " / " + amt)
amt ++;
setTimeout(3000)
setTimeout_recurse(amt, i)
}
}
for(i = 0; i< 10; i++){
var amt = 0;
setTimeout_recurse(amt, i);
}
You'll notice that the base is now i not amt which makes more sense to be the base.

Related

find sum of multiples 3 and 5, JS

I'm given a number and I need to find the sum of the multiples of 3 and 5 below the number.
For example:
20 => 78 = 3 + 5 + 6 + 9 + 10 + 12 + 15 + 18
My code works, but not for numbers greater than 1,000,000 (I tested it for 100,000 - it gives the result with 2sec delay). So, it should be optimized. Could someone help me? Why is my code slow? Thanks.
My logic is as follows:
add multiples to an array
filter duplicate values
sum all values
my code:
function sumOfMultiples(number) {
let numberBelow = number - 1;
let numberOfThrees = Math.floor(numberBelow / 3);
let numberOfFives = Math.floor(numberBelow / 5);
let multiples = [];
let multipleOfThree = 0;
let multipleOfFive = 0;
for (var i = 0; i < numberOfThrees; i++) {
multiples.push(multipleOfThree += 3);
}
for (var j = 0; j < numberOfFives; j++) {
multiples.push(multipleOfFive += 5);
}
return multiples
.filter((item, index) => multiples.indexOf(item) === index)
.reduce((a, b) => a + b);
}
You can also do this without using any loops.
For example if N is 1000, the sum of all multiples of 3 under 1000 is 3 + 6 + 9 ..... 999 => 3( 1 + 2 + 3 .... 333)
Similarly for 5, sum is 5(1 + 2 + 3 .... 200). But we have to subtract common multiples like 15, 30, 45 (multiples of 15)
And sum of first N natural numbers is N*(N+1)/2;
Putting all of this together
// Returns sum of first N natural numbers
const sumN = N => N*(N+1)/2;
// Returns number of multiples of a below N
const noOfMulitples = (N, a) => Math.floor((N-1)/a);
function sumOfMulitples(N) {
const n3 = noOfMulitples(N, 3); // Number of multiples of 3 under N
const n5 = noOfMulitples(N, 5); // Number of multiples of 5 under N
const n15 = noOfMulitples(N, 15); // Number of multiples of 3 & 5 under N
return 3*sumN(n3) + 5*sumN(n5) - 15*sumN(n15);
}
You can just run a loop from 1 to number, and use the modulo operator % to check if i divides 3 or 5:
function sumOfMultiples(number) {
var result = 0;
for (var i = 0; i < number; i++) {
if (i % 5 == 0 || i % 3 == 0) {
result += i;
}
}
return result;
}
console.log(sumOfMultiples(1000));
console.log(sumOfMultiples(100000));
console.log(sumOfMultiples(10000000));
You can do that just using a single loop.
function sumOfMultiples(number) {
let sum = 0;
for(let i = 1; i < number; i++){
if(i % 3 === 0 || i % 5 === 0){
sum += i;
}
}
return sum;
}
console.time('t');
console.log(sumOfMultiples(100000))
console.timeEnd('t')
You can do something like this
Set the difference equal to 5 - 3
Start loop with current as 0, keep looping until current is less than number,
Add 3 to current in every iteration,
Add difference to current and check if it is divisible by 5 only and less than number, than add it final result,
Add current to final result
function sumOfMultiples(number) {
let num = 0;
let difference = 5 - 3
let current = 0
while(current < number){
current += 3
let temp = current + difference
if((temp % 5 === 0) && (temp %3 !== 0) && temp < number ){
num += temp
}
difference += 2
if(current < number){
num += current
}
}
return num
}
console.log(sumOfMultiples(20))
console.log(sumOfMultiples(1000));
console.log(sumOfMultiples(100000));
console.log(sumOfMultiples(10000000));
you can do something like this
function multiplesOfFiveAndThree(){
let sum = 0;
for(let i = 1; i < 1000; i++) {
if (i % 3 === 0 || i % 5 === 0) sum += i;
}
return sum;
}
console.log(multiplesOfFiveAndThree());

How to work fix values being shifted over 1

I am working on a 'skill calculator' however i have ran into this problem. when putting 3 into the input field it displays the experience from 2... when putting
2 into the input field it's a null which is level 1... it's the same with all numbers up to 100 it displays the lower numbers experience 56 will display 55 experience.
function levelToExperience(goalLevel) {
var experience = 0;
for(var curLevel = 1 ; curLevel < goalLevel; curLevel += 1) {
experience = Math.floor(10 * Math.pow(curLevel, 3) - 10);
}
return Math.floor(experience);
}
// Convert experience to level
function experienceToLevel(goalExperience) {
var curExperience = 0;
for(var level = 1; level < 100; level += 1) {
curExperience += Math.floor(Math.floor(10 * Math.pow(level, 3)) - 10);
if(curExperience > goalExperience) {
break;
}
}
return level;
}
This calculation i am using 10L3 − 10 (L = level) level 2 = 70 exp so i can't understand why 2 is showing 0 and 3 is showing 2's experience.
for(var curLevel = 1 ; curLevel < goalLevel; curLevel += 1) {
The problem is this loop. When you pass 2 into it, you continue if curLevel is less than goalLevel, which is 2.
So you do Math.floor(10 * Math.pow(1, 3) - 10) which is 0.
Then curLevel is incremented, however, curlevel isn't less than 2, so you exit returning 0.
You don't have to loop, I think you just want to know how much experience to level to the goal.
function levelToExperience(goalLevel) {
return Math.floor(10 * Math.pow(goalLevel, 3) - 10);
}
Likewise, your experienceToLevel, can be greatly reduced if you take the Cube Root of the value:
function experienceToLevel(goalExperience) {
return Math.cbrt((goalExperience + 10)/10);
}

How to make a JS Counter & Reset?

I am trying to make a JS counter to reach a random number and reset it self once it reaches the number and repeat again in 5 seconds.
For example: Random Number is 0.05.
0.00 > 0.01 > 0.02 > 0.03 > 0.04 > 0.05 > 0.00
<div id="current">0</div>
JS
var randomNum = Math.random();
if ( current <= randomNum ) {
for (current = 0; current < randomNum; current+=0.01) {
setInterval(function(){
current += .01;
},1000); } }
else {
current = 0;
}
You could use a closure over the variables and make a check inside of the callback, if greater then the wanted result.
This proposal uses setInterval for counting and setTimeout for the waiting time of 5 sec and the restarting with a new random value.
function startInterval() {
var randomNum = Math.floor(Math.random() * 8) + 2,
current = 0,
interval = setInterval(function() {
current += .01;
if (current > randomNum / 100) {
current = 0;
clearInterval(interval);
setTimeout(startInterval, 5000);
}
document.getElementById('current').innerHTML = current.toFixed(2);
}, 1000);
}
startInterval();
<div id="current">0</div>
Keep a counter variable outside of the loop and then simply clear it, when the desired value is reached.
var randomNum = Math.random() * 25;
var currentValue = 0;
var counter;
counter = setInterval(function() {
if (currentValue < randomNum) {
//Carefull with "0.1" as JavaScript doesn't like it!
currentValue = (currentValue * 10 + 1) / 10
}
if (currentValue > randomNum) {
currentValue = randomNum;
clearInterval(counter);
}
console.log(currentValue, '/', randomNum)
}, 1000 / 60)

looping from 1 to 50 after the automatic pause for 30 seconds and further looping to 51 to 100 and so on

How do I submit looping from 1 to 10. And then pause for 10 seconds. And then looping from 11 to 20. And so on
Please help me.
Here is the solution for your question:
var count = 0;
function counter (count) {
if(count < 50) {
var limit = count + 10;
for(var i = count; i <= limit; i++) {
console.log(i);
this.count = i;
}
}
}
counter(count);
setInterval(function() {
counter(count);
}, 10000);
Have fun and try to write code by yourself.

repeating for loop in javascript

I want to count from 0 to 199 three times in a row in 10 millisecond steps like 0 1 2 ... 198 199 0 1 2 .... 198 199 0 1 2 .... The first run is working fine with:
function count() {
time = 0;
for (var i = 0; i < 200; i++) {
time += 10;
setTimeout(function(j) {
return function() {
console.log(j);
}
}(i), time);
};
};
count();
but i do not get the desired result when calling the function three times like
for (var i = 0; i < 3; i++) {
count();
}
What is the right way for me?
I suppose that should be timed too:
for (var i = 0; i < 3; i++) {
setTimeout(animateRio /*or do you mean count?*/, i*2000);
}
You don't need to schedule all of your own timeouts, setInterval can call a function every unit of time. So create an interval that will run every 10 milliseconds. Then add a loop counter and use some modulo arithmetic.
var time = -1,
interval,
loop = 3;
interval = setInterval(function() {
time += 1;
if(time % 200 === 0) {
loop--;
}
if(loop < 0){
clearInterval(interval);
return;
}
console.log(time % 200);
}, 10);
JSFiddle

Categories

Resources