#include <iostream> #include <string> #include <sstream> #include <iterator> #include <stdexcept> class fizzbuzz { public: class const_iterator; typedef std::pair<int, int> range; fizzbuzz(const range& range = range(0, 100), int fizz_num = 3, int buzz_num = 5, const std::string& fizz_word = "Fizz", const std::string& buzz_word = "Buzz") : _range(range), _fizz_num(fizz_num), _buzz_num(buzz_num), _fizz_word(fizz_word), _buzz_word(buzz_word) {} range get_range() const { return _range; } int get_fizz_num() const { return _fizz_num; } int get_buzz_num() const { return _buzz_num; } std::string get_fizz_word() const { return _fizz_word; } std::string get_buzz_word() const { return _buzz_word; } int get_fizz_num() { return _fizz_num; } int get_buzz_num() { return _buzz_num; } std::string get_fizz_word() { return _fizz_word; } std::string get_buzz_word() { return _buzz_word; } void set_fizz_num(int num) { _fizz_num = num; } void set_buzz_num(int num) { _buzz_num = num; } void set_fizz_word(const std::string& word) { _fizz_word = word; } void set_buzz_word(const std::string& word) { _buzz_word = word; } const_iterator begin() const { return const_iterator(this); } const_iterator end() const { return const_iterator(this, true); } class const_iterator { public: typedef std::string value_type; typedef std::random_access_iterator_tag iterator_category; const_iterator(const fizzbuzz* fb, bool end=false) : _fb(fb) { if (end) { _current = _fb->get_range().second; } else { _current = _fb->get_range().first; } } const_iterator(const const_iterator& other) { *this = other; } const_iterator& operator=(const const_iterator& rhs) { if (this == &rhs) return *this; this->_fb = rhs._fb; this->_current = rhs._current; return *this; } value_type operator*() const { if ((_current < _fb->get_range().first) || (_current >= _fb->get_range().second)) throw std::out_of_range("fizz went buzz(t)"); return _fb->get_value(_current); } const_iterator& operator++() { _current++; return *this; } const_iterator& operator++(int) { _current++; return *this; } const_iterator& operator--() { _current--; return *this; } const_iterator& operator--(int) { _current--; return *this; } value_type operator[](int index) const { if ((index < _fb->get_range().first) || (index >= _fb->get_range().second)) throw std::out_of_range("fizz went buzz(t)"); return _fb->get_value(index); } bool operator==(const const_iterator& rhs) const { return rhs._current == _current; } bool operator!=(const const_iterator& rhs) const { return !(*this == rhs); } private: const fizzbuzz* _fb; int _current; }; private: bool fizz(int num) const { return num % _fizz_num == 0; } bool buzz(int num) const { return num % _buzz_num == 0; } const std::string get_value(int num) const { if (fizz(num) && buzz(num)) return _fizz_word + _buzz_word; if (fizz(num)) return _fizz_word; if (buzz(num)) return _buzz_word; std::stringstream s; s << num; return s.str(); } range _range; int _fizz_num; int _buzz_num; std::string _fizz_word; std::string _buzz_word; }; int main() { fizzbuzz fb(fizzbuzz::range(0, 100)); for (fizzbuzz::const_iterator it(fb.begin()); it != fb.end(); ++it) { std::cout << *it << std::endl; } std::cout << std::endl; std::cout << "And now for some random access..." << std::endl << std::endl; fizzbuzz::const_iterator it(fb.begin()); std::cout << "it[5]: " << it[5] << std::endl; std::cout << "it[15]: " << it[15] << std::endl; std::cout << "it[33]: " << it[33] << std::endl; std::cout << "it[49]: " << it[49] << std::endl; return 0; }
Sunday, March 21, 2010
FizzBuzz? SRSLY?
I was playing with Visual Studio 2010 and could not resist. Does that mean I'm not a good software developer? Anyway, without further ado, I present to you my ridiculously overengineered, gold-plated version of FizzBuzz in C++. Complete with lazy evaluation via a custom random access iterator. I'm not a C++ guru, so I probably got a lot of stuff wrong. If you take the time to write a comment about my mistakes, it won't have been a complete waste of time. Well, not for me at least.
Subscribe to:
Posts (Atom)