Creating a For loop to find sum of proper divisors - javascript

I have this problem for my CIS class: "Write a function named sumOfProperDivisors that accepts an integer n > 1, and returns the sum of the proper divisors of n.(A proper divisor is a positive divisor of a number, excluding the number itself. For example, 1, 2, and 3 are proper divisors of 6, but 6 itself is not.) Use a for loop, and use function expression syntax."
I don't even know where to start. This is all I have so far and I'm pretty sure it's completely wrong. PLEASE I NEED HELP
var sumOfProperDivisors = function(n > 1) {
let sum = 0;
for (var i = 1; i <= n; i++)

// we don't have to search all numbers from 2 to the integer part of n / 2,
// but from 2 to the integer part of the square root of n
// if n = 1000 we look for divisors in the interval [2, 31] and not in [2, 500]
const sumOfProperDivisors = n => {
const root = Math.sqrt(n);
let result = 1 + Number.isInteger(root) * root;
for (let k = 2; k < root; k++) {
if (n % k === 0) result += k + n / k;
}
return result;
}
console.log(sumOfProperDivisors(6));
console.log(sumOfProperDivisors(1000));
console.log(sumOfProperDivisors(1000000));

Welcome to Stack Overflow
Read about asking homework questions - How do I ask and answer homework questions?
Also, read about asking a good question - https://stackoverflow.com/help/how-to-ask
The answer:
You can do it like this:
loop over from i = 1 to i = n/2 because once it cannot be divisible by something greater and n/2 and n.
if the modulo (remainder) of n / i is zero then increment sum
return sum
function sumOfProperDivisors(n) {
let sum = 0;
for (var i = 1; i <= n/2; i++){
if (n % i == 0){
sum++;
}
}
return sum;
}
console.log(sumOfProperDivisors(6))

The laziest way to do this is loop through all the numbers before n, 1 to n-1
and check if the modulo of n with the number gives 0 that means n is divisible by that number then add that number to a variable "sum" each time the condition applies.
You can alter some details like looping from 1 to n/2 to remove unnecessary numbers.

When you define a function, what goes in the parenthesis is the name of the argument, possibly with a default argument value, but the > 1 syntax you're using is not valid.
So, instead of:
function (n>1) {...}
You would need to do something like:
function (n) {
if (n <= 1) {
// ... throw an error or something...
// or maybe you don't need to bother with this?
// it's not super clear to me from the assignment
}
The other thing I would point you to in order to answer your question is the modulo operator, which is the percent sign (%) in javascript. That operator will return the remainder of a division operator, so if you want to check if a number is divisible by another number, you can check if the remainder is 0 in this way...
if (3 % 2 === 0) { console.log('3 is divisible by 2')}
if (4 % 2 === 0) { console.log('4 is divisible by 2')}
if (5 % 2 === 0) { console.log('5 is divisible by 2')}
One final note: it's nice to write a bunch of tests for yourself to see how your function works and see if you understand it. So if I got this problem as homework, the first thing I might do is write a bunch of statements to test out my answer and see how they work...
For example:
console.log('sumOfProperDivisors(4) should be 3... and it is ',sumOfProperDivisors(4))
console.log('sumOfProperDivisors(5) should be 1... and it is ',sumOfProperDivisors(5))
console.log('sumOfProperDivisors(6) should be 6... and it is ',sumOfProperDivisors(6))
console.log('sumOfProperDivisors(8) should be 7... and it is ',sumOfProperDivisors(8))

function findProperDivisor(num) {
if(num<0) return
let sum = 0;
for (let i = 0; i < Math.floor(num / 2); i++) {
if (num % i === 0) {
sum += i;
}
}
return sum
}

Related

Recursion counter doesn't work in codewars kata

Currently trying to complete the persistent bugger kata in code wars.
I need to return the number of times the input has to be multiplied until it is reduced to a single number (full task instructions below).
Everything appears to work apart from the count. when I console log, the number of times it logs and runs is correct, but instead of incrementing such as 1,2,3 it will be something like 2,2,4.
So instead of returning 3, it returns 4.
I try to not ask for help with katas, but this time I am completely at a loss as to why the count is firstly skipping numbers and also not incrementing.
Task:
Write a function, persistence, that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.
For example:
persistence(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence(999) === 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence(4) === 0 // because 4 is already a one-digit number
My function:
function persistence(num) {
//console.log('here', num)
if(num < 10) return 0;
if(num === 25) return 2
let spl = num.toString().split('');
let result = 1;
let count = 1;
spl.forEach((s) => {
let int = parseInt(s)
result *= int;
//count++;
})
//console.log(result)
if(result > 9) {
persistence(result)
count++;
}
// console.log('count-->', count)
return count;
}
A sub issue is that the input 25 always returns a count 1 less than it should. My fix is poor I know, again any advice would be much appreciated.
Spoiler alert: this contains a solution. If you don't want that, stop before the end.
You don't really want to work with count, since as people point out, it's a local variable. You also don't work too hard to special case the result if it's a single digit. Let the recursion handle it.
Thus:
function persistence(num) {
//console.log('here', num)
if(num < 10) return 0;
//still here, must be 2 or more digits
let spl = num.toString().split('');
let result = 1;
spl.forEach((s) => {
let int = parseInt(s)
result *= int;
})
//console.log(result)
return 1 + persistence(result)
}
As you already have a complete solution posted here with fixes to your implementation, I will offer what I think is a simpler version. If we had a function to create the digit product for us, then persistence could be this simple recursion:
const persistence = (n) =>
n < 10 ? 0 : 1 + persistence (digProduct (n))
You already have code for the digit product, and while it's fine, a mathematical approach, rather than a string-base one, is somewhat cleaner. We could write it -- also recursively -- like
const digProduct = (n) =>
n < 10 ? n : (n % 10) * digProduct (Math .floor (n / 10))
or instead we might choose (n / 10) | 0 in place of the floor call. Either is reasonable.
Putting it together, we have:
const digProduct = (n) =>
n < 10 ? n : (n % 10) * digProduct ((n / 10) | 0)
const persistence = (n) =>
n < 10 ? 0 : 1 + persistence (digProduct (n))
const tests = [39, 999, 4, 25]
tests.forEach (n => console.log (`${n} --> ${persistence(n)}`))

Transform this iteration function to recursive

This is a function to display the sum of the input digits with iteration perspective:
function sumOfDigits(number) {
let strNumber = number.toString()
let output = 0;
for(i=0;i<strNumber.length;i++){
let tmp = parseInt(strNumber[i])
output = output + tmp
}
return output
}
// TEST CASES
console.log(sumOfDigits(512)); // 8
console.log(sumOfDigits(1542)); // 12
console.log(sumOfDigits(5)); // 5
console.log(sumOfDigits(21)); // 3
console.log(sumOfDigits(11111)); // 5
I am wondering how we write this function in a recursive way?
Using the modulo operator, you can get the remainder (which in the case of a divison by 10, is the last number) and then add the next iteration.
function sumOfDigits (n) {
if (n === 0) return 0
return (n % 10 + sumOfDigits(Math.floor(n / 10)))
}
console.log(sumOfDigits(512))
If you want to see a more detailed explanation, check https://www.geeksforgeeks.org/sum-digit-number-using-recursion/
I have not tested it, but you can try the following without casting to string
function sumOfDigits(number)
{
if (number === 0) {
return 0;
}
return (number % 10 + sumOfDigits(Math.floor(number / 10)));
}
Make sure that the input is indeed in number format
Here you go
function sumOfDigitsRecursive(number){
let strNumber = number.toString()
if(strNumber.length<=0)
return 0
return parseInt(strNumber[0])+sumOfDigitsRecursive(strNumber.slice(1,strNumber.length))
}

Prime number factorization

I'm trying to write a function to take a positive integer and a prime number as an input and return true if the prime factors of the given positive integer are less than or equal the given prime number.
Given prime number should be a prime factor of the given positive integer.
hasLessPrimeFactor(20,5) should return true because Prime Factors of a Number: 20 = 2 X 2 X 5
Up to now I have completed 3 test cases out of 4 test cases
The return type should be a string.
hasLessPrimeFactor(20,5) should return true
hasLessPrimeFactor(20,7) should return false
The answer should be valid for any given input.(above mentioned not passed test case)
What I've done so far :
function hasLessPrimeFactor(num,primenum){
let arr = [];
if(num < 2 || primenum < 2 || isNaN(num) ||isNaN(primenum)){
return 0;
}
for (i = 2; i <= num; i++) {
while ((num % i) === 0) {
arr.push(i);
num /= i;
}
}
for (var k = 0; k < arr.length; k++) {
if(arr[k] == primenum && arr.length <= primenum)
return true;
}
return false;
}
hasLessPrimeFactor(20,5);
Any suggestion is welcome.
Given the requirement gleaned from your comment that the primenum variable should be a factor of num, you could verify that at the beginning. It seems a strange requirement, though-- not really implied in the name of the method, so I'd look closely to make sure you didn't introduce any accidental assumptions. That said, this would test to ensure the primenum parameter is a factor of num.
if (num % primenum) return false;
Additionally, your first for loop need not iterate from 2..num; it would be sufficient to iterate from 2..primenum.

Javascript - How to sum up all the first and last digit of a number until only two digits are left?

I am fairly new to programming, just knowing the basics in Javascript and Swift. I am trying to write a simple program which creates, from any entered number, a two digit number by summing up the first and last digit until only two digits are finally left.
Here is an example:
num = 1234567:
1+7 = 8
2+6 = 8
3+5 = 8
4 remains
So the first result is: 8884. Now everything is added again:
8+8 = 16
8+4 = 12
The result is 1612. Again everything is summed up:
1+2 = 3
6+1 = 7
The result is 37 - which is also the final result.
I am struggling with two things. First the while loop. I was thinking about casting num.toString() and then do a while loop like this in which I change the string to an int again:
num.toString()
while (num.length > 2) {
num = num.parseInt(num, 10);
...
}
But this doesn't work properly, plus it gets crazy complicated I guess because I would have to switch between string and int each new round, right?
I know how to add all digits together until I get a two digit number (it took me a while to figure this one out) and I am not even sure if this is a good way to do it:
var sum = num
.toString()
.split('')
.map(Number)
.reduce(function (a, b) {
return a + b;
}, 0);
But obviously I cannot use this here and I have no idea how to change the code so that the first and last digit are added together.
Slightly different approach:
function sum(num) {
var numString = num.toString();
var newString = "";
while (numString.length > 1) { // (1)
newString += (parseInt(numString[0]) + parseInt(numString[numString.length - 1])).toString(); // (2)
numString = numString.substring(1, numString.length - 1); // (3)
}
newString += numString; // (4)
if (newString.length > 2) { // (5)
console.log(newString)
return sum(newString);
} else {
return newString;
}
}
console.log(sum(1234567));
Outputs:
8884
1216
73
Brief explanation of what's going on:
(1) Your while loop will process the string until there's either 1 or
0 characters left
(2) Add the sum of your first and last character to
your newString
(3) Remove the first and last characters from your
numString now that they've been saved to the newString. Because
you're overwriting the value in numString and shrinking it, this
will eventually satisfy the while condition of a numString with
less than 2 characters
(4) Add the remaining characters to
newString, which will either be 1 or 0 characters depending on the
length of the original number
(5) if your newString is more than 2
characters, run this method again. Otherwise return your result
Try this buddy. Its just using simple for loop. Its loops upto half of number and add corresponding. The final result according to ur logic should be 73 not 37
function sum(num){
//if num is greater than or equal to 2 end the function and return final value
if(num.length <= 2) return num;
//converting the num to string beacuse first time input will be number
num = String(num);
let result = '';
//creating a loop upto half of length of the num
for(let i = 0;i<num.length/2;i++){
//if the number is not middle one
if(i !== num.length - 1 - i)
{
//adding the sum of corresponding numbers to result
result += parseInt(num[i]) + parseInt(num[num.length - 1 - i]);
}
//if the number is middle number just add it to result
else result += num[i]
}
return sum(result);
}
console.log(sum(1234567))
You could take a nested while loop and check the string length for the outer loop and the left and right indices for the inner loop
function add(n) {
var s = n.toString(),
l, r,
sum;
while (s.length > 2) {
l = 0;
r = s.length - 1;
sum = [];
while (l < r) {
sum.push(+s[l++] + +s[r--]);
}
if (l === r) sum.push(s[l]);
s = sum.join('');
}
return +s;
}
console.log(add(1234567));
The same but with a recursive function.
function add(n) {
var s = n.toString(),
l = 0, r = s.length - 1,
sum = [];
if (s.length <= 2) return n;
while (l < r) sum.push(+s[l++] + +s[r--]);
if (l === r) sum.push(s[l]);
return add(+sum.join(''));
}
console.log(add(1234567));

Javascript + return PrimeNumbers

I am trying to write a function that returns the PrimeNumber. for testing purposes i am just doing a console.log for stages of this function, to try and understand it better.
so this line(line:18) in my total function will just return i; as opposed to do a console.log
So Basically, 30 will be passed to the function and the function will return every prime number <=30.
It is based on this from wiki:
This routine consists of dividing n by each integer m that is greater than 1
and less than or equal to the square root of n.
If the result of any of these divisions is an integer,
then n is not a prime, otherwise it is a prime.
(Question here: 25/Math.sqrt(25) = 0, therefore NotPrime
BUT 25/2=12.5, 25/3=8.3333 25/4=6.25 => IsPrime as 12.5 is not an integer Or am I mising something here???)
there is also the problem of duplication: 13 is printed twice because 13/2 and 13/3 is executed. Question here: I would like to fix this duplication also?
function isInt(n) {
return n % 1 === 0;
}
var test = 25
console.log(Math.sqrt(test));
function prime(n) {
for(var i = 1; i <= n; i++)
{ if(i%2 !==0 && i%3 !==0){ // if i/2 does not have a remainder it might be a prime so go to next line else jump
to next number and i%3 the same
var a = Math.floor(Math.sqrt(i));
for(j = 2; j<=a; j++){
console.log(i + "/" + j); //print j//it prints 9 twice and 10 twice
console.log("==" + i/j); //because the sqrt of 9 = 3 =>
for j= 2 and j=3
if(isInt(i/j)) {}
else{console.log("----" + i + "is Prime");}
}
}
}
};
prime(test);
Another example here using aslightly different method: but again I have the same problem as the above 25 and duplication
var test = 25
console.log(Math.sqrt(test));
for(var i = 1; i <= test; i++)
{ if(i%2 !==0 && i%3 !==0){ // if i/2 does not have a remainder it might be a prime so go to next line else jump to next number and i%3 the same
var a = Math.floor(Math.sqrt(i));
for(j = 2; j<=a; j++){
console.log(i + "%" + j); //print j//it prints 9 twice and 10 twice
console.log("==" + i%j); //because the sqrt of 9 = 3 => for j= 2 and j=3
if(i%j !==0) {
console.log("----" + i + "is Prime");
}
}
}
}
[EDIT]Thank you all very much for pointing out my flaws/mistakes
here is my working example. Thank you all again!!
function isInt(n) {
return n % 1 === 0;
}
var test = 100
console.log(Math.sqrt(test));
function prime(n) {
for (var i = 1; i <= n; i++) {
var a = Math.floor(Math.sqrt(i));
var bool = true;
for(j = 2; j<=a; j++) {
if(!isInt(i/j)) {
//console.log(i+"/"+j+"=="+i/j+", therefore "+i+" is Prime");
} else {bool = false;}
}
if(bool) {console.log(i+"/"+j+"=="+i/j+", therefore "+i+" is Prime");}
}
}
prime(test);
25/Math.sqrt(25) = 0, therefore NotPrime
BUT 25/2=12.5, 25/3=8.3333 25/4=6.25 => IsPrime
No. Only because it neither is divisible by 2, 3, and 4, it does not mean that 25 is a prime number. It must be divisible by nothing (except 1 and itself) - but 25 is divisible by 5 as you noticed. You will have to check against that as well.
13 is printed twice because 13/2 and 13/3 is executed.
Question here: I would like to fix this duplication also?
Your logic is flawed. As above, just because a number is not divisible by an other number that does not mean it was prime - but your code prints results based on that condition. Instead, is has to be not divisible by all other numbers.
You just have an extra condition that nothing that is divisible by 2 or 3 enters the loop, but everything that is divisible by 5, 7, 11 etc (and not divisible by 2 or 3) is yielded. 25 is just the first number to occur in that series, the next ones will be 35 and 49.
Actually you're already testing 2 and 3 in the loop from 2 to a already, so you should just omit that condition. You would've noticed your actual problem much faster then if you had tried:
function prime(n) {
for (var i = 1; i <= n; i++) {
var a = Math.floor(Math.sqrt(i));
for(j = 2; j<=a; j++) {
if(!isInt(i/j)) {
console.log(i+"/"+j+"=="+i/j+", therefore "+i+" is Prime");
}
}
}
}
prime(25);
The logic should be: Test all divisors from 2 to sqrt(i), and if i is divisible by any of them you know that it's not a prime. Only if it has passed the loop with none of them being a factor of i, you know in the end that it's a prime. I'll leave that as an exercise to you :-)

Categories

Resources