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
Related
This question already has answers here:
How do I extract even elements of an Array?
(8 answers)
How to do a script for odd and even numbers from 1 to 1000 in Javascript?
(8 answers)
Closed 2 years ago.
I've spent an embarrassing amount of time on this question only to realize my function is only right 50% of the time. So the goal here is to return only the odd numbers of all the numbers in between the two arguments. (for instance if the arguments are 1 and 5 i'd need to return 2 & 3) the function I wrote is completely dependent on the first argument. if it's even my function will return odds, but if the first number is odd it'll return evens. does anyone know how i can fix this?
function oddNumbers(l, r) {
const arr = [];
const theEvens = [];
for (let i= l; i<r; i++) {
arr.push(i)
}
console.log(arr)
for (let i= 0; i < arr.length; i+= 2 ) {
const evens = arr[0] + i;
theEvens.push(evens);
}
theEvens.forEach(item => arr.splice(arr.indexOf(item), 1));
console.log(arr)
}
oddNumbers(2, 20);
I modified the code a bit to return only odd numbers
We use the % operator that behaves like the remainder operator in math:
so when we say i % 2 if the number is even the result of the operation will be 0
but when the "i" is an odd number the result will be 1
so now we can filter the even from the odd numbers using this operation
function oddNumbers(l, r) {
const arr = [];
for (let i= l; i<r; i++) {
if(i % 2 !== 0) arr.push(i);
}
console.log(arr);
}
oddNumbers(2, 20);
You can loop from initial to end parameters and get odd numbers using modulo, try this:
let result = [];
let returnOdd = (n1, n2) => {
for(i = n1; i < n2; i++){
if(i % 2 != 0){
result.push(i)
}
}
return result;
}
console.log(returnOdd(2, 20));
You could use the filter method.
This method creates a new array based on the condition it has. In this case it will to go through all the numbers in the array, and check if the number is odd (though the remainder operator).
For example:
1 % 2 = 1 ( true, keep in the new array )
2 % 2 = 0 ( false ignore in the new array )
function OddNumbers(start, end) {
// Create an array from the given range
const nums = Array(end - start + 1).fill().map((_, idx) => start + idx);
// Use filter to return the odd numbers via the % operator
return nums.filter(num => num % 2);
}
console.log(OddNumbers(2,20))
I'm totally stuck at one excersise question. Can someone help me out with this question?
Create a function sumRangeNumbers() that returns the sum of all numbers
between two chosen numbers. The function should take two arguments, one
representing the lowest boundary and one that represents the highest
boundary. For example, the arguments 10 and 20 should return the sum of
10+11+12+13...+20.
for (var i = 0; i < 82; i++) {
document.write(i + i + '+');
}
How do I write the loop that sums all the numbers with an function?
The answer of DCR already provides a nice implementation and is probably what you were looking for. However, with a little mathematical knowledge you can make the function a little easier.
We know that the sum of 1 to n is n(n+1)/2 by looking at this wikipedia page.
The sum of a to b, is simply the sum of 1 to b minus the sum of 1 to a - 1 (we also want to include a itself).
The sum between a and b is then b(b + 1)/2 - (a - 1)(a)/2 and therefore your function becomes:
const a = 10
const b = 20
function sumRangeNumbers(a, b) {
const high = Math.max(a, b);
const low = Math.min(a, b);
return high * (high + 1) / 2 - (low - 1) * (low) / 2;
}
console.log(sumRangeNumbers(a, b)); // 165
console.log(sumRangeNumbers(b, a)); // 165
console.log(sumRangeNumbers(5, 7)); // 18
function sumRangeNumber (num1, num2) {
let total = 0
for (let i = num1; i <= num2; i++) {
total += i
}
return total
}
You are on the right track with a for loop. What we did here was in place of declaring i as zero we passed the low value and in the comparison we pass the high value. This creates the range ie 10-20. From there each loop we add I too total which is declared outside fo the loop so as to not have it reset and we add to it.
As a previous comment mentioned, this is kinda doing your HW for you, so give the above function a shot and play around with it and change things to make sure you understand whats happening.
you need to first create a function and then you need to call it.
function sum(x,y){
var sum = 0;
for(let i = x;i<=y;i++){
sum = sum + i;
}
console.log(sum)
}
sum(1,10);
const sumRange = (num1, num2) => (
min = Math.min(num1, num2),
Array(Math.abs(num1 - num2) + 1)
.fill().map((_, i) => i + min)
.reduce((sum, el) => sum + el, 0)
);
console.log(sumRange(20, 10));
console.log(sumRange(10, 20));
function sumRangeNumbers(lower, upper) {
let total = 0;
for (let index=lower; index<=upper; index++) {
total = total + index;
}
return total;
}
document.write(sumRangeNumbers(10,20));
Simple:
function sumRangeNumbers(from, to) {
let result = 0;
for (let i = from; i <= to; i++) {
result += i;
}
return result;
}
If the numbers belong to range of natural numbers, then why do you need a loop. Just use the fact that sum from low to high=
((high-low+1) * (low + high)) / 2
Give this a shot:
function getSum(x,y) {
sum += x
console.log(sum, x)
if (x == y) { return sum }
else { return getSum(x+1,y) }
}
sum = 0
Here's a simple example using your current attempt. Keep in mind, you'll want to some error handling for cases where they give you an invalid high/low number.
IE:
if (lowNum >= highNum) { console.error('invalid range'); }
and maybe this too
if (typeof lowNum !== 'number' && typeof highNum !== 'number') { console.error('Invalid inputs'); }
function sumUp(lowNum, highNum) {
if (lowNum >= highNum) { throw new Error('Invalid Range'); }
// Initialize total at 0
let total = 0;
// Loop through numbers between lowNum and highNum.
// Do not include lowNum and highNum in the addition
for (let i = lowNum + 1; i < highNum; i++) {
// Increment the total with the 'in-between number (i)'
total += i;
}
// Return the result
return total;
}
// Test 1 (should be 44)
console.log(2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, sumUp(1, 10));
// Test 2 (should be 315)
console.log(50 + 51 + 52 + 53 + 54 + 55, sumUp(49, 56));
// If you really want to do document.write
document.write(sumUp(49, 56));
// Test 3 (should fail)
console.log(sumUp(15, 3));
I was given a quiz and I had gotten the answer wrong and It's been bugging me ever since so I thought I'd ask for your thoughts
I needed to optimise the following function
function sumOfEvenNumbers(n) {
var sum = 0;
for(let i = 2; i < n;i++){
if(i % 2 == 0) sum += i;
}
return sum;
}
console.log(sumOfEvenNumbers(5));
I came up with
function sumOfEvenNumbers(n) {
var sum = 0;
while(--n >= 2) sum += n % 2 == 0? n : 0
return sum;
}
console.log(sumOfEvenNumbers(5));
What other ways were there?
It's a bit of a math question. The sum appears to be the sum of an arithmitic sequence with a common difference of 2. The sum is:
sum = N * (last + first) / 2;
where N is the number of the numbers in the sequence, last is the last number of those numbers, and first is the first.
Translated to javascript as:
function sumOfEvenNumbers(n) {
return Math.floor(n / 2) * (n - n % 2 + 2) / 2;
}
Because the number of even numbers between 2 and n is Math.floor(n / 2) and the last even number is n - n % 2 (7 would be 7 - 7 % 2 === 6 and 8 would be 8 - 8 % 2 === 8). and the first is 2.
Sum of n numbers:
var sum = (n * (n+1)) / 2;
Sum of n even numbers:
var m = Math.floor(n/2);
var sum = 2 * (m * (m+1) /2);
You can compute these sums using an arithmetic sum formula in constant time:
// Return sum of positive even numbers < n:
function sumOfEvenNumbers(n) {
n = (n - 1) >> 1;
return n * (n + 1);
}
// Example:
console.log(sumOfEvenNumbers(5));
Above computation avoids modulo and division operators which consume more CPU cycles than multiplication, addition and bit-shifting. Pay attention to the limited range of the bit-shifting operator >> though.
See e.g. http://oeis.org/A002378 for this and other formulas leading to the same result.
First thing is to eliminate the test in the loop:
function sumOfEvenNumbers(n) {
var sum = 0;
var halfN= Math.floor(n/2);
for(let i = 1; i < n/2;i++) {
sum += i;
}
return sum * 2;
}
Then we can observe that is just calculating the sum of all the integers less than a limit - and there is a formula for that (but actually formula is for less-equal a limit).
function sumOfEvenNumbers(n) {
var halfNm1= Math.floor(n/2)-1;
var sum = halfNm1 * (halfNm1+1) / 2;
return sum * 2;
}
And then eliminate the division and multiplication and the unnecessary addition and subtraction:
function sumOfEvenNumbers(n) {
var halfN= Math.floor(n/2);
return (halfN-1) * halfN;
}
Your solution computes in linear (O(N)) time.
If you use a mathematical solution, you can compute it in O(1) time:
function sum(n) {
let half = Math.ceil(n/2)
return half * (half + 1)
}
Because the question is tagged ecmascript-6 :)
const sumEven = x => [...Array(x + 1).keys()].reduce((a, b) => b % 2 === 0 ? a + b : a, 0);
// set max number
console.log(sumEven(10));
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;
}
I've been trying to write code that multiplies even indexed elements of an array by 2 and odd indexed elements by 3.
I have the following numbers stored in the variable number, which represents an array of numbers
numbers = [1,7,9,21,32,77];
Even Indexed Numbers - 1,9,32
Odd Indexed Numbers - 7, 21, 77
Please keep in mind that arrays are Zero Indexed, which means the numbering starts at 0. In which case, the 0-Indexed element is actually 1, and the 1-Indexed element is 7.
This is what I expected the output to be
[2,21,18,63,64,231]
Unfortunately, I got this output
[2,14,17,42,64,154]
Here is the code for my method
numbers = numbers.map(function(x) {
n = 0;
while (n < numbers.length) {
if (n % 2 == 0) {
return x * 2;
}
else {
return x * 3;
}
n++;
}});
return numbers;
Here I created a while loop, that executes code for every iteration of the variable n. For every value of the variable n, I'm checking if n is even, which is used by the code n % 2 == 0. While it's true that 0 % 2 == 0 it's not true that 1 % 2 == 0. I'm incrementing n at the end of the while loop, so I don't understand why I received the output I did.
Any help will be appreciated.
You created a global property called n, by doing
n = 0;
and then,
while (n < numbers.length) {
if (n % 2 == 0) {
return x * 2;
} else {
return x * 3;
}
}
n++; // Unreachable
you always return immediately. So the, n++ is never incremented. So, n remains 0 always and so all the elements are multiplied by 2 always.
The Array.prototype.map's callback function's, second parameter is the index itself. So, the correct way to use map is, like this
numbers.map(function(currentNumber, index) {
if (index % 2 === 0) {
return currentNumber * 2;
} else {
return currentNumber * 3;
}
});
The same can be written succinctly, with the ternary operator, like this
numbers.map(function(currentNumber, index) {
return currentNumber * (index % 2 === 0 ? 2 : 3);
});
To complement the other answer, the source of OP's confusion is on how "map" works. The map function is already called for each element - yet, OP attempted to use a while loop inside it, which is another way to iterate through each element. That is a double interaction, so, in essence, if OP's code worked, it would still be modifying each number n times! Usually, you just chose between a loop or map:
Using a loop:
var numbers = [1,7,9,21,32,77];
for (var i=0; i<numbers.length; ++i)
numbers[i] = i % 2 === 0 ? numbers[i] * 2 : numbers[i] * 3;
Using map:
var numbers = [1,7,9,21,32,77];
numbers.map(function(number, index){
return number * (index % 2 === 0 ? 2 : 3);
});
Or, very briefly:
[1,7,9,21,32,77].map(function(n,i){ return n * [2,3][i%2]; });
Basically you want to return a modified array that if the elements of the initial one is:
in even position, then multiply the element by 2.
in odd position, then multiply the element by 3.
You can use map with arrow functions and the conditional (ternary) operator to get this one-liner
console.log([1,7,9,21,32,77].map((num,ind) => num * (ind % 2 === 0 ? 2 : 3)));
This will output the desired
[2, 21, 18, 63, 64, 231]