increase value until limit then decrease loop - javascript
I try to increase the value of a variable valuem from 0 to 10 and if the value of valuem is 10 it should decrease until the value is 0, then again increase until 10 and so on.
for example: 0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1 0 1 2 ...
what is the simplest and efficientest way to do that?
var valuem = 0;
$('#number').text(valuem);
function count() {
valuem++;
$('#number').text(valuem);
if (valuem == 10) {
valuem--;
$('#number').text(valuem);
}
}
setInterval(count, 1000);
This way:
var valuem = 0, dir = 1;
$('#number').text(valuem);
function count() {
valuem += dir;
$('#number').text(valuem);
if (valuem < 1) dir = 1;
if (valuem > 9) dir = -1;
}
setInterval(count, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="number"></div>
You have to store the counting direction as the part of the state besides the current number to know in which direction to count when valuem is between 1 and 9.
I suppose one might simplify it more by just using the remainder with an offset. This way the entire calculation is done in a single line without any if statements.
var n = 0;
setInterval(function() {
number.innerHTML = 10 - Math.abs(n++ % 20 - 10);
}, 500);
<h1 id="number"></h1>
Related
JAVASCRIPT nested loops - triangle exercise from user input
I am trying to figure out a triangle excercise where the user inputs a number and the triangle is then created based on said number ex enter 5 This is what I want **5 6 6 7 7 7 8 8 8 8 9 9 9 9 9 10 10 10 10 10** Each line the number is increased by 1. I can't get my code to increase by 1. I keep getting 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 Anyone have any suggestions? Thanks let num = prompt("Enter a number"); //Check if its a number num = parseInt(num); //loop 1 for (i = 1; i <= 6; i++) { //loop 2 for (y = 0; y < i; y++) { document.write(num); } document.write(num = num +1; "<br>"); } <p id="num"> </p>
You just have to use the entered number as the loop upper limit: let num = prompt("Enter a number"); //Check if its a number num = parseInt(num); //loop 1 for (i = 1; i <= num; i++) { //loop 2 for (y = 0; y < i; y++) { document.write(num); } document.write("<br>"); }
This syntax is entirely invalid: document.write(num = num +1; "<br>"); You're somehow confusing calling a function with defining a for loop. Those are two entirely different things. Don't randomly try to munge together separate operations. Put each operation on its own line of code. The two operations you want to perform are: Add 1 to num Output a <br> element These are separate operations. So separate them: num = num +1; document.write("<br>");
You don't seem to be placing the incrementation of your num before writing it to the document. See the code below check the line between loops. let num = prompt("Enter a number"); //Check if its a number num = parseInt(num); //loop 1 for (let i = 1; i <= 6; i++) { //loop 2 num++; for (let y = 0; y < i; y++) { document.write(num); } document.write("<br>"); } <p id="num"> </p>;
Count Down Random Numbers to 0 within given time
I'm creating a countdown, which i need to count down it to 0 but in random numbers. Ex- countdown from 4 minutes by second by second, but i need to show a value between 300 to 390 countdown to 0 with random numbers within above 4 minutes period. I created random number count down, but still cannot able to figure out how to target that become 0 within given time. <script> var count = 350; //this is a random value between(300-390) var timer = setInterval(function() { //this will generate number between 0 to 10 and reduce it from count randimly count -= Math.floor(Math.random()*9); //set it to html element jQuery('#maindvpart').html(count); //when number become 0 if( count <= 0) { jQuery('#maindvpart').html(0); count = 0; clearInterval(timer); } //but i need to run this countdown within 4 minutes //(so when 0 minutes ends above count should zero, until 0 it should count down from random number) },1000); </script> <div id="maindvpart"> </div> anyone have idea or example how to do this, thank you
Your "timer" runs each second. When you do "count -= Math.floor(Math.random()*9);", it reduces "count" variable value much faster, so you will always reach "count <= 0" much faster than 4 minutes. If you want to run your timer for 4 minutes, you need to run your timer per second - 240 times, and "display a random number", but do not subtract that random number from count. Does this help? Editing with an example, hoping it would point you towards your goal: <script> var count = 240; //4 minutes var displayNumber = 350; //or whatever number you want to start with var timer = setInterval(function() { //this will generate number between 0 to 10 and reduce it from displayNumber randomly displayNumber -= Math.floor(Math.random()*9); count--; console.log(displayNumber); // exit if either the display number is <= 0 or the time is up if( displayNumber <= 0 || count <= 0) { console.log(0); displayNumber = 0; clearInterval(timer); } },1000); </script>
Solution 1: simply modify the time interval after which the random number is reduced by unit step (ie:1) to indicate the time step necessary for the random number to equal 0 when the time is up . the equation would be : {delay before subtracting 1 from rand# (in sec) = time elapsed till rand# reaches 0 (in sec)/rand#} ex: 1) rand# = 300 , needed to count down till reaches 0 in 2 minutes (120sec) , then 300 needs to count down by 1 each 120/300 sec var count = 300 // your randomly generated number; var time = 60 //time elapsed before the random number to equal 0; var timer = setInterval(function() { count = count -1; console.log(count); if( count <= 0) { count = 0; clearInterval(timer); } },(time/count)*1000); Solution 2: modify the unit step by which the random number is decreased every second till it reaches 0 after the specified time is elapsed . the equation would be : {random # decrement step = rand#/time elapsed till rand# reaches 0 (in sec)} ex: 1) rand# = 300 , needed to count down till reaches 0 in 1 minute (60sec) , then 300 needs to count down by 300/60 each 1 sec var count = 300 // your randomly generated number; var time = 20 //time elapsed before the random number to equal 0; var decrementStep=count/time; var timer = setInterval(function() { count = count - decrementStep; console.log(count); if( count <= 0) { count = 0; clearInterval(timer); } },1000);
JavaScript - Project Euler #5 -- efficiency
This is for Project Euler, problem #5. The task is to find the smallest number evenly divisible by numbers 1-20. My code seems to work on 1-18, but at 19 my browser starts timing out. This leads me to believe my code is just inefficient. How can I mitigate this? function divisible(a){ counter = 0; result = 2; while (counter < a){ for (var x = 0; x <= a; x ++){ if (result % x === 0){ counter ++; } } if (counter != a){ counter = 0; result ++; } } return result; } divisible(20)
Basically, you want the least common multiple of 1,...,20. I would implement lcm by using gcd, which can be implemented using the fast Euclidean algorithm. function gcd(a, b) { return b === 0 ? a : gcd(b, a%b); // Euclidean algorithm } function lcm(a, b) { return a * b / gcd(a, b); } function divisible(a){ var result = 1; for(var i=2; i<=a; ++i) result = lcm(result, i); return result; } divisible(20); // 232792560
Yup, inefficient. You would need to change the algorithm. The most efficient I can think of is to factorise all the numbers from 2 to 20 (with factors and counts: e.g. 18 is 3 * 3 * 2, or twice 3 and once 2, for final { 3: 2, 2: 1 }); then find the maximum for each factor, and multiply them together. An abbreviated example: the least number that is divisible by 18 and 16: 18: { 3: 2, 2: 1 } 16: { 2: 4 } maximums of factor repetitions: { 3: 2, 2: 4 } result: 3^2 * 2^4 = 144 Factorising numbers from 2 to 20 is easy; if you don't know how to do it, there are many possible algorithms, you can see the Wikipedia article on integer factorisation for ideas.
another option with brute force and modulo rest-classification this problem can be solved with a simple common modulo rest class characteristics. look at the numbers from 1 to 20 and divide it into two groups and find some unique common attributes between them. 1 2 3 4 5 6 7 8 9 10 we are building a division with the same reminder members 1 divides all 2 divide 4,8 -->>8 important 3 divide 6,9 but 6 doesnt divide 9 evenly--> 6,9 5 divide 10-->> 10 important that leaves us with 6,7,8,9,10 to check if there is any number from 1 that can divide this with rest 0. the trick is if 2,4,8 divides a number let say 16 with the same reminder then we don't have to check if 2,4 divides 16, we check only 8. 11 12 13 14 15 16 17 18 19 20 here we can do the same from about with factors of the numbers from above and we will be left with 11 12 13 14 15 16 17 18 19 20 NB: we know that the last number that has to divide the number is 20, so that means either the solution will be a number ending with 0 or is one of the factors of 20, so we build factors of 20 and check if 11 12 13 14 15 16 17 18 19 can divide it then we are done. int start = 20; while (start % 11 != 0 || start % 12 != 0 | start % 13 != 0 || start % 14 != 0 || start % 15 != 0 || start % 16 != 0 || start % 17 != 0 || start % 18 != 0 || start % 19 != 0 ) { start += 20; } console.log(start) The same idea applies analogue to the first deduction I made to make the problem seems smaller. //smallest number divisible by all numbers from 1 to 10 int a = 10; while (a % 6 != 0 || a % 7 != 0 | a % 8 != 0 || a % 9 != 0 ) { a += 10; } console.log(a) //smallest number divisible by all numbers from 1 to 5 int i = 5; while (i % 3 != 0 || i % 4 != 0) { i += 5; } console.log(i)
Javascript random min max doesn't work
I am trying to make a simple program for a tabletop game that calculates damage. So I want to use random between two integers with a couple of percentage stuff to calculate damage. The problem is random doesn't work for me. It doesn't matter what numbers I set as min or max, it always starts from 0 to the number before max. <script> function showDiv() { var armor = document.getElementById('armortype').value; var damage = document.getElementById('dmgtype').value; var min = document.getElementById('mindmg').value; var max = document.getElementById('maxdmg').value; document.getElementById('result').style.display = "block"; for (var i=0;i<100;i++) { var dmg_done = Math.floor(Math.random()*max+min+1); document.getElementById('test').innerHTML += " " + dmg_done; } } </script> So for min = 3, max = 6 I get the following 100 numbers: 3 1 2 2 0 2 2 1 2 2 3 3 4 0 1 1 2 2 5 2 3 5 3 3 3 4 0 0 5 2 3 0 4 0 2 1 0 5 4 1 0 5 5 4 2 1 2 4 5 1 5 1 0 4 3 5 2 1 4 3 1 1 5 1 4 2 1 0 3 3 3 4 3 4 5 4 2 0 2 4 5 0 3 1 2 5 0 1 5 1 2 2 1 4 0 0 0 1 4 2 So it doesn't matter that min is 3, it randomizes from 0 and there is not even a single 6 in the result.
Demo: http://jsfiddle.net/zprr6/ You want to utilize it as such: var dmg_done = Math.floor(Math.random() * (max - min + 1) + min); The reason it starts at 0, is because the Math.random function produces a float from 0-1 (as many JS functions and features do). So, by telling it to start at max - min + 1, ie 4, it avoids using the 0 as a starting value.
Try replacing Math.floor(Math.random()*max+min+1) with Math.floor(Math.random() * (max - min + 1) + min)
So why don't you try calculating random like this function getRandom (min, max) { return Math.random() * (max - min + 1) + min; } Edit: to add to the comment var valOne = $("#input-1").val(), valTwo = $("#input-2").val(); $("#button").click(function() { $("#answer-input").val(getRandom(parseInt(valOne), parseInt(valTwo))); );
Found the problem. both min and max were used as strings, not numbers. So I just parsed them as ints like this: var min = parseInt(document.getElementById('mindmg').value); var max = parseInt(document.getElementById('maxdmg').value); and it works flawlessly now
Try Math.floor((Math.random() * (max+1-min))+min); max+1 - so that the maximum is include, and +min so that the min is respected Test case var max = 6; var min = 3; var result = ""; for(var i=0;i<100;i++) { result += Math.floor((Math.random()*(max+1-min))+min) +","; } console.log(result); results (5 runs) 3,4,5,6,6,4,5,6,3,5,5,3,5,5,6,6,5,4,5,5,4,5,6,6,6,5,6,3,4,3,5,3,6,6,6,3,6,3,5,6,5,4,6,6,6,5,5,4,3,5,6,6,3,6,6,3,6,5,6,5,6,5,3,3,5,6,6,4,5,5,4,3,5,4,4,4,3,5,4,5,5,3,3,4,4,6,3,3,3,4,4,3,6,3,4,4,3,3,4,6, 6,5,4,3,6,4,4,6,4,4,5,5,3,4,6,4,4,3,4,6,6,5,3,6,4,5,4,6,5,4,4,3,5,6,4,3,5,5,3,5,4,3,6,4,3,3,3,4,6,5,6,3,5,5,6,6,6,5,5,6,5,6,5,4,5,4,4,5,3,6,3,3,6,5,6,3,5,3,6,3,5,6,3,4,5,4,3,5,3,5,3,5,3,5,3,5,3,5,5,6, 3,3,6,5,5,3,3,4,3,5,6,4,3,3,6,3,6,6,3,4,5,5,5,4,4,6,6,3,3,3,5,4,4,3,6,6,5,5,5,4,4,4,5,3,6,3,5,4,5,6,3,6,5,3,3,4,5,4,6,3,4,6,3,6,3,4,6,5,3,6,3,5,6,5,6,4,5,4,3,6,4,4,3,4,6,3,5,5,3,6,6,6,5,6,6,4,3,6,3,4, 4,4,3,6,4,6,4,3,5,4,5,3,4,5,6,6,6,3,4,4,4,4,4,4,5,6,4,4,6,6,5,5,5,3,6,3,5,4,6,5,5,4,5,4,5,4,3,3,5,4,6,5,5,4,4,6,6,6,3,4,6,6,3,6,5,5,4,6,6,4,3,4,6,3,5,6,4,3,5,6,3,4,3,6,6,6,6,3,3,4,4,4,6,6,4,3,6,5,4,3, 4,5,3,6,3,4,5,4,4,5,5,3,3,6,6,4,6,4,5,5,3,5,5,5,3,6,3,5,4,5,5,6,6,4,4,5,3,3,4,5,5,5,4,6,5,4,5,4,5,6,6,3,3,3,4,3,4,6,5,3,5,5,3,3,5,6,3,5,6,3,6,3,5,5,5,6,3,6,4,3,4,5,5,3,6,6,6,6,4,5,6,5,3,4,4,3,4,6,3,6, On an additional note, getting the value of a textbox always returns a string, so the following (min and max) are both strings var min = document.getElementById('mindmg').value; var max = document.getElementById('maxdmg').value; I would check that they are actually numbers, and cast them, before using them in the Math, something like var min = +(document.getElementById('mindmg').value); var max = +(document.getElementById('maxdmg').value); putting the + at the front will casue a number cast IF IT CAN, if it can't, it will be NaN (Not a Number), so before you use, check that they are not NaN. Nan can easily be checked, as nothing equala Nan not even Nan so something like if(min === min && max === max) { //... all good to use con.. } will check that they are actually numbers as Nan will never equal NaN but 3 will always equal 3
Understanding the modulus operator
I have some code that loops through a collection of list elements and a collection of colours. It makes sure each list element is designated to a colour. I understand everything about this apart from the modulus operator. I get that it finds and uses the remaining number, but I cannot for the life of me understand what it is doing here? var li = document.getElementsByTagName('li'); var colors = ["salmon", "teal", "orange", "grey", "blue"]; var colorsCount = colors.length; for ( var i = 0; i < li.length; i++ ) { li[i].style.backgroundColor = colors[ i % colorsCount ]; // why does this work? }
Since there is (potentially) a larger number of items in the li array, this prevents i from being outside the bounds of the colors array, since i % colorsCount can never be over colorsCount. For example, if we had 10 elements in li, and 5 colors, i % colorsCount would be: i i % colorsCount Color ------------------------------- 0 0 salmon 1 1 teal 2 2 orange 3 3 grey 4 4 blue 5 0 salmon 6 1 teal 7 2 orange 8 3 grey 9 4 blue More Information on Modulo Operations.
i % colorsCount will set the bound of the index to be between 0 and colorsCount-1, thus ensuring you never index past the end of the array. Since mod is the remainder, the remainder can never be greater than the divisor (which in this case, is the length of the array).
Perhaps this snippet may help you understand: var s = '' for (var i = 0; i < 20; i ++) { s += (i % 5) + ', ' } console.log(s) The result is: 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, Note how the number resets to 0 every time it reaches 5. The % colors.length just makes sure the index never goes above the array's length. A more descriptive way of understanding: 0 % 5: 0/5 = 0, remainder 0 1 % 5: 1/5 = 1/5, remainder 1 ... 5 % 5: 5/5 = 1, remainder 0 6 % 5: 6/5 = 1 1/5, remainder 1 7 % 5: 7/5 = 1 2/5, remainder 2 ...
It's cycling your colours. Because you only have a limited number of colours, and any number of possible list items, it makes sure that i will not overflow the bounds of your colors array.
The modulus operator returns the remainder of division. It allows you to loop through and reuse the colors array even though there are potentially less colors in the array than there are elements in your list to color. If length is say 8, 5 % 1 == (5 / 1) = 0 remainder 1 5 % 2 == (5 / 2) = 0 remainder 2 5 % 3 == (5 / 3) = 0 remainder 3 5 % 4 == (5 / 4) = 0 remainder 4 5 % 5 == (5 / 5) = 1 remainder 0 5 % 6 == (5 / 6) = 1 remainder 1 5 % 8 == (5 / 7) = 1 remainder 2 5 % 7 == (5 / 8) = 1 remainder 3 As you can see, the remainders are what's returned by the mod operator, and they're always less than the length of the colors array.
why does i % colorsCount work? What it does This code cycles through colors. It does so using the modulus operator to ensure you're always within the bounds of the array. How it does it Modulus operation finds the remainder of division of one number by another. In your case by taking i modulus the colorsCount: 0 % 5; // 0 1 % 5; // 1 1 % 5; // 2 3 % 5; // 3 4 % 5; // 4 5 % 5; // 0 8 % 5; // 3
The result of a modulus operation is the remainder after division of the left operand by the right operand. So the line of code in question will always return some number between 0 and colorsCount-1.
You iterate from 0 until how many li elements you have. For this example, say 10. You then look at the colors array and find the element for that iteration (i) and modulus by how many items are in the colors array. In short, this is what's happening: var colorsCount = 10; 1 % 10 = 1 // ... Access colors[1]; (teal) 2 % 10 = 2 // .... Access colors[2]; (orange) 3 % 10 = 3 // .... Access colors[3]; (grey) 4 % 10 = 4 // .... Access colors[4]; (blue) 5 % 10 = 5 // .... Access colors[5]; etc If you are wondering why it will never access an element outside of the array, the answer is because as i becomes greater, the result becomes smaller. For example, take iteration 8: 8 % 5 = 3 (Iteration 8, 5 elements in the array) Therefore you are accessing colors[3];