My exercise is to write the Fizz Buzz problem with the following in mind:
- Use the latest up-to-date style and best practices for a C++17 compiler.
- Don’t just show that I can write a loop. Rather, illustrate some good engineering concepts, as much as can be done without making the code not-so-trivial.
The “good engineering” shown is
to separate the logic from I/O. The code does something, and is called by a UI of some kind or a test case checker. Most (all?) solutions I see of this simply print to standard output in the middle of the logic.
Don’t repeat blocks of code where only a couple values change. Instead, store the values and loop over them.
Be mindful of future enhancements (code always gets more complex over time) and localization.
I think I was successful in that point 2 makes the code simpler and shorter. Implementing point 1 seems to be free — appending vs outputting, same thing.
#include <utility> #include <iostream> #include <boost/range/irange.hpp> using std::string; constexpr std::pair<int, const char*> fbchart[]{ { 3, "Fizz" }, { 5, "Buzz" }, // standard FizzBuzz { 7, "Boom" } // easily generalized and extended by adding to this chart! }; // Game Impl 1 : Simple stateless function string fbencode (int n) { string retval; for (auto&[div, codeword] : fbchart) { if ((n%div)==0) retval += codeword; } if (retval.empty()) retval= std::to_string(n); return retval; } // and to drive it: int main() { using boost::irange; for (auto n : irange(1,101)) { cout << n << ": " << fbencode(n) << '\n'; } } In the main, I avoided a legacy for-loop by using Boost.Range 2.0. That is tried and true for production work. I’ve not tried to get the latest Visual Studio compiler drop to swallow Range-v3 yet.