Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I need to calculate numbers between n and m, but something goes wrong and I don't know what..
function even(){
var n = document.getElementById("n").value;
var m = document.getElementById("m").value;
var s = 0 ;
if(n<m){
i = n;
while(i<=n){
n*(n+2)/4;
i++;
alert(n.value)
}
}else if(n>m);{
i=m;
S=n*(n+2)/4;
i++
alert(m.value)
}
}
<input type="text" id="n" > </br><br>
<input type="text" id="m" > </br><br>
<button onclick="even()">Click me !</button>
Unless you are specifically told to use a loop you should use the formula for sum of arithmetic progression.
function even() {
let n1 = Number(document.getElementById("n").value);
let n2 = Number(document.getElementById("m").value);
if (n1 > n2) [n1,n2] = [n2,n1];
n1 = 2*Math.ceil(n1/2);
n2 = 2*Math.floor(n2/2);
if (n1 > n2) return 0;
return (n1 + n2) * ((n2 - n1) / 2 + 1) / 2;
}
<input type="text" id="n" > <br><br>
<input type="text" id="m" > <br><br>
<button onclick="alert(even())">Click me !</button>
Even if you use a loop you should consider making number even first and then increment loop variable by 2 every time instead of checking parity on each iteration.
You were trying to calculate the sum, however, in your while loop, you were not adding it to the sum and trying to alert n.value or m.value which will be undefined here as there is no value property.
You can define a logic for the same (AP) rather than looping
function even(){
// convert the values to numbers otherwise it will be strings
var n = parseInt(document.getElementById("n").value);
var m = parseInt(document.getElementById("m").value);
if (n > m) [n, m] = [m, n]; // store smaller number in n
n = (n%2 === 0) ? n: n+1; // find the first even number
m = (m%2 === 0) ? m: m-1; // find the last even number
var s = 0; // initialize sum to 0
if(m >= n) {
var numbers = (m-n)/2 + 1; // number of even numbers in the range
/* Understanding the formula. It is a basic airthmetic series of n
* numbers, with first number being a, last number being l
* which is equal to (a + (n-1)d) where difference
* being d. The sum will be n/2(a+l) => n/2(a + a + (n-1)d)
* => n/2(2a + (n-1)d). With our d being 2, equation becomes
* n/2(2a +(n-1)2) => n(a + n -1). */
s = numbers*(n + numbers-1);
}
alert(s);
}
<input type="text" id="n" > </br><br>
<input type="text" id="m" > </br><br>
<button onclick="even()">Click me !</button>
Or you can update your code to following
function even(){
// convert the values to numbers otherwise it will be strings
var n = parseInt(document.getElementById("n").value);
var m = parseInt(document.getElementById("m").value);
var s = 0 ;
var i;
// Iterate over the numbers and check if it is divisible by 2 if yes then add it to the sum and finally alert the sum
if(n<m){
i = n;
while(i<=m){
if(i%2 === 0) s += i;
i++;
}
alert(s);
}else if(n>m) {
i=m;
while(i<=n){
if(i%2 === 0) s += i;
i++;
}
alert(s);
}
}
<input type="text" id="n" > </br><br>
<input type="text" id="m" > </br><br>
<button onclick="even()">Click me !</button>
To perform calculations only for even numbers, you need to find the remainder of the division. The remainder of the division must be zero
let a = 2;
let b = 10;
for(let i = a; i <= b; i++){
if (i%2 === 0){
// do something here even numbers
}
}
Try this:
if (n < m) {
for (let i = n; i <= m; i++) {
if (i%2 === 0)
s += i;
}
} else {
for (let i = m; i <= n; i++) {
if (i%2 === 0)
s += i;
}
}
The line if (s%2 === 0) is key to this because it will only add the numbers in the range which have a 0 remainder when divided by 2 (are even).
I've also converted the while loops you had into for loops because they are cleaner and easier to read.
You could also attempt to use ternary operators to quickly set-up lower and upper variables if you want to eliminate the need for the outer if-else statements.
I have taken the numbers as 10 and 3 and I am not considering both the numbers in loop because you have asked for sum of even numbers between these two.I have taken sum as 0.I have found the highest and lowest number using Ternary operator.using for loop i have found the Even integers and added them.
var x=10;
var y=3;
var higher=x>y?x:y;
var lower=x>y?y:x;
var sum=0;
for(var i=lower+1;i<higher;i++){
if(i%2==0){
sum+=i;
}
}
console.log("sum is"+sum)
Related
While I was solving a question saying "add odd numbers from 1 to 20", I coded this:
var i, sum=0;
for (i=2; i<=20; i*2){
sum=sum+i;
}
document.write(sum);
When I launched it through a browser, it did not work. However, when I fixed i*2 into i+=2, it worked.
What am I missing? Am I not able to use *(multiplier) in For Loops?
If you need to add odd numbers from 1 to 20, then you need i+=2 as the third parameter of the for and need to initialize the variable to 1 to get the correct result:
var sum = 0;
for (var i = 1; i <= 20; i += 2) {
sum += i;
}
When you have
i += 2
2 is added to i and the result is stored into i. When you tried
var i, sum=0;
for (i=2; i<=20; i*2){
sum=sum+i;
}
i*2 calculates the value which is twice as big as i, but it will not change the value of i, so this would "work" instead:
var i, sum=0;
for (i=2; i<=20; i*=2){
sum=sum+i;
}
where
i *= 2
not only calculates the value twice as big as i, but stores the result into i as well. However, even though this will run, the result will not be correct, since you are using the wrong formula.
Also, you can calculate the result without using a for:
1 + 2 + ... + n = n * (n + 1) / 2
Assuming that n is pair: and since we know that we are "missing" half the numbers and all the pair numbers are bigger exactly with 1 than the previous impair numbers, we can subtract half of the sequence
n * (n + 1) / 2 - n / 2 = (n * (n + 1) - n) / 2 = (n * (n + 1 - 1)) /
2 = n * n / 2
and now we have exactly the double value of what we need, so the final formula is:
sum = n * n / 4;
Let's make this a function
function getOddSumUpTo(limit) {
if (limit % 2) limit ++;
return limit * limit / 4;
}
and then:
var sum = getOddSumUpTo(20);
Note that we increment limit if it is odd.
The issue is that you're not updating the value of the i in the for loop.
I want add odd numbers from 1 to 20
Then you need to change the initial value of i to 1.
var i, sum = 0;
for (i = 1; i <= 20; i += 2){
sum += i;
}
document.write(sum);
Also, you can find the sum of odd numbers from 1 to 20 by using a formula.
n = 20;
console.log(n % 2 == 0 ? (n * n)/ 4 : ((n + 1) * (n + 1))/4);
You can you just have to do it simillary to what you've written about sum.
You used there i += 2 and not i + 2.
The same way just change i * 2 to i *= 2.
Here is an working example
var i, sum = 0;
for (i = 2; i <= 20; i *= 2) {
console.log(i);
sum += i;
}
document.write(sum);
But a couple of things here.
First of all you wrote
add odd numbers from 1 to 20
and in all your examples you use sum on even numbers.
Secondly, by multiplying you will not achieve your desired goal (as you can see in a snippet above in a console)
So to actually
add odd numbers from 1 to 20
you should do it like this:
var i, sum = 0;
for (i = 1; i <= 20; i += 2) {
console.log(i);
sum += i;
}
document.write(sum);
EDIT
If you want to add even numbers you still can't use multiplying.
Why? Simply because you said yourself that you want a sum of numbers.
So let's say that we start with 2.
If we multiply it by 2 it has the value 4 which is fine.
But now look what happens in the next iteration. Our variable i which has the value 4 is multiplied by 2 and now its new value is 8. So what about 6?
Next iteration multiply 8 by 2 and its new value is 16.
Do you see where this is going?
And when you use i += 2 instead of i *= 2?
So if we start with 2 and than we add 2 its new value is 4.
In next iteration we add 2 to 4 and we have 6.
And so on.
If you want to test it, here is an example with multiplying and adding.
Pay attention to console logs
var i;
console.log("Multiplying");
for (i = 2; i <= 20; i *= 2) {
console.log("i value is: " + i);
}
console.log("Adding");
for (i = 2; i <= 20; i += 2) {
console.log("i value is: " + i);
}
What you are looking is this :
let sum = 0;
for(var i = 2; i <= 20; i += 2){
sum += i;
}
document.write(sum)
Another take on this :
// set to n (what you want). Set to n + 1
var N = 21;
// The main driver code create an array from 0-(N-1) and removes all even nums
let a = Array.apply(null, {length: N}).map(Number.call, _ => +_).filter(_=>_%2)
// console.log the array
console.log(a)
You can use whatever expression in loop header, even this is a valid for loop statement for (;;) which simply runs forever (equivalent to while(true)).
Problem is that you are not updating the i counter in for (i=2; i<=20; i*2) so the i will stays the same throughout the execution of the loop.
If you change it to for (i=2; i<=20; i = i*2) or for (i=2; i<=20; i *=2) then it will work.
It is the same as if you did
let i = 1;
i * 2;
console.log(i);
i = i * 2;
console.log(i);
The first i * 2 doesn't update the i while the second one does.
You can also translate the for loop into while loop to see the error more clearly.
// wrong
let i = 1;
while(i <= 20) {
i * 2;
// do something
}
// right
let i = 1;
while(i <= 20) {
i = i * 2 // or i *= 2
// do something
}
Just a side note, if you wanted to perform sum on more types of sequences efficiently than you could use a generator based approach and write your sum function and describe each type of a sequence with a generator function.
function *generateOdd(start, end) {
for (let i = start; i <= end; i++) {
if (i % 2 === 1) { yield i; }
}
}
function *generateEven(start, end) {
for (let i = start; i <= end; i++) {
if (i % 2 === 0) { yield i; }
}
}
function sumNums(gen, start, end) {
const generator = gen(start, end);
let res = 0;
let item = generator.next();
while (!item.done) {
res += item.value;
item = generator.next();
}
return res;
}
console.log(sumNums(generateOdd, 0, 20));
console.log(sumNums(generateEven, 0, 20));
/* sum of the Odd number using loop */
function sumOfOddNumbers(n){
let sum= 0;
for(let i = 1; i <= n; i++) {
if(i % 2 !== 0){
sum = sum + i;
}
}
return sum;
}
// 567 = 1+3+5+7+9+11+13+15+17+19+21+23+25+27+29+31+33+35+37+39+41+43+45+47
let n = 47;
let sum = sumOfOddNumbers(47);
alert('sumOfOddNumbers(' + n + ') = ' + sum);
i'm doing some coding exercises and i'm not being able to solve this one.
Find the sum of all divisors of a given integer.
For n = 12, the input should be
sumOfDivisors(n) = 28.
example: 1 + 2 + 3 + 4 + 6 + 12 = 28.
Constraints:
1 ≤ n ≤ 15.
how can i solve this exercise? i'm not being able to.
function(n){
var arr = [],
finalSum;
if(n <= 1 || n => 16){
return false ;
}
for(var i = 0; i < n; i++){
var tmp= n/2;
arr.push(tmp)
// i need to keep on dividing n but i can't get the way of how to
}
return finalSum;
}
This is another way to do it:
var divisors = n=>[...Array(n+1).keys()].slice(1)
.reduce((s, a)=>s+(!(n % a) && a), 0);
console.log(divisors(12));
JSFiddle: https://jsfiddle.net/32n5jdnb/141/
Explaining:
n=> this is an arrow function, the equivalent to function(n) {. You don't need the () if there's only one parameter.
Array(n+1) creates an empty array of n+1 elements
.keys() gets the keys of the empty array (the indexes i.e. 0, 1, 2) so this is a way to create a numeric sequence
[...Array(n+1)].keys()] uses the spread (...) operator to transform the iterator in another array so creating an array with the numeric sequence
.slice(1) removes the first element thus creating a sequence starting with 1. Remember the n+1 ?
.reduce() is a method that iterates though each element and calculates a value in order to reduce the array to one value. It receives as parameter a callback function to calculate the value and the initial value of the calculation
(s, a)=> is the callback function for reduce. It's an arrow function equivalent to function(s, a) {
s+(!(n % a) && a) is the calculation of the value.
s+ s (for sum) or the last value calculated +
!(n % a) this returns true only for the elements that have a 0 as modular value.
(!(n % a) && a) is a js 'trick'. The case is that boolean expressions in javascript don't return true or false. They return a 'truthy' or 'falsy' value which is then converted to boolean. So the actual returned value is the right value for && (considering both have to be truthy) and the first thuthy value found for || (considering only one need to be truthy). So this basically means: if a is a modular value (i.e. != 0) return a to add to the sum, else return 0.
, 0 is the initial value for the reduce calculation.
Reduce documentation: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Edit
Answering to Tristan Forward:
var divisorsList = [];
var divisors = (n)=>[...Array(n+1).keys()].slice(1)
.reduce((s, a)=>{
var divisor = !(n % a) && a;
if (divisor) divisorsList.push(divisor);
return s+divisor;
}, 0);
console.log('Result:', divisors(12));
console.log('Divisors:', divisorsList);
You have to check if specified number is or not a divisor of given integer. You can use modulo % - if there's no rest, specified number is the divisor of the given integer - add it to the sum.
function sumDivisors(num){
var sum = 0;
for (var i = 1; i <= num; i++){
if (!(num % i)) {
sum += i;
}
}
console.log(sum);
}
sumDivisors(6);
sumDivisors(10);
Here is a solution with better algorithm performance (O(sqrt(largest prime factor of n)))
divisors = n => {
sum = 1
for (i = 2; n > 1; i++) {
i * i > n ? i = n : 0
b = 0
while (n % i < 1) {
c = sum * i
sum += c - b
b = c
n /= i
}
}
return sum
}
since n / i is also a devisor this can be done more efficiently.
function sumDivisors(num) {
let sum = 1;
for (let i = 2; i < num / i; i++) {
if (num % i === 0) {
sum += i + num / i;
}
}
const sqrt = Math.sqrt(num);
return num + (num % sqrt === 0 ? sum + sqrt : sum);
}
function countDivisors(n){
let counter = 1;
for(let i=1; i <= n/2; i++){
n % i === 0 ? counter++ : null;
}
return counter
}
in this case, we consider our counter as starting with 1 since by default all numbers are divisible by 1. Then we half the number since numbers that can be able to divide n are less or equal to half its value
I am newbie.
I want to make small app which will calculate the sum of all the digits of a number.
For example, if I have the number 2568, the app will calculate 2+5+6+8 which is equal with 21. Finally, it will calculate the sum of 21's digits and the final result will be 3 .
Please help me
Basically you have two methods to get the sum of all parts of an integer number.
With numerical operations
Take the number and build the remainder of ten and add that. Then take the integer part of the division of the number by 10. Proceed.
var value = 2568,
sum = 0;
while (value) {
sum += value % 10;
value = Math.floor(value / 10);
}
console.log(sum);
Use string operations
Convert the number to string, split the string and get an array with all digits and perform a reduce for every part and return the sum.
var value = 2568,
sum = value
.toString()
.split('')
.map(Number)
.reduce(function (a, b) {
return a + b;
}, 0);
console.log(sum);
For returning the value, you need to addres the value property.
rezultat.value = sum;
// ^^^^^^
function sumDigits() {
var value = document.getElementById("thenumber").value,
sum = 0;
while (value) {
sum += value % 10;
value = Math.floor(value / 10);
}
var rezultat = document.getElementById("result");
rezultat.value = sum;
}
<input type="text" placeholder="number" id="thenumber"/><br/><br/>
<button onclick="sumDigits()">Calculate</button><br/><br/>
<input type="text" readonly="true" placeholder="the result" id="result"/>
How about this simple approach using modulo 9 arithmetic?
function sumDigits(n) {
return (n - 1) % 9 + 1;
}
With mathy formula:
function sumDigits(n) {
return (--n % 9) + 1;
}
Without mathy formula:
function sumDigits(n) {
if (typeof n !== 'string') {
n = n.toString();
}
if (n.length < 2) {
return parseInt(n);
}
return sumDigits(
n.split('')
.reduce((acc, num) => acc += parseInt(num), 0)
);
}
let's try recursivity
function sumDigits(n) {
if (n < 10) return n
return sumDigits(n % 10 + sumDigits(Math.floor(n / 10)))
}
sumDigits(2) // 2
sumDigits(2568) // 3
The sum of digits can be calculated using that function (based on other answers):
function sumDigits(n) {
let sum = 0;
while (n) {
digit = n % 10;
sum += digit;
n = (n - digit) / 10;
}
return sum;
}
If you really need to sum the digits recursively there is recursive version of the function:
function sumDigitsRecursively(n) {
let sum = sumDigits(n);
if (sum < 10)
return sum;
else
return sumDigitsRecursively(sum);
}
The sumDigitsRecursively(2568) expression will be equal to 3. Because 2+5+6+8 = 21 and 2+1 = 3.
Note that recursive solution by #FedericoAntonucci should be more efficient, but it does not give you intermediate sum of digits if you need it.
You could do it this way.
function sums(input) {
let numArr = input.toString().split('');
let sum = numArr.reduce((a, b) => Number(a) + Number(b));
return sum < 10 ? sum : sums(sum);
}
Expanding upon #fethe 's answer, this sumOfDigit function is able to handle large number or BigInt
function sumOfDigits(n) {
return (Number.isSafeInteger(n)) ? (--n % 9) + 1 : Number((--n % 9n) + 1n);
}
console.log(sumOfDigits(101)); // 2
console.log(sumOfDigits(84932)); // 8
console.log(sumOfDigits(900000000000000000000000009n)); // 9
you can use this function and pass your number to it:
const solution = (n) => {
const arr = `${n}`
let sum = 0;
for (let index = 0; index < arr.length; index++) {
sum += parseInt(arr[index])
}
return sum;
}
Im a student currently studying from home and im seriously stuck on a Checksum problem. The script is supposed to validate the PESEL(Polish equivilant of a social security number i think), Anyway the checksum works as follows for
PESEL: 70051012347
PESEL:7,0,0,5,1,0,1,2,3,4 (7)
(Multiply each Pesel number by its corresponding check number)
CHECK:1,3,7,9,1,3,7,9,1,3
(Sum Each number)
SUM: + 7,0,0,45,1,0,7,18,3,12 =93
MOD: 93 MOD 10 = 3
10 - 3 = 7(last digit of pesel)
Where the MOD 10 doesn't equal 0, the result of sum%10 is subtracted from 10 and then matched with the final digit in the original number, if they match its good, if not its bad. All i need to have is a good or bad result.
I'm pretty sure I have all of this fine in my code and there's a simple solution i just cant see it. Any help at all would be massively appreciated.
<html>
<head>
<meta charset="utf-8">
<title>Pesel Checker</title>
<script type="text/javascript">
function peselgood(y)
{
//sample PESEL's
//type 1
//70051012347
//02070803628
//07020803628
//type 2
//83102570819
if (y.length == 11)
{
var arr = [1,3,7,9,1,3,7,9,1,3];
var sum = 0;
//hold original number
var a = parseInt(y);
//First 10 digits without check number and convert to array
y = y.substring(0,9);
y = parseInt(y);
var arr1 = new Array(10);
arr1 = y;
//muliply pesel digits by checksum digits
for (var i = 0; i < 10; i++)
{
sum += arr[i] * arr1[i];
}
sum = sum%10;
if (sum !== 0)
{
sum = 10-sum;
if(sum != a[10])
{
return false;
}
else
{
return true;
}
}
}
else
{
return false;
}
}
function checkpesel()
{
num = document.getElementById("peselfield").value
if (peselgood(num))
{
document.getElementById("peselfield").style.background="#00ff00";
}
else
{
document.getElementById("peselfield").style.background="#ff6666";
}
}
</script>
</head>
<body>
<div>
Check Sum Template
<br/><br/>
<form name="form">
PESEL:
<input type="text" id="peselfield" value="70051012347" /> <button type="button" onclick="checkpesel()">Check</button>
<br/><br/>
</form>
</div>
<br/><br/>
</body>
</html>
You have made a couple of mistakes. If you step through your code using a JavaScript debugger, you will find out exactly what goes wrong. The most important fact is, that you don't have to convert a string to an array of integers. JavaScript automatically understands when to convert a character to an integer.
This is my solution:
function peselgood(y)
{
if (y.length == 11)
{
var arr = [1,3,7,9,1,3,7,9,1,3];
var sum = 0;
//muliply pesel digits by checksum digits
for (var i = 0; i < 10; i++)
{
sum += arr[i] * y[i];
}
sum = sum%10 == 0 ? 0 : 10-sum%10;
return sum == y[10];
}
else
{
return false;
}
}
function checksum(p) { let i, s = +p[ i = 10 ]; while( i-- ) s += "1379"[ i % 4 ] * p[i]; return ! ( s % 10 ); }
<input id="pesel" placeholder="PESEL" autofocus>
<input type="button" value="check" onclick="alert( checksum(pesel.value) ? 'Ok' : 'Bad' )">
var1=anyInteger
var2=anyInteger
(Math.round(var1/var2)*var2)
What would be the syntax for JavaScripts bitshift alternative for the above?
Using integer not floating
Thank you
[UPDATED]
The quick answer:
var intResult = ((((var1 / var2) + 0.5) << 1) >> 1) * var2;
It's faster than the Math.round() method provided in the question and provides the exact same values.
Bit-shifting is between 10 and 20% faster from my tests. Below is some updated code that compares the two methods.
The code below has four parts: first, it creates 10,000 sets of two random integers; second, it does the round in the OP's question, stores the value for later comparison and logs the total time of execution; third, it does an equivalent bit-shift, stored the value for later comparison, and logs the execution time; fourth, it compares the Round and Bit-shift values to find any differences. It should report no anomalies.
Note that this should work for all positive, non-zero values. If the code encounters a zero for the denominator, it will raise and error, and I'm pretty sure that negative values will not bit-shift correctly, though I've not tested.
var arr1 = [],
arr2 = [],
arrFloorValues = [],
arrShiftValues = [],
intFloorTime = 0,
intShiftTime = 0,
mathround = Math.round, // #trinithis's excellent suggestion
i;
// Step one: create random values to compare
for (i = 0; i < 100000; i++) {
arr1.push(Math.round(Math.random() * 1000) + 1);
arr2.push(Math.round(Math.random() * 1000) + 1);
}
// Step two: test speed of Math.round()
var intStartTime = new Date().getTime();
for (i = 0; i < arr1.length; i++) {
arrFloorValues.push(mathround(arr1[i] / arr2[i]) * arr2[i]);
}
console.log("Math.floor(): " + (new Date().getTime() - intStartTime));
// Step three: test speed of bit shift
var intStartTime = new Date().getTime();
for (i = 0; i < arr1.length; i++) {
arrShiftValues.push( ( ( ( (arr1[i] / arr2[i]) + 0.5) << 1 ) >> 1 ) * arr2[i]);
}
console.log("Shifting: " + (new Date().getTime() - intStartTime));
// Step four: confirm that Math.round() and bit-shift produce same values
intMaxAsserts = 100;
for (i = 0; i < arr1.length; i++) {
if (arrShiftValues[i] !== arrFloorValues[i]) {
console.log("failed on",arr1[i],arr2[i],arrFloorValues[i],arrShiftValues[i])
if (intMaxAsserts-- < 0) break;
}
}
you should be able to round any number by adding 0.5 then shifting off the decimals...
var anyNum = 3.14;
var rounded = (anyNum + 0.5) | 0;
so the original expression could be solved using this (instead of the slower Math.round)
((var1/var2 + 0.5)|0) * var2
Run the code snippet below to test different values...
function updateAnswer() {
var A = document.getElementById('a').value;
var B = document.getElementById('b').value;
var h = "Math.round(A/B) * B = <b>" + (Math.round(A/B) * B) + "</b>";
h += "<br/>";
h += "((A/B + 0.5)|0) * B = <b>" + ((A/B + 0.5) | 0) * B +"</b>";
document.getElementById('ans').innerHTML = h;
}
*{font-family:courier}
A: <input id="a" value="42" />
<br/>
B: <input id="b" value="7" />
<br/><br/>
<button onclick="updateAnswer()">go</button>
<hr/>
<span id="ans"></span>
If var2 is a power of two (2^k) you may
write
(var1>>k)<<k
but in the general case
there is no straightforward solution.
You can do (var | 0) - that would truncate the number to an integer, but you'll always get the floor value. If you want to round it, you'll need an additional if statement, but in this case Math.round would be faster anyway.
Unfortunately, bit shifting operations usually only work with integers. Are your variables integers or floats?