diff --git a/conv/CMakeLists.txt b/conv/CMakeLists.txt index 333af1f..e7dc96c 100644 --- a/conv/CMakeLists.txt +++ b/conv/CMakeLists.txt @@ -24,3 +24,6 @@ target_link_libraries(feat_dcode PRIVATE args) # ---- procedural of preprocessing add_executable(aprob_bmap common.hh aprob_bmap.cc) target_link_libraries(aprob_bmap PRIVATE args) + +add_executable(bmap_fmap common.hh bmap_fmap.cc) +target_link_libraries(bmap_fmap PRIVATE args) diff --git a/conv/bmap_fmap.cc b/conv/bmap_fmap.cc new file mode 100644 index 0000000..23c5e27 --- /dev/null +++ b/conv/bmap_fmap.cc @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "common.hh" + + +namespace param { +using namespace ::args; + +ArgumentParser parser { + "converter: bmap -> fmap" +}; +HelpFlag help { + parser, "help", "display this menu", {'h', "help"}, +}; + +ValueFlag fnum { + parser, "64", "number of feature kinds", {"fnum"}, 64, +}; + +} // namespace param + + +static bool NextCombination(auto begin, auto end) noexcept { + auto first = std::find(begin, end, true); + if (first == end) { + return false; + } + if (!NextCombination(first+1, end)) { + if (first+1 >= end || *(first+1)) { + return false; + } + const auto n = std::count(first+2, end, true); + std::fill(first+2 , first+2+n, true); + std::fill(first+2+n, end , false); + *first = false; + *(first+1) = true; + } + return true; +} + +static void Exec() { + const auto bmap = ReadMatrix(std::cin); + const auto fnum = args::get(param::fnum); + + for (uint32_t t = 0; t < bmap.size(); ++t) { + const auto& blocks = bmap[t]; + const auto bnum = static_cast(blocks.size()); + Enforce(fnum < pow(bnum, 2), "number of blocks is too less"); + + std::vector C(bnum); + uint32_t r = 0; + for (uint32_t f = 0; f < fnum; ++f) { + if (!NextCombination(C.begin(), C.end())) { + ++r; + assert(r <= bnum); + std::fill(C.begin(), C.begin()+r, 1); + std::fill(C.begin()+r, C.end(), 0); + } + auto itr = C.begin(); + for (uint32_t i = 0; i < r; ++i, ++itr) { + itr = std::find(itr, C.end(), true); + if (itr >= C.end()) { + for (const auto& b : C) std::cout << !!b << ','; + std::cout << std::endl; + assert(false); + } + const auto idx = std::distance(C.begin(), itr); + std::cout << blocks[idx] << ' '; + } + std::cout << '\n'; + } + std::cout << "----\n"; + } +} + +int main(int argc, char** argv) +try { + param::parser.ParseCLI(argc, argv); + Exec(); + return EXIT_SUCCESS; +} catch (const args::Help&) { + std::cout << param::parser << std::endl; + return EXIT_SUCCESS; +} catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + return EXIT_FAILURE; +} +