mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2024-11-12 21:09:01 +00:00
96 lines
3.2 KiB
C++
96 lines
3.2 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2011-2014 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);
|
|
}
|
|
}
|