| /* |
| Adapted from: |
| https://github.com/akalenuk/wordsandbuttons/blob/master/exp/cpp_magic_cubes/numbers.cpp |
| |
| This is free and unencumbered software released into the public domain. |
| |
| Anyone is free to copy, modify, publish, use, compile, sell, or |
| distribute this software, either in source code form or as a compiled |
| binary, for any purpose, commercial or non-commercial, and by any |
| means. |
| |
| In jurisdictions that recognize copyright laws, the author or authors |
| of this software dedicate any and all copyright interest in the |
| software to the public domain. We make this dedication for the benefit |
| of the public at large and to the detriment of our heirs and |
| successors. We intend this dedication to be an overt act of |
| relinquishment in perpetuity of all present and future rights to this |
| software under copyright law. |
| |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| OTHER DEALINGS IN THE SOFTWARE. |
| |
| For more information, please refer to <http://unlicense.org> |
| */ |
| |
| #include <chrono> |
| #include <iostream> |
| #include <string> |
| |
| using namespace std; |
| |
| // here you should implement your own magic checker. |
| // returns true if the square is magic, false otherwise |
| // |
| // 8 1 6 this is |
| // "816357492" = 3 5 7 a magic |
| // 4 9 2 square |
| // |
| auto magic_number = '5' * 3; |
| uint_fast64_t ideal_char_map = static_cast<uint_fast64_t>(0x1FF) << 49; |
| uint_fast64_t char_map_one = 1u; |
| bool check_if_magic(const std::string& square) { |
| if ((square[0] + square[1] + square[2] != magic_number) || |
| (square[3] + square[4] + square[5] != magic_number) || |
| (square[6] + square[7] + square[8] != magic_number) || |
| |
| (square[0] + square[3] + square[6] != magic_number) || |
| (square[1] + square[4] + square[7] != magic_number) || |
| (square[2] + square[5] + square[8] != magic_number) || |
| |
| (square[0] + square[4] + square[8] != magic_number) || |
| (square[2] + square[4] + square[6] != magic_number)) |
| return false; |
| |
| auto char_map = ideal_char_map; |
| for (auto i = 0u; i < 9; ++i) |
| char_map ^= char_map_one << square[i]; |
| if (char_map != 0) |
| return false; |
| |
| return true; |
| } |
| |
| // this generates all possible combinations of 1-9 cyphers |
| // that may or may not form a magic square |
| static string buffer = " "; |
| void generate_or_check(int index_or_check = 8) { |
| if (index_or_check == -1) { |
| if (check_if_magic(buffer)) |
| cout << buffer << " "; |
| return; |
| } |
| |
| for (auto i = 1u; i < 10; ++i) { |
| buffer[index_or_check] = '0' + i; |
| generate_or_check(index_or_check - 1); |
| } |
| } |
| |
| // this runs the generator and measures time |
| void magic_numbers_tests() { |
| auto start = std::chrono::system_clock::now(); |
| generate_or_check(); |
| auto end = std::chrono::system_clock::now(); |
| std::chrono::duration<double> difference = end - start; |
| std::cout << difference.count() << "\n\n"; |
| } |