#include #include #include #include #include #include #include "al_function.hpp" using namespace std; 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; typedef Function MyFunction; void test_function() { Function f_8(16); assert(("sizeof(sizeof(Function)", sizeof(Function)==2)); assert(("f_8(16) = 00010000", "00010000" == f_8.string())); assert(("f_8(15) = 00001111", "00001111" == Function(15).string())); assert(("converting 01001001", Function("01001001").string() == "01001001")); assert(("converting 00000000", Function("00000000").string() == "00000000")); assert(("converting 11111111", Function("11111111").string() == "11111111")); Function a(12); Function b(5); assert(("a = 00001100", a.string() == "00001100")); assert(("b = 00000101", b.string() == "00000101")); assert(("a ^ b = 00001001", (a xor b).string() == "00001001")); assert(("a | b = 00001101", (a or b).string() == "00001101")); assert(("a & b = 00000100", (a and b).string() == "00000100")); // no changed in this objects assert(("a = 00001100", a.string() == "00001100")); assert(("b = 00000101", b.string() == "00000101")); cout << "self-test passed" << endl; } vector get_linear_components() { vector res; if ( ARGS_COUNT == 3 ) { res.push_back(MyFunction("11111111")); // f = 1 res.push_back(MyFunction("00001111")); // f = x_1 res.push_back(MyFunction("00110011")); // f = x_2 res.push_back(MyFunction("01010101")); // f = x_3 } else if ( ARGS_COUNT == 4 ) { res.push_back(MyFunction("1111111111111111")); // f = 1 res.push_back(MyFunction("0000000011111111")); // f = x_1 res.push_back(MyFunction("0000111100001111")); // f = x_2 res.push_back(MyFunction("0011001100110011")); // f = x_3 res.push_back(MyFunction("0101010101010101")); // f = x_4 } else if ( ARGS_COUNT == 5 ) { res.push_back(MyFunction("11111111111111111111111111111111")); // f = 1 res.push_back(MyFunction("00000000000000001111111111111111")); // f = x_1 res.push_back(MyFunction("00000000111111110000000011111111")); // f = x_2 res.push_back(MyFunction("00001111000011110000111100001111")); // f = x_3 res.push_back(MyFunction("00110011001100110011001100110011")); // f = x_4 res.push_back(MyFunction("01010101010101010101010101010101")); // f = x_5 } else { assert (("bad args_count", false)); } return res; } vector get_linear_combinations(const vector &linear_components) { set res(linear_components.begin(), linear_components.end()); bool is_added = true; while ( is_added ) { is_added = false; for (auto el_first: res) for (auto el_second: res) { bool is_added_now = res.insert(el_first xor el_second).second; is_added = is_added or is_added_now; } } return vector(res.begin(), res.end()); } vector get_all_monomials(const vector &linear_combinations) { set res(linear_combinations.begin(), linear_combinations.end()); bool is_added = true; while ( is_added ) { is_added = false; for (auto el_first: res) for (auto el_second: res) { bool is_added_now = res.insert(el_first and el_second).second; is_added = is_added or is_added_now; } } return vector(res.begin(), res.end()); } void fill_ranks(vector monomials) { vector used_map(FUNCTIONS_COUNT, 0); size_t functions_remains = FUNCTIONS_COUNT; ofstream f_out("out.txt"); vector< vector > ranks; ranks.push_back(vector()); // empty set ranks.push_back(monomials); // empty set cout << "rank index = " << 1 << endl; f_out << "rank index = " << 1 << endl; for (auto el: monomials) { --functions_remains; used_map.at(el.value()) = 1; f_out << el.string() << endl; } for (size_t rank_ind = 2; functions_remains; ++rank_ind) { ranks.push_back(vector()); cout << "rank index = " << rank_ind << " remains: " << functions_remains << endl; f_out << "rank index = " << rank_ind << endl; for (auto el_first: ranks.at(rank_ind - 1)) { for (auto el_second: ranks.at(1)) { MyFunction res_el = el_first xor el_second; if ( used_map[res_el.value()] == 0 ) { --functions_remains; used_map[res_el.value()] = 1; ranks.at(rank_ind).push_back(res_el); f_out << res_el.string() << " = " << el_first.string() << " + " << el_second.string() << "\n"; } } } if ( rank_ind - 1 > 1 ) ranks.at(rank_ind - 1).clear(); // больше не нужен cout << "size for rank " << rank_ind << " is " << ranks.at(rank_ind).size() << endl; } f_out.close(); } int main() { test_function(); cout << "using " << sizeof(Storage) << " bytes for storage" << endl; cout << FUNCTIONS_COUNT << " functions with " << ARGS_COUNT << " arguments and " << FUNCTION_LEN << " values" << endl; auto linear_components = get_linear_components(); cout << "Linear components: " << endl; for (auto el: linear_components) cout << el.string() << endl; auto linear_combinations = get_linear_combinations(linear_components); cout << "Linear combinations: " << linear_combinations.size() << endl; auto monomials = get_all_monomials(linear_combinations); cout << "Monomials: " << monomials.size() << endl; fill_ranks(monomials); return 0; }