2

//Script to find numbers that are the power of 3 and 5 from 1 to 100 using % Modulus operator - when it finds a number that can be the power of 3 or 5 it outupts FizzBuzz... example hosted on my blog http://chadcollins.com/find-numbers-that-are-the-power-of-3-and-5-from-1-to-100/

// this was an interview question, and I want to know how to optimize or improve this with "pure javascript".

<div id=out_put></div>


//from a list of 1 to 100 numbers, find the 3's and 5's using modulus
function findPowerOf(numList) {
    //setup the variables 
    var myModMatch1 = 3; //find numbers that have the power of 3
    var myModMatch2 = 5; //find numbers that have the power of 5
    var tempCheck1 = ""; //stores true or false based on myModMatch1
    var tempCheck2 = ""; //stores true or false based on myModMatch2
    var stringOut = ""; //concat string for output
    var numListStart = 1; //starting number list index
    var numListFinish = 100; //ending list index
    var numberList = []; //create the list of numbers
    for (var i = numListStart; i <= numListFinish; i++) {
        numberList.push(i);
    }
    for (i = 0; i < numberList.length; i++) { //loop on each number and check the modulus params
        console.log(numberList[i]);
        if ((numberList[i] % myModMatch1) === 0) { //check first modulus param
            console.log('houston, we have a match on a number modulus 3');
            tempCheck1 = "Fizz";
        }
        if ((numberList[i] % myModMatch2) === 0) {
            console.log('houston, we have a match on a number modulus 5');
            tempCheck2 = "Buzz";
        }
        if (tempCheck1 === "" && tempCheck2 === "") { //no modulus matches
            console.log("no modulus matches");
            stringOut += numberList[i] + "\n";
        }
        stringOut += tempCheck1 + tempCheck2 + "\n";
        tempCheck1 = ""; //clear both variables
        tempCheck2 = "";
    }
    //dynamically make a div
    var outDiv = document.createElement("div");
    outDiv.innerHTML = stringOut; //output the final loop values all at once
    document.getElementById('out_put').appendChild(outDiv); //update the view
}
findPowerOf(); // call our function
  • 5
    I'm voting to close this question as off-topic because it is an open-ended discussion question. It *might* be more suitable for http://codereview.stackexchange.com/ but check their [guidelines](http://codereview.stackexchange.com/help) first. – Quentin Jul 23 '15 at 08:51
  • rewrite it without variables or for loops – dandavis Jul 23 '15 at 08:53
  • @danavis - well, it's impossible to do without ANY variables, but they could be reduced, yes. – Vilx- Jul 23 '15 at 08:53
  • Its not off topic, I have tried to optimize this script and am asking for expert help? –  Jul 23 '15 at 08:55
  • @danavis please provide a code sample if you are capable... –  Jul 23 '15 at 08:56
  • the fizzbuzz question is a popular interview question, and Im interested to see how a skilled javascript developer could improve my script with pure javascript... not by using less chars etc, but with real thought here... forwarding me to another site isnt cool. Give it a try guys.. –  Jul 23 '15 at 08:57
  • @Vilx-, are you sure? ;) (assuming the iterator is not perceived as a variable) – Shomz Jul 23 '15 at 09:25
  • @Shomz - ahh, ok, then you can. I counted that as a variable also. – Vilx- Jul 23 '15 at 10:18

1 Answers1

0

You can remove pretty much all the variables and the function parameter (especially since you're not using the parameter at all). That will also remove one redundant loop.

You can optimize those three parallel ifs by doing one nested if-else.

With all that, you could reduce the code to about 30% of its current size.

Let me give it a shot:


My optimized version:

var div = document.getElementById('out_put');
for (var i = 1; i <= 100; i++) {
  if (i % 3 == 0 || i % 5 == 0) {
    if (i % 3 == 0) {
      div.innerHTML += "Fizz";
    }
    if (i % 5 == 0) {
      div.innerHTML += "Buzz";
    }
  } else {
    div.innerHTML += i;
  }
  div.innerHTML += '<br>';
}
<div id=out_put></div>

I've used one variable for the div element because selecting it on every iteration is a waste of resources.


Shorter/less readable version:

Here's an even shorter, commented and slighly less-readable version:

var div = document.getElementById('out_put');
for (var i = 1; i <= 100; i++) {
  if (i % 3 == 0 || i % 5 == 0) { // see if there's ANY match
    if (i % 3 == 0)               // check for 3
      div.innerHTML += "Fizz";
    if (i % 5 == 0)               // check for 5
      div.innerHTML += "Buzz";
  } else                          // otherwise just output the number
    div.innerHTML += i;
  div.innerHTML += '<br>';        // add a new line after each
}
<div id=out_put></div>

Insane version - one-liner:

(just for fun - don't ever do this!)

And if you really REALLY want to go crazy with this, you can do a few nested ternary conditionals inside the loop. Technically, a loop with a single line inside - but pretty much unreadable and will perform worse because I removed the DOM element reference variable, so it will do the element query on every iteration. :)

for (var i = 1; i <= 100; i++) 
  document.getElementById('out_put').innerHTML += ( (i % 3 == 0 || i % 5 == 0) ? ( ((i % 3 == 0) ? "Fizz" : "") + ((i % 5 == 0) ? "Buzz" : "") ) : i) + '<br>';
<div id=out_put></div>
Shomz
  • 37,421
  • 4
  • 57
  • 85
  • Are you willing to update the code? those are great points, and yes I never used the arg.. but I like your point about nested if... not sure it would work tho.. Are you willing to try yourself? or should i try and follow your points and see? Thanks for feedback this far tho! –  Jul 23 '15 at 08:59
  • You're welcome! Sure thing, just wrote you how I'd do it. The nested if seems redundant, but actually the if/else part is where we gain a few milliseconds of performance. – Shomz Jul 23 '15 at 09:03
  • 1
    Awesome job.... thank you!!!! Im new here so not sure I can upvote yet., but I will check this as answered at least... Thanks again for taking the time. Record time :) –  Jul 23 '15 at 09:05
  • Hahaha, no problem, man, I'm really glad I could help! :) Maybe someone will come up with something even more optimized though. – Shomz Jul 23 '15 at 09:06
  • Awesome man... also very cool.... no wonder I didnt get that particuliar contract job :) lol.. I learned something so thanks again. –  Jul 23 '15 at 09:11
  • You're welcome! Don't worry, you'll get the next job, just keep learning. – Shomz Jul 23 '15 at 09:12
  • Btw. see if you like the Insane version ;) – Shomz Jul 23 '15 at 09:20
  • Performance optimization: updating `innerHTML` every time is not the most efficient way either. Gather the results in an array and in the end do `document.getElementById('out_put').innerHTML=arr.join()`. You still get the same number of variables. – Vilx- Jul 23 '15 at 10:21
  • Have you tried googling? (query: short fizz buzz) https://gist.github.com/remy/961583 – psukys Jul 23 '15 at 10:44
  • @Vilx-, that's true. Btw. is array join faster than string concat in this case? – Shomz Jul 23 '15 at 11:09
  • @Shomz - well, that's the classical wisdom. If you need to concat a lot of strings, push them in an array and `.join()`. Perhaps in the latest browsers this isn't true anymore, I don't know. Try benchmarking or finding a benchmark on the web. – Vilx- Jul 23 '15 at 12:16
  • 1
    @Shomz ... Holy Moly! :) packed in one line.. pretty cool 'just for fun I know' but nice1. @ Vilx, thats a great tip too... Ill google a bench-marking tool, and take any recommendations you have if you wish to share. –  Jul 23 '15 at 13:52