Add up numbers generated from a "for loop"?

I apologize for bringing my super noob beginner questions here. I have written a program which will generate all of the odd numbers between 1 and a user-generated number. What I actually need is to add all of the odd numbers. My desired output is the total of all odd numbers between 1 and the user-generated number. Below is my code:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Add up the odd numbers.</title>
<script type="text/javascript">

//((n+1)/2)^2 n plus one, divided by 2, square that number is sum of all consecutive odd numbers.

function sumIt()
{
var number = parseInt (document.getElementById('number').value);

for (var start = 1; number >= start; start += 2){

document.write (start + "<br>");

}
}
</script>
</head>
<body>
Your Number:<input type="text" id="number">
</br>
<button type="button" onClick="sumIt();">Sum It Up!</button>
</body>
</html>

Inside the loop, you’d need to add up the odd numbers to an accumulator variable then:

function sumOdds (n) {
  let sum = 0
  
  for (let i = 1; i <= n; i += 2) {
    sum += i
  }
  
  return sum
}

console.log(sumOdds(10)) // 25

So this works. But, how can I make it only display the final number? I only want to display the final sum at the end of the loop and not the sums that come up during the processing of the loop.

Hi there aaronjcurtis,

I would suggest that you do not use “document.write()” for this project. :wonky:

Have a look at this example…

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>Add up the odd numbers.</title>

<style media="screen">
body {
    background-color: #f0f0f0;
    font: 1em/150% verdana, arial, helvetica, sans-serif;
 }

form {
    width: 16em;
    padding: 1em;
    margin: auto;
    border: 0.062em solid #999;
    border-radius: 1em;
    box-sizing: border-box;
    background-color: #fff;
    box-shadow: inset 0 0 1em rgba( 0, 0, 0, 0.3 ),
            0.5em 0.5em 0.5em rgba( 0, 0, 0, 0.3 );
 }

form input[type=text] {
    width: 3em;
 }

form button,form div {
    margin: 0.5em 0;
 }
</style>

</head>
<body>

 <form action="#">
  <label for="number">Your Number: </label><input id="number" type="text" required><br>
   <button>Sum It Up!</button>
    <div id="list"></div>
    <div id="total"></div>
 </form>

<script>
(function(d) {
   'use strict';

   d.getElementsByTagName( 'button' )[0].addEventListener( 'click', function(){

   var start = 1;
   var total = 0;
   var number = 0;
   
   number = d.getElementById( 'number' ).value;

   d.getElementById( 'list' ).textContent = 'the odd numbers are... ';

   while ( start <= number ){

         d.getElementById( 'list' ).textContent += start + ', ';
         total += start;
         start += 2;
     }
         d.getElementById( 'total' ).textContent = '...and their total is ' + total;
     }, false);
}(document));
</script>

</body>
</html>

coothead

Actually, the function from my snippet does exactly that: it returns the result without any side effects. The final line in the snippet logs the result to the console; if you want to .write() it to the document, you might do this as well (although I’d avoid that – it’ll clear the document).

I’d suggest to use a dedicated #result element (say) to output the result instead, and just change its .textContent. Like e.g.

var number = document.getElementById('number')
var result = document.getElementById('result')
var button = document.querySelector('button')

function sumOdds (n) {
  let sum = 0
  
  for (let i = 1; i <= n; i += 2) {
    sum += i
  }
  
  return sum
}

button.addEventListener('click', function () {
  result.textContent = sumOdds(number.value)
})

x-post

These days I would want to separate the process of generating the next number, from the process of totalling them up.

The next number can be generated using a generator function, that just yields the next number before increasing the value;

function* oddNumbers(limit) {
    let index = 1;
    while (index <= limit) {
       yield index;
       index += 2;
    }
}

One way to then handle that generator is to assign the function to a generating variable, and call .next()

const nextNumGenerator = oddNumbers(25);
let num = nextNumGenerator.next().value;
let total = 0;
while (num) {
  total += num;
  num = nextNumGenerator.next().value;
}

That works, but there’s a lot of complexity in there. Simpler is to use for...of which natively understands how to handle generators.

let total = 0;
for (let num of oddNumbers(25)) {
  total += num;
}

Even simpler than that though is to use the spread syntax:

let total = [...oddNumbers(25)]
    .reduce((sum, value) => sum += value);

But it’s inefficient to create a whole array of values when we are only going to reduce them down to a total.
Let’s instead use a generator that gives us the total value of summed odd numbers:

function* oddNumbersTotal(limit) {
    let index = 1;
    for (let total = 0; index <= limit; index += 2) {
       total += index;
       yield total;
    }
}

let total = 0;
for (total of oddNumbersTotal(25)) {}

But why are we iterating over all of the previous totals? Surely it’s easier to just calculate the value straight out.

How would we calculate the total of odd numbers? We can use two sets of odd numbers to figure this out.

S = 1 + 3 + ... + n-2 + n;
S = n + n-2 + ... + 3 + 1;
S2 = (n+1) + (n+1) + ... + (n+1) + (n+1)

How many of those (n+1)'s are there?
When n is 5, there would be three of them (1, 3, 5).
When n is 9, there would be 5 of them, so overall there are (n+1)/2 of them.

S2 = (n+1) * (n+1) / 2
S = 1/2 (n+1) * (n+1) / 2

So, if we want the sum of odd numbers from 1 to 25, all we need to do is to just purely calculate the total using that formula.

function oddNumbersTotal(limit) {
    return 0.5 * (limit + 1) * (limit + 1) / 2;
}
const total = oddNumbersTotal(25);

Which could be simplified even further.

S = 1/2 (n+1) * (n+1) / 2
S = (n+1) / 2 * (n+1) / 2
S = ((n+1)/2) ^ 2
function oddNumbersTotal(limit) {
    // using the ((n+1)/2)² formula
    return Math.pow((limit + 1) / 2, 2);
}
const total = oddNumbersTotal(25);

There’s no need to involve loops or generating arrays of numbers when all you need is the total.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.