HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppModerate

Yet another FizzBuzz

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
yetanotherfizzbuzz

Problem

Since today is apparently a good day for...unlikely FizzBuzz implementations, I decided to contribute another, this one in C++:

#include 
#include 
#include 
#include "xrange.h"

int main() {
    std::vector > funcs {
        [](int i) { std::cout << i << "\n"; },
        [](int i) { std::cout << "fizz\n";  },
        [](int i) { std::cout << "buzz\n";  },
        [](int i) { std::cout << "fizzbuzz\n"; }
    };

    auto test = [](int i){return (i % 3 == 0) + 2 * (i % 5 == 0); };

    for (auto i : xrange(1, 101))
        funcs[test(i)](i);
}


This uses the same xrange I posted in a previous answer.

I'd be particularly interested in eliminating having to use test, but a sequence like: [[ is parsed as introducing an attribute rather than using the return from a lambda as an index (and inserting white space doesn't seem to help). I could use .at() instead, but that imposes runtime overhead I'd also rather avoid.

Solution

I'd be inclined to make a simple fixed array instead of a std::vector for funcs:

const std::function funcs[] {
    [](int i) { std::cout << i << "\n"; },
    [](int ) { std::cout << "fizz\n";  },
    [](int ) { std::cout << "buzz\n";  },
    [](int ) { std::cout << "fizzbuzz\n"; }
};


This is useful because it eliminates the overhead of memory allocations for a std::vector and the calls for constructor and destructor. As an embedded systems guy, I tend to think about whether code can be in ROM rather than RAM, and whether work can be done at compile-time rather than run-time.

Note, too that I've omitted the variable name for the last three lambdas. There's no real difference except that it prevents the compiler from generating a warning about "unused parameter i" in those three lines.

Also, I think you're overthinking the lambda. The test lambda isn't really necessary at all since you can call it like this:

funcs[ (i % 3 == 0) + 2 * (i % 5 == 0) ](i);


So (without xrange.h, although one could use that also) it would look like this:

#include 
#include 

int main() {
    const std::function funcs[] {
        [](int i) { std::cout << i << "\n"; },
        [](int ) { std::cout << "fizz\n";  },
        [](int ) { std::cout << "buzz\n";  },
        [](int ) { std::cout << "fizzbuzz\n"; }
    };

    for (int i=1; i <= 100; ++i)
        funcs[ (i % 3 == 0) + 2 * (i % 5 == 0) ](i);
}

Code Snippets

const std::function<void(int i)> funcs[] {
    [](int i) { std::cout << i << "\n"; },
    [](int ) { std::cout << "fizz\n";  },
    [](int ) { std::cout << "buzz\n";  },
    [](int ) { std::cout << "fizzbuzz\n"; }
};
funcs[ (i % 3 == 0) + 2 * (i % 5 == 0) ](i);
#include <iostream>
#include <functional>

int main() {
    const std::function<void(int i)> funcs[] {
        [](int i) { std::cout << i << "\n"; },
        [](int ) { std::cout << "fizz\n";  },
        [](int ) { std::cout << "buzz\n";  },
        [](int ) { std::cout << "fizzbuzz\n"; }
    };

    for (int i=1; i <= 100; ++i)
        funcs[ (i % 3 == 0) + 2 * (i % 5 == 0) ](i);
}

Context

StackExchange Code Review Q#56867, answer score: 15

Revisions (0)

No revisions yet.