diff --git a/main.cpp b/main.cpp index 74b7699..01aaa58 100644 --- a/main.cpp +++ b/main.cpp @@ -16,6 +16,7 @@ typedef uint16_t Storage; const size_t ARGS_COUNT = 4; const size_t FUNCTION_LEN = 1ll << ARGS_COUNT; const size_t FUNCTIONS_COUNT = 1ll << FUNCTION_LEN; +const bool ONLY_CREATE_CLASSES = true; typedef Function MyFunction; typedef BoolSquareMatrix MyMatrix; @@ -242,6 +243,51 @@ string preprocess_monom(string monom) { return monom; } +inline bool exists_test0 (const std::string& name) { + ifstream f(name.c_str()); + return f.good(); +} + + +string get_out_file_name(size_t rank_ind) { + return string("base_" + to_string(ARGS_COUNT) + "_rank_" + to_string(rank_ind) + ".txt"); +} + +size_t recover_ranks(vector< vector >& ranks, vector& used_map, size_t& functions_remains) { + for (size_t rank_ind = 2; true; ++rank_ind) { + ifstream f_in(get_out_file_name(rank_ind).c_str(), std::ios::binary); + if ( not f_in.good() ) + return rank_ind; + ranks.push_back(vector()); + while ( not f_in.eof() and f_in.good() ) { + char buf[sizeof(Storage)]; + f_in.read(buf, sizeof(Storage)); + Storage function_value = *reinterpret_cast(buf); + MyFunction f(function_value); + if (used_map.at(f.value())) + continue; + used_map.at(f.value()) = rank_ind; + --functions_remains; + ranks.back().push_back(f); + } + } +} + +void save_rank(size_t rank_ind, vector& rank_items) { + ofstream f_out(get_out_file_name(rank_ind).c_str(), ios::binary); + for (auto f: rank_items) { + Storage function_value = f.value(); + f_out.write(reinterpret_cast(&function_value), sizeof(function_value)); + } +} + + +void clean_trash_ranks(vector< vector >& ranks) { + for (size_t rank_ind = 2; rank_ind < ranks.size() - 1; ++rank_ind) + ranks.at(rank_ind).clear(); +} + + void fill_ranks(vector monomials) { vector used_map(FUNCTIONS_COUNT, 0); size_t functions_remains = FUNCTIONS_COUNT; @@ -255,30 +301,61 @@ void fill_ranks(vector monomials) { --functions_remains; used_map.at(el.value()) = 1; } - size_t total_ranks = 1; - for (total_ranks = 1; functions_remains; ++total_ranks) { - ranks.push_back(vector()); + size_t total_ranks = recover_ranks(ranks, used_map, functions_remains); + clean_trash_ranks(ranks); + cout << "recovered to " << total_ranks << endl; + cout << "current ranks: " << endl; + for (auto&& r: ranks) + cout << r.size() << " "; + cout << endl; + for (; functions_remains; ++total_ranks) { cout << "rank index = " << total_ranks << " remains: " << functions_remains << endl; - for (auto el_first: ranks.at(total_ranks - 1)) { - for (auto el_second: ranks.at(1)) { + vector temp_used_map(FUNCTIONS_COUNT, 0); + for (size_t ind_first = 0; ind_first != ranks[1].size(); ++ind_first) { + if ( ind_first % 20 == 0 ) { + for (auto&& r: ranks) + cout << r.size() << " "; + cout << endl; + cout << 100. * ind_first / ranks[1].size() << "% for " << ranks[1].size() + << " x " << ranks.back().size() << endl; + } + const auto el_first = ranks[1][ind_first]; + for (auto el_second: ranks.back()) { MyFunction res_el = el_first xor el_second; - if ( used_map[res_el.value()] == 0 ) { - --functions_remains; - - function_formulas[res_el.value()] = - preprocess_monom(function_formulas[el_first.value()]) + - " + " + preprocess_monom(function_formulas[el_second.value()]); - - used_map.at(res_el.value()) = total_ranks; - ranks.at(total_ranks).push_back(res_el); + if constexpr ( not ONLY_CREATE_CLASSES ) { + if ( used_map[res_el.value()] == 0 ) { + function_formulas[res_el.value()] = + preprocess_monom(function_formulas[el_first.value()]) + + " + " + preprocess_monom(function_formulas[el_second.value()]); + } } + temp_used_map[res_el.value()] = total_ranks; } } - if ( total_ranks - 1 > 1 ) - ranks.at(total_ranks - 1).clear(); // больше не нужен + + ranks.push_back(vector()); + clean_trash_ranks(ranks); + for (size_t func_ind = 0; func_ind < temp_used_map.size(); ++func_ind) { + if (not temp_used_map[func_ind] or used_map[func_ind] != 0) + continue; + --functions_remains; + auto cur_fn = MyFunction(func_ind); + auto val = cur_fn.value(); + if (val >= used_map.size()) { + cout << val << " " << cur_fn.string() << endl; + continue; + } + used_map[val] = total_ranks; + ranks.back().push_back(cur_fn); + } + save_rank(total_ranks, ranks.back()); cout << "size for rank " << total_ranks << " is " << ranks.at(total_ranks).size() << endl; } + if constexpr ( ONLY_CREATE_CLASSES ) { + return; + } + auto possible_tranformations = get_good_matrices(); cout << "Total " << possible_tranformations.size() << " linear tranformations" << endl;