Advertisement
tomdodd4598

Untitled

Sep 25th, 2021
1,378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.52 KB | None | 0 0
  1. #include <cstdint>
  2. #include <iomanip>
  3. #include <iostream>
  4. #include <set>
  5. #include <vector>
  6.  
  7. void bb1();
  8. void bb2();
  9. void bb3();
  10. void bb4();
  11.  
  12. typedef int_fast8_t i8;
  13. typedef int64_t i64;
  14. typedef uint64_t u64;
  15.  
  16. int main() {
  17.     int n;
  18.     std::cout << "Card count: ";
  19.     std::cin >> n;
  20.     std::cout << "\n";
  21.  
  22.     if (n < 1) std::cout << "Can not compute busy beaver function for less than 1 card!\n";
  23.     else if (n == 1) bb1();
  24.     else if (n == 2) bb2();
  25.     else if (n == 3) bb3();
  26.     else if (n == 4) bb4();
  27.     else std::cout << "Can not compute busy beaver function for more than 4 cards!\n";
  28.  
  29.     return 0;
  30. }
  31.  
  32. inline i8 spl(i64 raw) {
  33.     return (raw > 0l) - (raw <= 0l);
  34. }
  35.  
  36. inline size_t index(i64 pos) {
  37.     const i64 mask = pos >> 63;
  38.     const u64 mag = (pos + mask) ^ mask;
  39.     return static_cast<size_t>((mag << 1) - (pos < 0));
  40. }
  41.  
  42. inline void check(std::vector<i8>& vec, size_t idx) {
  43.     if (idx >= vec.size()) vec.resize(idx << 1, 0);
  44. }
  45.  
  46. inline size_t count(const std::vector<i8>& vec) {
  47.     size_t num = 0;
  48.     for (i8 c : vec) {
  49.         num += (c > 0);
  50.     }
  51.     return num;
  52. }
  53.  
  54. inline size_t fullhash(const std::vector<i8>& vec, i64 state, i8 in, size_t idx) {
  55.     size_t h = 5381 + vec.size();
  56.     for (i8 c : vec) {
  57.         h = ((h << 5) + h) + c;
  58.     }
  59.     h = ((h << 5) + h) + state;
  60.     h = ((h << 5) + h) + in;
  61.     return ((h << 5) + h) + idx;
  62. }
  63.  
  64. template <typename T>
  65. inline bool contains(const std::set<T> set, T& elem) {
  66.     return set.find(elem) != set.end();
  67. }
  68.  
  69. void bb1() {
  70.     constexpr size_t VECLIMIT = 4;
  71.     constexpr size_t SETLIMIT = 16;
  72.  
  73.     size_t score = 0;
  74.  
  75.     i64 perm = -1;
  76.     i64 card[1][2][3];
  77.  
  78.     while (++perm < 64) {
  79.         i64 valid = 0;
  80.         i64 state;
  81.         i64 c0 = perm / 8;
  82.         i64 c1 = perm % 8;
  83.  
  84.         card[0][0][0] = c0 & 1;
  85.         card[0][0][1] = spl(c0 & 2);
  86.         card[0][0][2] = state = c0 >> 2;
  87.         valid += (state < 1);
  88.  
  89.         card[0][1][0] = c1 & 1;
  90.         card[0][1][1] = spl(c1 & 2);
  91.         card[0][1][2] = state = c1 >> 2;
  92.         valid += (state < 1);
  93.  
  94.         if (!valid) continue;
  95.  
  96.         auto vec = std::vector<i8>(1, 0);
  97.         auto hashes = std::set<size_t>();
  98.  
  99.         state = 0;
  100.         i8 in = 0;
  101.         i64 pos = 0;
  102.         size_t hash, idx = 0;
  103.  
  104.         do {
  105.             if (vec.size() > VECLIMIT || hashes.size() > SETLIMIT || contains(hashes, hash = fullhash(vec, state, in, idx))) {
  106.                 state = -1;
  107.                 break;
  108.             }
  109.             else hashes.insert(hash);
  110.             idx = index(pos);
  111.             check(vec, idx);
  112.             in = vec[idx];
  113.             vec[idx] = static_cast<i8>(card[state][in][0]);
  114.             pos += card[state][in][1];
  115.             state = card[state][in][2];
  116.         }       while (state < 1);
  117.  
  118.         if (state > 0) score = std::max(score, count(vec));
  119.     }
  120.  
  121.     std::cout << "Score: " << score << "\n";
  122. }
  123.  
  124. void bb2() {
  125.     constexpr size_t VECLIMIT = 8;
  126.     constexpr size_t SETLIMIT = 32;
  127.  
  128.     size_t score = 0;
  129.  
  130.     i64 perm = -1;
  131.     i64 card[2][2][3];
  132.  
  133.     while (++perm < 20736) {
  134.         i64 valid = 0;
  135.         i64 state;
  136.         i64 c0 = perm / 1728;
  137.         i64 c1 = (perm / 144) % 12;
  138.         i64 c2 = (perm / 12) % 12;
  139.         i64 c3 = perm % 12;
  140.  
  141.         card[0][0][0] = c0 & 1;
  142.         card[0][0][1] = spl(c0 & 2);
  143.         card[0][0][2] = state = c0 >> 2;
  144.         valid += (state < 2);
  145.  
  146.         card[0][1][0] = c1 & 1;
  147.         card[0][1][1] = spl(c1 & 2);
  148.         card[0][1][2] = state = c1 >> 2;
  149.         valid += (state < 2);
  150.  
  151.         card[1][0][0] = c2 & 1;
  152.         card[1][0][1] = spl(c2 & 2);
  153.         card[1][0][2] = state = c2 >> 2;
  154.         valid += (state < 2);
  155.  
  156.         card[1][1][0] = c3 & 1;
  157.         card[1][1][1] = spl(c3 & 2);
  158.         card[1][1][2] = state = c3 >> 2;
  159.         valid += (state < 2);
  160.  
  161.         if (!valid) continue;
  162.  
  163.         auto vec = std::vector<i8>(1, 0);
  164.         auto hashes = std::set<size_t>();
  165.  
  166.         state = 0;
  167.         i8 in = 0;
  168.         i64 pos = 0;
  169.         size_t hash, idx = 0;
  170.  
  171.         do {
  172.             if (vec.size() > VECLIMIT || hashes.size() > SETLIMIT || contains(hashes, hash = fullhash(vec, state, in, idx))) {
  173.                 state = -1;
  174.                 break;
  175.             }
  176.             else hashes.insert(hash);
  177.             idx = index(pos);
  178.             check(vec, idx);
  179.             in = vec[idx];
  180.             vec[idx] = static_cast<i8>(card[state][in][0]);
  181.             pos += card[state][in][1];
  182.             state = card[state][in][2];
  183.         }       while (state < 2);
  184.  
  185.         if (state > 0) score = std::max(score, count(vec));
  186.     }
  187.  
  188.     std::cout << "Score: " << score << "\n";
  189. }
  190.  
  191. void bb3() {
  192.     std::cout << "This may take some time...\n0%";
  193.  
  194.     constexpr i64 PERMCOUNT = 16777216;
  195.     constexpr size_t VECLIMIT = 16;
  196.     constexpr size_t SETLIMIT = 64;
  197.  
  198.     size_t score = 0;
  199.  
  200.     i64 perm = -1;
  201.     i64 card[3][2][3];
  202.  
  203.     int progress = 0;
  204.  
  205.     while (++perm < PERMCOUNT) {
  206.         i64 valid = 0;
  207.         i64 state;
  208.         i64 c0 = perm / 1048576;
  209.         i64 c1 = (perm / 65536) % 16;
  210.         i64 c2 = (perm / 4096) % 16;
  211.         i64 c3 = (perm / 256) % 16;
  212.         i64 c4 = (perm / 16) % 16;
  213.         i64 c5 = perm % 16;
  214.  
  215.         card[0][0][0] = c0 & 1;
  216.         card[0][0][1] = spl(c0 & 2);
  217.         card[0][0][2] = state = c0 >> 2;
  218.         valid += (state < 3);
  219.  
  220.         card[0][1][0] = c1 & 1;
  221.         card[0][1][1] = spl(c1 & 2);
  222.         card[0][1][2] = state = c1 >> 2;
  223.         valid += (state < 3);
  224.  
  225.         card[1][0][0] = c2 & 1;
  226.         card[1][0][1] = spl(c2 & 2);
  227.         card[1][0][2] = state = c2 >> 2;
  228.         valid += (state < 3);
  229.  
  230.         card[1][1][0] = c3 & 1;
  231.         card[1][1][1] = spl(c3 & 2);
  232.         card[1][1][2] = state = c3 >> 2;
  233.         valid += (state < 3);
  234.  
  235.         card[2][0][0] = c4 & 1;
  236.         card[2][0][1] = spl(c4 & 2);
  237.         card[2][0][2] = state = c4 >> 2;
  238.         valid += (state < 3);
  239.  
  240.         card[2][1][0] = c5 & 1;
  241.         card[2][1][1] = spl(c5 & 2);
  242.         card[2][1][2] = state = c5 >> 2;
  243.         valid += (state < 3);
  244.  
  245.         if (!valid) continue;
  246.  
  247.         auto vec = std::vector<i8>(1, 0);
  248.         auto hashes = std::set<size_t>();
  249.  
  250.         state = 0;
  251.         i8 in = 0;
  252.         i64 pos = 0;
  253.         size_t hash, idx = 0;
  254.  
  255.         do {
  256.             if (vec.size() > VECLIMIT || hashes.size() > SETLIMIT || contains(hashes, hash = fullhash(vec, state, in, idx))) {
  257.                 state = -1;
  258.                 break;
  259.             }
  260.             else hashes.insert(hash);
  261.             idx = index(pos);
  262.             check(vec, idx);
  263.             in = vec[idx];
  264.             vec[idx] = static_cast<i8>(card[state][in][0]);
  265.             pos += card[state][in][1];
  266.             state = card[state][in][2];
  267.         }       while (state < 3);
  268.  
  269.         if (state > 0) score = std::max(score, count(vec));
  270.  
  271.         int new_progress = static_cast<int>(100.0 * perm / PERMCOUNT);
  272.         if (new_progress > progress) std::cout << "\r" << new_progress << "%";
  273.         progress = new_progress;
  274.     }
  275.  
  276.     std::cout << "\r100%\n\nScore: " << score << "\n";
  277. }
  278.  
  279. void bb4() {
  280.     std::cout << "This may take a very, very long time...\n0.00%";
  281.     std::cout << std::fixed << std::setprecision(2);
  282.  
  283.     constexpr i64 PERMCOUNT = 25600000000;
  284.     constexpr size_t VECLIMIT = 32;
  285.     constexpr size_t SETLIMIT = 128;
  286.  
  287.     size_t score = 0;
  288.  
  289.     i64 perm = -1;
  290.     i64 card[4][2][3];
  291.  
  292.     int progress = 0;
  293.  
  294.     while (++perm < 25600000000) {
  295.         i64 valid = 0;
  296.         i64 state;
  297.         i64 c0 = perm / 1280000000;
  298.         i64 c1 = (perm / 64000000) % 20;
  299.         i64 c2 = (perm / 3200000) % 20;
  300.         i64 c3 = (perm / 160000) % 20;
  301.         i64 c4 = (perm / 8000) % 20;
  302.         i64 c5 = (perm / 400) % 20;
  303.         i64 c6 = (perm / 20) % 20;
  304.         i64 c7 = perm % 20;
  305.  
  306.         card[0][0][0] = c0 & 1;
  307.         card[0][0][1] = spl(c0 & 2);
  308.         card[0][0][2] = state = c0 >> 2;
  309.         valid += (state < 4);
  310.  
  311.         card[0][1][0] = c1 & 1;
  312.         card[0][1][1] = spl(c1 & 2);
  313.         card[0][1][2] = state = c1 >> 2;
  314.         valid += (state < 4);
  315.  
  316.         card[1][0][0] = c2 & 1;
  317.         card[1][0][1] = spl(c2 & 2);
  318.         card[1][0][2] = state = c2 >> 2;
  319.         valid += (state < 4);
  320.  
  321.         card[1][1][0] = c3 & 1;
  322.         card[1][1][1] = spl(c3 & 2);
  323.         card[1][1][2] = state = c3 >> 2;
  324.         valid += (state < 4);
  325.  
  326.         card[2][0][0] = c4 & 1;
  327.         card[2][0][1] = spl(c4 & 2);
  328.         card[2][0][2] = state = c4 >> 2;
  329.         valid += (state < 4);
  330.  
  331.         card[2][1][0] = c5 & 1;
  332.         card[2][1][1] = spl(c5 & 2);
  333.         card[2][1][2] = state = c5 >> 2;
  334.         valid += (state < 4);
  335.  
  336.         card[3][0][0] = c6 & 1;
  337.         card[3][0][1] = spl(c6 & 2);
  338.         card[3][0][2] = state = c6 >> 2;
  339.         valid += (state < 4);
  340.  
  341.         card[3][1][0] = c7 & 1;
  342.         card[3][1][1] = spl(c7 & 2);
  343.         card[3][1][2] = state = c7 >> 2;
  344.         valid += (state < 4);
  345.  
  346.         if (!valid) continue;
  347.  
  348.         auto vec = std::vector<i8>(1, 0);
  349.         auto hashes = std::set<size_t>();
  350.  
  351.         state = 0;
  352.         i8 in = 0;
  353.         i64 pos = 0;
  354.         size_t hash, idx = 0;
  355.  
  356.         do {
  357.             if (vec.size() > VECLIMIT || hashes.size() > SETLIMIT || contains(hashes, hash = fullhash(vec, state, in, idx))) {
  358.                 state = -1;
  359.                 break;
  360.             }
  361.             else hashes.insert(hash);
  362.             idx = index(pos);
  363.             check(vec, idx);
  364.             in = vec[idx];
  365.             vec[idx] = static_cast<i8>(card[state][in][0]);
  366.             pos += card[state][in][1];
  367.             state = card[state][in][2];
  368.         }       while (state < 4);
  369.  
  370.         if (state > 0) score = std::max(score, count(vec));
  371.  
  372.         double percent = 100.0 * perm / PERMCOUNT;
  373.         int new_progress = static_cast<int>(100.0 * percent);
  374.         if (new_progress > progress) std::cout << "\r" << percent << "%";
  375.         progress = new_progress;
  376.     }
  377.  
  378.     std::cout << "\r100%\n\nScore: " << score << "\n";
  379. }
  380.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement