Add individual negative numbers from a String - javascript

function sumDigits(num) {
newStr = num.toString();
var sum = 0;
for(var i=0; i < newStr.length; i++) {
sum = sum + parseInt(newStr[i]);
}
return sum;
}
var output = sumDigits(1148);
console.log(output); // --> 14
Hey guys, my output is 14. However, my for loop falls apart if num is a negative number. Anyone got any ideas how to get past this? Presently, a negative number returns 'NaN'

I would suggest using a modulus approach here, which avoids the unnecessary cast from integer to string and vice-versa:
function sumDigits(num) {
var sum = 0;
while (num != 0) {
sum += num % 10;
num = num > 0 ? Math.floor(num / 10) : Math.ceil(num / 10);
}
return sum;
}
var output = sumDigits(1148);
console.log("1148 => " + output);
var output = sumDigits(-1148);
console.log("-1148 => " + output);
output = sumDigits(0);
console.log("0 => " + output);

Multiply the result?
function sumDigits(input) {
return Math.abs(input)
.toString()
.split("")
.reduce((sum, num) => sum + Number(num), 0)
* (input < 0 ? -1 : 1);
}

One of the examples.
function sumDigits(num) {
newStr = Math.abs(num).toString();
var sum = 0;
for(var i=0; i < newStr.length; i++) {
sum = sum + parseInt(newStr[i]);
}
return num >= 0 ? sum : -sum ;
}
var output = sumDigits(1148);
console.log(output); // --> 14
var output = sumDigits(-1148);
console.log(output); // --> -14
var output = sumDigits(0);
console.log(output); // --> 0

When you pass a negative number into your sumDigits() function and convert it to a string, the first character becomes the sign (-). So, you should get the absolute value to get rid of the sign. However, if you're expecting a negative value, then you should define a flag that indicates whether the parameter was a negative integer before it got converted, or simply multiply it again by the initial sign. So, you should modify your function like this:
function sumDigits(num) {
const seq = Math.abs(num).toString();
let sum = 0;
for (let i = 0; i < seq.length; i++) {
sum += parseInt(seq[i]);
}
return sum * Math.sign(num);
}

Related

Convert a Negative Number to a string then back to a negative Number

function sumDigits(num) {
var newStr = num.toString();
var result = 0;
for(var i=0; i<newStr.length; i++) {
result += Number(newStr[i]);
}
return result;
}
var output = sumDigits(-1148);
console.log(output); // --> -14
Trying to sum the individual digits in this problem. However, when negative numbers are involved the function falls apart. This is because when you use toString() converts the negative-sign as a value in the newStr. For example, newStr[0] === '-' in this case. Anyway to work around this? Preferably using the Number() function
You could work with the absolute value and apply the sign later to the result.
function sumDigits(num) {
var newStr = Math.abs(num).toString(),
result = 0;
for (var i = 0; i < newStr.length; i++) {
result += Number(newStr[i]);
}
return (num > 0 || -1) * result;
}
var output = sumDigits(-1148);
console.log(output); // --> -14
Using String(), Array.prototype.reduce(), Math.abs(), spread syntax and ternary operator to get the desired result.
function sumDigits(num) {
const number = Math.abs(num),
sum = [...String(number)].reduce((acc, n) => acc + parseInt(n), 0);
return num >= 0 ? sum : -1 * sum;
}
const output1 = sumDigits(-1148);
console.log(output1); // --> -14
const output2 = sumDigits(1148);
console.log(output2); // --> 14

How can I count the number and calculate it? (i using isNaN())

My code is below. I'm using isNaN() but the problem is it's still valid
function numberSearch(str) {
let sum = 0
let strCount = 0
if (str === "") {
return 0
};
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1 // if it's true, +1
}
sum = sum + Number(str[i]) // if it's a number
}
return Math.round(sum / strCount);
}
//debugger;
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 1
How can I count the number and calculate it?
When I using debugger sum is NaN .. I cant understand well.
The issue is that sum = sum + Number(str[i]) is being executed even if isNaN(Number(str[i])) === true because it is outside of the if block. You need to wrap it inside of the else block so that it only executes if the previous condition is false.
function numberSearch(str) {
let sum = 0
let strCount = 0
if (str === "") {
return 0
};
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1 // if it's true, +1
} else {
sum = sum + Number(str[i]) // if it's a number
}
}
return Math.round(sum / strCount);
}
//debugger;
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 1
The other way of doing this is with a continue statement. Think of continue the same way you think about an early return in a function, except for a loop.
For example, you've written:
function numberSearch(str) {
// . . .
if (str === "")
return 0
// . . .
}
This is called an "early return" or "early exit." The same technique can be used in a loop:
for (let i = 0; i <= 10; i++) {
if (i % 3 === 0) // matches every multiple of 3 (3, 6, 9, etc.)
continue;
console.log(i)
}
Here is your code again, this time using continue.
function numberSearch(str) {
let sum = 0
let strCount = 0
if (str === "") {
return 0
};
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1 // if it's true, +1
continue
}
sum = sum + Number(str[i]) // if it's a number
}
return Math.round(sum / strCount);
}
//debugger;
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 1
I recommend you go with the if-else version because for a loop as simple as this, the use of continue adds a little unnecessary metal-overhead.
That being said, if the logic within the loop grows (the part in the else statement), you may find it is easy to read if you do use the continue method. In the end, what really matters is what you personally feel is easier to read.
I would probably do it slightly different than in the original code, and find out how many numbers there are, and work from there
function numberSearch(str) {
if (!str) {
// early exit for null or ''
return 0;
}
// get all the chars, filter the non-numbers
const numbers = str.split('').filter( v => !isNaN(Number(v)));
// map all the numbers to numbers and sum them up
const sum = numbers.map( Number ).reduce( (agg, item) => agg + item, 0 );
// divide the sum by the length of the string - the amount of numbers found
// but always by at least 1 (so not to get a divide by 0 error when only all numbers are given)
return Math.round( sum / Math.max(1, str.length - numbers.length) );
}
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 2
output = numberSearch('111111111');
console.log(output); // --> 9
output = numberSearch('');
console.log(output);
For the original code however, you should just add a continue in your if branch and your code will work (as long as not all characters are numbers, cause then you would divide by 0 and you didn't specify how to handle such a case)
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1; // if it's true, +1
continue;
}
sum = sum + Number(str[i]); // if it's a number
}
Just remember to verify to not divde by 0 if all are numbers :)
Your main issue is that you add a number anyway. In the line sum = sum + Number(str[i]) is read for each and every character. So even the last char will be NaN and it would be added to the sum, making it NaN.
I'm not quite sure what you're trying to do here, it seems like you are trying to get the sum and divide it by the number of non number characters.
You need to skip those in the sum. There are plenty of ways to do it, and some other problems with the code, but to keep the changes to your code to a minimum I say, just do this:
function numberSearch(str) {
let sum = 0;
let strCount = 0;
if (str === "") {
return 0;
};
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1; // if it's true, +1
} else {
sum = sum + Number(str[i]); // if it's a number
}
}
return Math.round(sum / strCount);
}
Think of the following case
for(let i = 0 ; i<str.length ; i++){
//str[0] is 'H', so fall into the first if-case
if(isNaN(Number(str[i]))){
strCount = strCount + 1 // if it's true, +1
}
//the code keep running but 'H' shouldn't fall into the following case
sum = sum + Number(str[i]) // if it's a number
}
return Math.round(sum/strCount);
I suggest you add one more if-else for each case which clearly state out each of the case. This makes it easier to recall memory when you come across the code days or months later.
for(let i = 0 ; i<str.length ; i++){
if(isNaN(Number(str[i]))){
strCount = strCount + 1
}else if(typeof str[i] === 'number'){
sum = sum + Number(str[i])
}
}
return Math.round(sum/strCount);

Calculate the sum of positive values smaller or equal to a number

I am trying to calculate the sum of positive values smaller or equal to the entered number, for ex: 5 -> 1+2+3+4+5 = 15
I came up with this:
var num = Number(prompt("Enter a number "));
sum = 0;
i = num;
do {
sum = sum += i;
i--
document.write(sum);
} while (i > 0);
I don't understand what I am doing wrong.
i think this is correct code:
var num = Number(prompt("Enter a number "));
sum = 0;
i = num;
do
{
sum += i;
i--;
}
while (i > 0);
document.write(sum);
and i suggest you to use this formula : document.write((num * (num + 1)) / 2);
If you look closer to your task, you'll find out, that:
If Num = 1, the sequence to be summed is [1]
if Num = 2, the sequence is [1, 2]
if Num = 3, the sequence is [1, 2, 3]
You can imagine, that you have a square with sides equal to num, for example, when num = 4:
****
****
****
****
And you need to summ 1, 2, 3, 4:
***#
**##
*###
####
See? It's a square of a triangle.
It could be calculated by formula: num * (num + 1) / 2
So, you code could be:
var num = Number(prompt("Enter a number "));
document.write(num * (num + 1) / 2)
You are writing the sum on each loop instead you have to print it finally. If you want to print the numbers then keep it an array and join them with + symbol before writing. To make it in ascending order change the loop condition.
var num = Number(prompt("Enter a number "));
sum = 0;
i = 1;
nums = [];
do {
sum = sum += i;
nums.push(i++);
}
while (i <= num);
document.write(nums.join(' + ') + ' = ' + sum);
Do with increment instead of decrements.And also show result of sum outside of loop .Not with in loop.And create array to append increment value.Finally print with document.write
var num=Number(prompt("Enter a number "));
sum = 0;
i = 1;
var a=[];
do {
sum +=i;
a.push(i)
i++;
}
while (num >= i);
document.write(a.join('+')+'='+sum)
You should write the answer at the end of loop and make this simple sum += i;.
var num = Number(prompt("Enter a number"));
sum = 0;
i = num;
do {
sum += i;
i--;
}
while (i > 0);
document.write(sum);
var number = 5, // Your number
result = 0;
while ( number !== 0 ) {
result += number;
number--;
}
document.write(result);
Fast and precious solution.
Here is the case with complete check and display as you need: JAVA
public static void main ( String arg[]) {
Scanner scan = new Scanner(System.in);
int number = scan.nextInt();
System.out.println("Number entered : " + number);
int sum =1 ;
if(number > 1) {
int nextNumber = 1;
System.out.print(nextNumber);
do {
// sum of all the positive numbers
nextNumber++ ;
sum = nextNumber + sum;
System.out.print( " + " + nextNumber);
}while(nextNumber < number);
System.out.print(" = " + sum);
}
}
var num = Number(prompt("Enter a number"));
sum = 0;
for (i = num; i > 0; i--) {
sum += i;
}
document.write(sum);

function sumDigits; How do I get this function to work with a negative number?

Question:
Write a function called sumDigits.
Given a number, sumDigits returns the sum of all its digits.
var output = sumDigits(1148);
console.log(output); // --> 14
If the number is negative, the first digit should count as negative.
var output = sumDigits(-316);
console.log(output); // --> 4
This is what I currently have coded and it works for positive values but I can't wrap my head around how to tackle the problem when given a negative value. When -316 is put into the function, NaN is returned and I understand that when I toString().split('') the number, this is what is returned: ['-', '3', '1', '6']. How do I deal with combining index 0 and 1?
function sumDigits(num) {
var total = 0;
var newString = num.toString().split('');
for (var i = 0; i < newString.length; i ++) {
var converted = parseInt(newString[i]);
total += converted;
}
return total;
}
sumDigits(1148);
Any hints on what methods I should be using? and is there a smarter way to even look at this?
This should do it:
function sumDigits(num) {
var total = 0;
var newString = num.toString().split('');
for (var i = 0; i < newString.length; i ++) {
if(newString[i]==='-') { //check to see if the first char is -
i++; //if it is, lets move to the negative number
var converted = parseInt(newString[i]); // parse negative number
total -= converted; // subtract value from total
continue; // move to the next item in the loop
}
var converted = parseInt(newString[i]);
total += converted;
}
return total;
}
console.log(sumDigits(-316));
You could always use String#replace with a function as a parameter:
function sumDigits (n) {
var total = 0
n.toFixed().replace(/-?\d/g, function (d) {
total += +d
})
return total
}
console.log(sumDigits(-1148)) //=> 14
One way to do this, is to do a split that will keep the minus and the first digit together, not split.
You can do that with a regular expression, and use match instead of split:
var newString = num.toString().match(/-?\d/g);
function sumDigits(num) {
var total = 0;
var newString = num.toString().match(/-?\d/g);
for (var i = 0; i < newString.length; i++) {
var converted = parseInt(newString[i]);
total += converted;
}
return total;
}
var result = sumDigits(-316);
console.log(result);
In a bit shorter version, you could use map and reduce, like this:
function sumDigits(num) {
return String(num).match(/-?\d/g).map(Number).reduce( (a, b) => a+b );
}
console.log(sumDigits(-316));
Is there a smarter way to even look at this?
You can avoid the conversion from number to string and back by using the modulo operator to extract the last digit. Repeat this step until you got all digits:
function sumDigits(num) {
let total = 0, digit = 0;
while (num != 0) {
total += digit = num % 10;
num = (num - digit) * 0.1;
}
return total < 0 ? digit + digit - total : total;
}
console.log(sumDigits(-316)); // 4
console.log(sumDigits(1148)); // 14
console.log(sumDigits(Number.MAX_SAFE_INTEGER)); // 76
function sumDigits(num) {
let string = num.toString();
let zero = 0;
let total = 0;
for (var i = 0; i < string.length; i++) {
if (Math.sign(num) === 1) {
total = zero += Number(string[i]);
} else {
for (var i = 2; i < string.length; i++) {
total = (zero += Number(string[i])) - Number(string[1]);
}
}
}
return total;
}

A code wars challenge

I have been struggling with this challenge and can't seem to find where I'm failing at:
Some numbers have funny properties. For example:
89 --> 8¹ + 9² = 89 * 1
695 --> 6² + 9³ + 5⁴= 1390 = 695 * 2
46288 --> 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51
Given a positive integer n written as abcd... (a, b, c, d... being digits) and a positive integer p we want to find a positive integer k, if it exists, such as the sum of the digits of n taken to the successive powers of p is equal to k * n. In other words:
Is there an integer k such as : (a ^ p + b ^ (p+1) + c ^(p+2) + d ^ (p+3) + ...) = n * k
If it is the case we will return k, if not return -1.
Note: n, p will always be given as strictly positive integers.
digPow(89, 1) should return 1 since 8¹ + 9² = 89 = 89 * 1
digPow(92, 1) should return -1 since there is no k such as 9¹ + 2² equals 92 * k
digPow(695, 2) should return 2 since 6² + 9³ + 5⁴= 1390 = 695 * 2
digPow(46288, 3) should return 51 since 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51
I'm new with javascript so there may be something off with my code but I can't find it. My whole purpose with this was learning javascript properly but now I want to find out what I'm doing wrong.I tried to convert given integer into digits by getting its modulo with 10, and dividing it with 10 using trunc to get rid of decimal parts. I tried to fill the array with these digits with their respective powers. But the test result just says I'm returning only 0.The only thing returning 0 in my code is the first part, but when I tried commenting it out, I was still returning 0.
function digPow(n, p){
// ...
var i;
var sum;
var myArray= new Array();
if(n<0)
{
return 0;
}
var holder;
holder=n;
for(i=n.length-1;i>=0;i--)
{
if(holder<10)
{
myArray[i]=holder;
break;
}
myArray[i]=holder%10;
holder=math.trunc(holder/10);
myArray[i]=math.pow(myArray[i],p+i);
sum=myArray[i]+sum;
}
if(sum%n==0)
{
return sum/n;
}
else
{
return -1;
}}
Here is the another simple solution
function digPow(n, p){
// convert the number into string
let str = String(n);
let add = 0;
// convert string into array using split()
str.split('').forEach(num=>{
add += Math.pow(Number(num) , p);
p++;
});
return (add % n) ? -1 : add/n;
}
let result = digPow(46288, 3);
console.log(result);
Mistakes
There are a few problems with your code. Here are some mistakes you've made.
number.length is invalid. The easiest way to get the length of numbers in JS is by converting it to a string, like this: n.toString().length.
Check this too: Length of Number in JavaScript
the math object should be referenced as Math, not math. (Note the capital M) So math.pow and math.trunc should be Math.pow and Math.trunc.
sum is undefined when the for loop is iterated the first time in sum=myArray[i]+sum;. Using var sum = 0; instead of var sum;.
Fixed Code
I fixed those mistakes and updated your code. Some parts have been removed--such as validating n, (the question states its strictly positive)--and other parts have been rewritten. I did some stylistic changes to make the code more readable as well.
function digPow(n, p){
var sum = 0;
var myArray = [];
var holder = n;
for (var i = n.toString().length-1; i >= 0; i--) {
myArray[i] = holder % 10;
holder = Math.trunc(holder/10);
myArray[i] = Math.pow(myArray[i],p+i);
sum += myArray[i];
}
if(sum % n == 0) {
return sum/n;
} else {
return -1;
}
}
console.log(digPow(89, 1));
console.log(digPow(92, 1));
console.log(digPow(46288, 3));
My Code
This is what I did back when I answered this question. Hope this helps.
function digPow(n, p){
var digPowSum = 0;
var temp = n;
while (temp > 0) {
digPowSum += Math.pow(temp % 10, temp.toString().length + p - 1);
temp = Math.floor(temp / 10);
}
return (digPowSum % n === 0) ? digPowSum / n : -1;
}
console.log(digPow(89, 1));
console.log(digPow(92, 1));
console.log(digPow(46288, 3));
You have multiple problems:
If n is a number it is not going to have a length property. So i is going to be undefined and your loop never runs since undefined is not greater or equal to zero
for(i=n.length-1;i>=0;i--) //could be
for(i=(""+n).length;i>=0;i--) //""+n quick way of converting to string
You never initialize sum to 0 so it is undefined and when you add the result of the power calculation to sum you will continually get NaN
var sum; //should be
var sum=0;
You have if(holder<10)...break you do not need this as the loop will end after the iteration where holder is a less than 10. Also you never do a power for it or add it to the sum. Simply remove that if all together.
Your end code would look something like:
function digPow(n, p) {
var i;
var sum=0;
var myArray = new Array();
if (n < 0) {
return 0;
}
var holder;
holder = n;
for (i = (""+n).length - 1; i >= 0; i--) {
myArray[i] = holder % 10;
holder = Math.trunc(holder / 10);
myArray[i] = Math.pow(myArray[i], p + i);
sum = myArray[i] + sum;
}
if (sum % n == 0) {
return sum / n;
} else {
return -1;
}
}
Note you could slim it down to something like
function digPow(n,p){
if( isNaN(n) || (+n)<0 || n%1!=0) return -1;
var sum = (""+n).split("").reduce( (s,num,index)=>Math.pow(num,p+index)+s,0);
return sum%n ? -1 : sum/n;
}
(""+n) simply converts to string
.split("") splits the string into an array (no need to do %10 math to get each number
.reduce( function,0) call's the array's reduce function, which calls a function for each item in the array. The function is expected to return a value each time, second argument is the starting value
(s,num,index)=>Math.pow(num,p+index+1)+s Fat Arrow function for just calling Math.pow with the right arguments and then adding it to the sum s and returning it
I have created a code that does exactly what you are looking for.The problem in your code was explained in the comment so I will not focus on that.
FIDDLE
Here is the code.
function digPow(n, p) {
var m = n;
var i, sum = 0;
var j = 0;
var l = n.toString().length;
var digits = [];
while (n >= 10) {
digits.unshift(n % 10);
n = Math.floor(n / 10);
}
digits.unshift(n);
for (i = p; i < l + p; i++) {
sum += Math.pow(digits[j], i);
j++;
}
if (sum % m == 0) {
return sum / m;
} else
return -1;
}
alert(digPow(89, 1))
Just for a variety you may do the same job functionally as follows without using any string operations.
function digPow(n,p){
var d = ~~Math.log10(n)+1; // number of digits
r = Array(d).fill()
.map(function(_,i){
var t = Math.pow(10,d-i);
return Math.pow(~~((n%t)*10/t),p+i);
})
.reduce((p,c) => p+c);
return r%n ? -1 : r/n;
}
var res = digPow(46288,3);
console.log(res);

Categories

Resources