#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:
Comments (Atom)