-1

I am typing a program in c++ where it takes a number and does the following.

  • If the number is a multiple of 3 but not 5, the output is Fizz.

  • If the number is a multiple of 5 but not 3, the output is Buzz.

  • If the number is a multiple of both 5 and 3, the output is FizzBuzz.

  • If the number is neither a multiple of 3 or 5, it just prints out the a number.

Whenever I compile the code with 15 as the test input, instead of getting the expected output:

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz

I instead get this

FizzBuzz
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz

My code is as follows:

#include <bits/stdc++.h>
#include <iostream>

using namespace std;

string ltrim(const string &);
string rtrim(const string &);




void fizzBuzz(int n) {
    
    for(int i = 0; i <= n; i++)
    {
        if(i % 3 == 0 && i % 5 != 0)
        {
            cout << "Fizz" << endl;
        }
        
        if (i % 3 != 0 && i % 5 == 0)
        {
            cout << "Buzz" << endl;
        }
        
        if (i % 3 != 0 && i % 5 != 0)
        {
            cout << i << endl;
        }
        
        if (i % 3 == 0 && i % 5 == 0)
        {
            cout << "FizzBuzz" << endl;
        }
    }
     
}

int main()
{
    string n_temp;
    getline(cin, n_temp);

    int n = stoi(ltrim(rtrim(n_temp)));

    fizzBuzz(n);

    return 0;
}

string ltrim(const string &str) {
    string s(str);

    s.erase(
        s.begin(),
        find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace)))
    );

    return s;
}

string rtrim(const string &str) {
    string s(str);

    s.erase(
        find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(),
        s.end()
    );

    return s;
}

Would like to know what I'm doing wrong that's making the extra line in the output show up, any advice will be greatly appreciated!

  • 1
    0 is divisible by both 3 and 5. If you don't want `fizzbuzz` to print a line for `i=0`, don't include `i=0` in the for loop. – Brian61354270 Sep 20 '21 at 23:27
  • 2
    I recommend replacing whatever materials you are using to learn C++ with [a good book on C++](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). The code you have shown has a few of what we call [bad smells](https://en.wikipedia.org/wiki/Code_smell) associated with inferior educational resources. – user4581301 Sep 20 '21 at 23:28
  • Thank you, I was able to fix it by adding i != 0 to the final if statement. – user16961399 Sep 20 '21 at 23:29
  • 1
    On a side note: `string n_temp; getline(cin, n_temp); int n = stoi(ltrim(rtrim(n_temp)));` can be re-written as `int n; cin >> n; cin.ignore(numeric_limits::max(), '\n');` And `not1(ptr_fun(isspace))` would be better handled using a lambda instead: `[](unsigned char ch){ return !isspace(ch); }` – Remy Lebeau Sep 20 '21 at 23:29
  • Thanks to everyone who commented appreciate your inputs. – user16961399 Sep 20 '21 at 23:30
  • Side note about the history of Fizz Buzz: This isn't a question interviewers ask to see if you can write it. It's one they ask to see HOW you write it. If you go in with Fizz Buzz memorized and just write the sucker out, the interviewer learns you have a decent memory and nothing about your problem solving ability. Depending on the position they're filling and the time they have to rejig and ask a completely different question to get the information they need to make a good decision, that could cost you the job. – user4581301 Sep 20 '21 at 23:45

2 Answers2

2

For loop should start from 1.

void fizzBuzz(int n) {
    for(int i = 1; i <= n; i++){
        if(i % 3 == 0 && i % 5 != 0) cout << "Fizz" << endl;
        if (i % 3 != 0 && i % 5 == 0) cout << "Buzz" << endl;
        if (i % 3 != 0 && i % 5 != 0) cout << i << endl;
        if (i % 3 == 0 && i % 5 == 0) cout << "FizzBuzz" << endl;
    }  
}
JIN
  • 149
  • 2
  • 10
  • I ended up just revising my final if statement to the following ``` else if (i != 0 && i % 3 == 0 && i % 5 == 0) { cout << "FizzBuzz" << endl; } ``` and it works fine passes all the test cases, but I'll keep what you said in mind for next time. – user16961399 Sep 20 '21 at 23:35
  • Yes, it works too. However, it includes also unnecessary operations. Even if `i` is not zero, your program will always compare `i` with zero totally n times. It is not that critical though, these things can make your program heavier later, snowballing the unnecessary operations. – JIN Sep 20 '21 at 23:39
  • `else` is a really important keyword, and would be appropriate where two or more exclusive conditions exist. – Chris Sep 20 '21 at 23:40
  • @Chris Yes, right. If this program must be used like this without `else` keyword, then the `continue` keyword is powerful. – JIN Sep 20 '21 at 23:44
1

@JIN's answer is correct, because 0 is a multiple of both 3 and 5. However, I'd like to further suggest you change the order with which you check the conditions.

Currently you check if it's a multiple of 3, then a multiple of 5, then a multiple of neither, and then if it's a multiple of 15. This works, but we can be more efficient without coding if we check like so:

if (i % 3 == 0 && i % 5 == 0) {
    // Multiple of 15.
}
else if (i % 3 == 0) {
    // If we reach this stage and we know that i is divisible by 3, 
    // then we *know* the only reason it failed the first condition
    // is that it's *not* divisible by 5, so we don't need to check
    // that.
    // Multiple of 3.
}
else if (i % 5 == 0) {
    // As in the previous condition, if we're here, we know that
    // i is not a multiple of 3.
    // Multiple of 5.
}
else {
    // Must be a multiple of neither 3 nor 5.
}
Chris
  • 26,361
  • 5
  • 21
  • 42
  • Depending on what the interviewer is looking for, the test for 3 and 5 is a possible boobytrap. Set things up correctly and the test for 3 prints out fizz, the test for 5 prints out buzz, and you don't need a test for 3 and 5. – user4581301 Sep 20 '21 at 23:53
  • That's a fair point. But either that opens up the possibility for bugs of `i` changes in one of those conditionals, or the desired behavior may change in the future, and it'll be easier to affect that if all required outcomes have a separate branch. Or both! If I were an interviewer, I think I'd be skeptical of "cleverness." – Chris Sep 21 '21 at 00:20
  • Totally depends on what slot you need the candidate to fill. I don't use FizzBuzz for reasons I listed under the question. People come in with a solution memorized, and I learn nothing. Actually, I've found it better to ask questions about stuff totally unrelated to programming. If I find a great problem solver, I'll teach them C++ myself. – user4581301 Sep 21 '21 at 00:26
  • OK. Not myself. But I'll point 'em at some good reading. – user4581301 Sep 21 '21 at 00:54
  • That's a wise clarification. – Chris Sep 21 '21 at 00:56