while loop test case errors - javascript

The question as per the practice course is :
Write a JavaScript program to find the maximum integer n such that (1 + 2 + ... + n <= given integer ) is true. For eg. If a given integer is 10, value of maximum integer n is 4 so that 1+2+3+4 <= 10 is true. Your output code should be in the format console.log("Value of n is ", variableName)
My code is :
var num = prompt("Enter a number");
function test(x) {
var sum = 1,
n = 1,
a = 0;
while (sum <= x) {
sum += n;
n = n + 1;
a += 1;
}
return a;
}
var output = test(num);
console.log("Result is :", output);
I'm getting the correct outputs as per the test cases I've entered(10-4,15-5,16-6,17-6) but the website says there is something wrong with the program.
What am i doing wrong?

Better answer than looping: exploit maths. Starting with Triangular number formula:
1 + 2 + ... + n = n * (n + 1) / 2
Thus, for input x, you need to find n such that
n * (n + 1) / 2 <= x
To solve this, we need to clean up the inequality, then use the quadratic equation formula:
n^2 + n <= 2x
n^2 + n - 2x <= 0
n <= (-1 + sqrt(1 + 8x)) / 2
as the final solution. e.g. for
x = 10: n <= (-1 + sqrt(81)) / 2; n <= 4
x = 16: n <= (-1 + sqrt(128)) / 2; n <= 5.156854249492381
Round the upper limit down, and you have the largest allowed integer. Translated into JavaScript:
function test(x) {
return Math.floor((Math.sqrt(8 * x + 1) - 1) / 2);
}
var num = prompt("Enter a number");
console.log("Result is :", test(num));

Consider if the passed value is 11. Then, the maximum integer n should be 4, because 1+2+3+4 < 11 is true, while 1+2+3+4+5 < 11 is false. Your current code outputs 5 for an input of 11, though, which is incorrect; your while loop is sometimes overshooting sum.
You also need to initialize sum to start at 0, not at 1.
Subtract one from a before returning it:
function test(x) {
var sum = 0,
n = 1,
a = 0;
while (sum <= x) {
sum += n;
n = n + 1;
a += 1;
console.log(a, sum);
}
return a - 1;
}
console.log(test(10));
console.log(test(11));
var num = prompt("Enter a number");
var output = test(num);
console.log("Result is :", output);

The code below should work for you. Basically, what I did was that if the input is 10, and your sum is 9, it will still go into the while loop. Then it will add n again and now your number is greater than your input (which is 10), but you still return it. Here what I did is that at the end of the while loop, if your sum is greater than your input, subtract one from a. That way it will still execute, but it will fix the problem.
Also another error I noticed was that sum started at 1, and n started at 1. You wanted 1+2+3+...+n, however using your previous method, you got 1+1+2+3+...+n.
var num = prompt("Enter a number");
function test(x) {
var sum = 0,
n = 1,
tempSum = 1,
a = 0;
while (sum <= x) {
sum += n;
n++;
a++;
if (sum > x) {
a--;
}
}
return a;
}
var output = test(num);
console.log("Result is :", output);

Your order of operation is a little funky; all you have to do is add the incrementor. The while false case will make sure the sum only passes over the number once. So when you return, reduce the number by one:
var num = prompt("Enter a number");
var output = test(num);
console.log("Result is :", output);
function test(num){
let sum = 0
let inc = 0
while(sum<=num)
sum+=++inc
return --inc;
}

This is a reduced version of your code, basically we increment first the number to add (n) in each iteration, and then we add it to the variable holding the sum. When the loop conditions evaluates to false you need to decrement one to n to get your value:
var num = prompt("Enter a number");
function test(x)
{
var sum = 0, n = 0;
while (sum <= x)
{
sum += (++n);
}
return --n;
}
var output = test(num);
console.log("Result is :", output);

I think this will work for you:
var num = prompt("Enter a number");
function test(x) {
var sum = 1,
n = 0;
while ((sum+n) <= x) {
n = n + 1;
sum += n;
}
return n;
}
var output = test(num);
console.log("Result is :", output);

Try below function to find max Number
function maxNumber(a){
var i=1,sum=0,maxNumber=0;
while(sum<=a) {
sum=sum+i;
if(sum<=a)
{
maxNumber=i;
}
i+=1;
}
return maxNumber;
}
doubled checked condition sum<=a to preserve the previous loop value and if condition not satisfied that means current loop value is not useful so returned preserved value of previous loop
Output tested :

Below will help you get the job done.
var num = prompt("Enter a number");
function findMaxNumber(num){
var sum = 0;
var counter = 0;
while(sum < num){
if(sum + counter > num){
break; // Exit loop
}
sum = sum + counter;
counter++;
}
return --counter; // Loop will cause this to be 1 higher than the max int.
}
console.log('Result is: ' + findMaxNumber(num));

Related

that returns the sum of all numbers between two chosen numbers

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));

Counting sum every 7th while loop

I'm having a hard time with this problem here:
Write a function named sumEvery7th that accepts a
non negative integer n and returns the sum integers divisible by 7.
Use a while loop
I have this code so far but console.log(sumEvery7th(25)); outputs 63 when it should output 42
function sumEvery7th(n){
let sum=0;
var i=7;
while (i<=n) {
i+=7
sum+=i;
}
return sum;
}
console.log(sumEvery7th(25)); // 7+14+21=42
console.log(sumEvery7th(0)); // expect 0
Thanks for the help
Your logic is out of order inside the for loop. There are two ways you can address this:
You need to increase the sum and then increment the iterated value. Just simply switch the line for incrementing i by 7 to be below the sum addition and you're good to go.
function sumEvery7th(n){
let sum=0;
var i=7;
while (i<=n) {
sum+=i;
i+=7;
}
return sum;
}
console.log(sumEvery7th(25)); // 7+14+21=42
console.log(sumEvery7th(0)); // expect 0
Or you could set i to 0 and get the same result
function sumEvery7th(n){
let sum=0;
var i=0;
while (i<=n) {
i+=7
sum+=i;
}
return sum;
}
console.log(sumEvery7th(25)); // 7+14+21=42
console.log(sumEvery7th(0)); // expect 0
choose whichever feels more natural to you as both are correct logic.
Remember: order of operations is important
Try it with a for loop:
const sumEvery7th = (n) => {
let sum = 0;
for (let i = 7; i <= n; i += 7) {
sum += i;
}
return sum;
}
console.log("50 -> ", sumEvery7th(50));
console.log("25 -> ", sumEvery7th(25));
console.log("7 -> ", sumEvery7th(7));
console.log("6 -> ", sumEvery7th(6));
console.log("0 -> ", sumEvery7th(0));
.as-console-wrapper{min-height: 100%!important; top: 0;}
Just change the order of lines in while loop
function sumEvery7th(n) {
let sum = 0;
var i = 7;
while (i < n) {
sum += i;
i += 7
}
return sum;
}
console.log(sumEvery7th(25)); // 42
console.log(sumEvery7th(0)); // 0
The line sum+=i; should come before i+=7
The input is also the increment number. int--
Exit loop when the there is no more input left. while (int > 0) {...
Check by modulus on every iteration. if (int % 7 === 0) {...
When a factor of 7 is found add it to sum. sum +=int
Made it a little more useful by adding a second parameter for the factor. Now you can use something other than 7.
function sumOfFactors(int, fac) {
let sum = 0;
while (int > 0) {
int--;
if (int % fac === 0) {
sum += int;
}
}
return sum;
}
console.log(sumOfFactors(25, 7));
console.log(sumOfFactors(58, 7));
console.log(sumOfFactors(0, 7));
console.log(sumOfFactors(77, 7));

Sum of odd numbers until reached limit in Javascript

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);

Sum all the digits of a number Javascript

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;
}

Euler Project 2 in Javascript

I am going through the Odin Project and part of that is doing questions 1-3 in the Euler project. I am stumped on question 2:
"By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms."
I am so frustrated! What am I doing wrong? Here's what I have so far. Thanks!
function f() {
var fib = [];
fib.push(1,2,3);
var i = fib.length;
var total = 0;
while(fib[i] < 4000000) {
var x = fib[i-2] + fib [i-1];
if(x % 2 == 0) {
total += x;
}
} return total;
}
console.log(f());
The fibonacci sequences starts 1, 1, 2, not 1, 2, 3.
Also, your solution looks like it will work, but you are storing every number in the sequence instead of just the last two, so this will gobble memory comparatively.
As #DLeh notes, the fibonacci sequence starts with 1,1,2 - not 1,2,3. However, that doesn't change the result of summing the even valued items. The problem you're having is that at this point:
while(fib[i] < 4000000) {
fib[i] is undefined, so the function immediately exits with the total staying at 0. Also within the while loop, you're not pushing the next item in the sequence into your array. The below code fixes both of these problems:
function f() {
var fib = [];
fib.push(1,1);
var i = fib.length;
var total = 0;
while(fib[i-1] < 4000000) {
var x = fib[i-2] + fib [i-1];
fib.push(x);
i = fib.length;
if(x % 2 == 0) {
total += x;
}
} return total;
}
console.log(f()); //4613732
#DLeh also pointed out that you're storing more numbers than needed, this solution works without using the array:
function f() {
var f1 = 1;
var f2 = 1;
var total = 0;
while (f2 < 4000000) {
var t = f1 + f2;
if (t % 2 == 0)
total += t;
f1 = f2;
f2 = t;
}
return total;
}
console.log(f()); //4613732
Just for grins, note that you can do this problem without any use of %, and just + operations. Every third value in the sequence is even. That is, 2 is followed by 3 (odd), and then 3 + 2 is 5 (odd), but that sum of two odd numbers gets us back to even (8) and the cycle repeats.
Thus:
function evenFibTotal(limit) {
var a = 1, b = 1, c = 2, total = 0;
while (c < limit) {
total += c;
a = b + c;
b = a + c;
c = a + b;
}
return total;
}
On each iteration, the second trailing value is set to the next value in the sequence (b + c), and that plus the current one is the first trailing value, and finally the next even Fibonacci number is the sum of those two.
(There's also the closed solution but it's no fun :)

Categories