Sprout/example/inv_fizzbuzz/main.cpp
2019-01-07 17:47:17 +09:00

96 lines
3.2 KiB
C++

/*=============================================================================
Copyright (c) 2011-2019 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <sprout/array.hpp>
#include <sprout/string.hpp>
#include <sprout/utility.hpp>
#include <sprout/container.hpp>
#include <sprout/range.hpp>
#include <sprout/range/algorithm.hpp>
#include <sprout/range/adaptor.hpp>
static constexpr auto token_table = sprout::make_array<sprout::string<8> >(
"Fizz", "Buzz", "Fizz", "Fizz", "Buzz", "Fizz", "FizzBuzz",
"Fizz", "Buzz", "Fizz", "Fizz", "Buzz", "Fizz"
);
static constexpr auto index_table = sprout::make_array<int>(
3, 5, 6, 9, 10, 12, 15,
18, 20, 21, 24, 25, 27
);
template<typename ForwardRange, typename Difference>
constexpr sprout::pair<int, int>
inv_fizzbuzz_impl(ForwardRange const& rng, Difference found) {
return found == sprout::size(token_table) ? sprout::pair<int, int>{0, 0}
: sprout::pair<int, int>{
index_table[found],
sprout::size(rng) / 7 * 15 + index_table[found + sprout::size(rng) % 7 - 1]
}
;
}
template<typename ForwardRange>
constexpr sprout::pair<int, int>
inv_fizzbuzz(ForwardRange const& rng) {
return sprout::size(rng) <= 7
|| (sprout::size(sprout::range::find_end<sprout::range::return_found_end>(rng, rng | sprout::adaptors::taken(7))) == 7 + sprout::size(rng) % 7
&& sprout::range::equal(
rng | sprout::adaptors::taken(sprout::size(rng) % 7),
rng | sprout::adaptors::dropped(sprout::size(rng) - sprout::size(rng) % 7)
)
)
? inv_fizzbuzz_impl(
rng,
sprout::size(sprout::range::search<sprout::range::return_begin_found>(token_table, rng | sprout::adaptors::taken(7)))
)
: sprout::pair<int, int>{0, 0}
;
}
#include <iostream>
template<typename ForwardRange, typename Pair>
void print(ForwardRange const& input, Pair const& answer) {
std::cout << "input : ";
for (auto const& e : input) {
std::cout << e << ' ';
}
std::cout << std::endl;
std::cout << "answer: (" << answer.first << ',' << answer.second << ')' << std::endl;
}
int main() {
{
constexpr auto input = sprout::make_array<sprout::string<8> >(
"Fizz", "FizzBuzz", "Fizz", "Buzz"
);
constexpr auto answer = inv_fizzbuzz(input);
static_assert(answer.first == 12 && answer.second == 20, "answer is (12,20)");
print(input, answer);
}
{
constexpr auto input = sprout::make_array<sprout::string<8> >(
"FizzBuzz", "Fizz", "Buzz", "Fizz", "Fizz", "Buzz", "Fizz",
"FizzBuzz", "Fizz", "Buzz", "Fizz", "Fizz", "Buzz", "Fizz",
"FizzBuzz", "Fizz", "Buzz"
);
constexpr auto answer = inv_fizzbuzz(input);
static_assert(answer.first == 15 && answer.second == 50, "answer is (15,50)");
print(input, answer);
}
{
constexpr auto input = sprout::make_array<sprout::string<8> >(
"Fizz", "FizzBuzz", "Buzz"
);
constexpr auto answer = inv_fizzbuzz(input);
static_assert(answer.first == 0 && answer.second == 0, "answer is (0,0)");
print(input, answer);
}
}