Guest User

LoL Worlds 2020 Groups Probabilities

a guest
Sep 10th, 2020
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.19 KB | None | 0 0
  1. #include <vector>
  2. #include <unordered_map>
  3. #include <string>
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <stdexcept>
  7. #include <cmath>
  8.  
  9. enum class Region
  10. {
  11.     CN,
  12.     EU,
  13.     KR,
  14.     NA,
  15.     PCS
  16. };
  17.  
  18. struct Team
  19. {
  20.     Region region;
  21.     std::string name;
  22. };
  23.  
  24. constexpr int N_POOLS = 4;
  25. constexpr int N_GROUPS = 4;
  26.  
  27. bool drawGroupsRec(const std::vector<std::vector<Team>>& teams,
  28.                     const std::vector<std::vector<int>>& drawOrder,
  29.                     std::vector<std::vector<int>>& teamsInGroups,
  30.                     int currentPool,
  31.                     int currentDrawInPool)
  32. {
  33.     if (currentDrawInPool == N_GROUPS)
  34.     {
  35.         if (++currentPool == N_POOLS)
  36.             return true;
  37.         currentDrawInPool = 0;
  38.     }
  39.  
  40.     auto& teamDrawn = teams[currentPool][drawOrder[currentPool][currentDrawInPool]];
  41.  
  42.     for (size_t i = 0; i < N_GROUPS; i++)
  43.     {
  44.         if (teamsInGroups[i][currentPool] >= 0)
  45.             continue;
  46.  
  47.         bool sameRegionInGroup = false;
  48.  
  49.         for (size_t j = 0; j < currentPool; j++)
  50.         {
  51.             auto& teamChecked = teams[j][teamsInGroups[i][j]];
  52.             if (teamDrawn.region == teamChecked.region)
  53.             {
  54.                 sameRegionInGroup = true;
  55.                 break;
  56.             }
  57.         }
  58.        
  59.         if (sameRegionInGroup)
  60.             continue;
  61.        
  62.         // Try to draw the rest with this placement. Rewind if it fails
  63.         teamsInGroups[i][currentPool] = drawOrder[currentPool][currentDrawInPool];
  64.  
  65.         if (drawGroupsRec(teams, drawOrder, teamsInGroups, currentPool, currentDrawInPool + 1))
  66.             return true;
  67.  
  68.         teamsInGroups[i][currentPool] = -1;
  69.     }
  70.  
  71.     return false;
  72. }
  73.  
  74. std::vector<std::vector<int>> drawGroups(const std::vector<std::vector<Team>>& teams,
  75.                                          const std::vector<std::vector<int>>& drawOrder)
  76. {
  77.     std::vector<std::vector<int>> teamsInGroups(N_GROUPS, std::vector<int>(N_POOLS, -1));
  78.  
  79.     if (!drawGroupsRec(teams, drawOrder, teamsInGroups, 0, 0))
  80.     {
  81.         throw std::logic_error{"No valid group possible"};
  82.     }
  83.    
  84.     return teamsInGroups;
  85. }
  86.  
  87. namespace std
  88. {
  89.     template<typename T>
  90.     struct hash<vector<T>>
  91.     {
  92.         size_t operator()(vector<T> const& vec) const
  93.         {
  94.             size_t seed = vec.size();
  95.             for(auto& i : vec) {
  96.                 seed ^= hash<T>{}(i) + 0xc4ceb9fe1a85ec53 + (seed << 6) + (seed >> 2);
  97.             }
  98.             return seed;
  99.         }
  100.     };
  101. }
  102.  
  103. constexpr int factorial(int n)
  104. {
  105.     int ret = 1;
  106.     for(int i = 1; i <= n; ++i)
  107.         ret *= i;
  108.     return ret;
  109. }
  110.  
  111. int main()
  112. {
  113.     const std::vector<std::vector<Team>> teamsInPools {
  114.         {{Region::CN, "TES"}, {Region::EU, "G2"}, {Region::KR, "DAMWON"}, {Region::NA, "TSM"}},
  115.         {{Region::CN, "JDG"}, {Region::EU, "FNC"}, {Region::KR, "DRX"}, {Region::CN, "SNG"}},
  116.         {{Region::PCS, "MACHI"}, {Region::EU, "RGE"}, {Region::KR, "GENG"}, {Region::NA, "FLY"}},
  117.         {{Region::CN, "LGD"}, {Region::EU, "MAD"}, {Region::PCS, "PSG"}, {Region::NA, "TL"}}
  118.     };
  119.  
  120.     std::vector<std::vector<int>> drawOrder (N_POOLS, {0, 1, 2, 3});
  121.     std::unordered_map<std::vector<int>, int> groupOccurrences;
  122.     std::unordered_map<std::vector<std::vector<int>>, int> groupCombinationOccurrences;
  123.  
  124.     do
  125.     {
  126.         do
  127.         {
  128.             do
  129.             {
  130.                 do
  131.                 {
  132.                     auto teamsInGroups = drawGroups(teamsInPools, drawOrder);
  133.                     std::vector<std::vector<int>> orderedGroups(N_GROUPS);
  134.                     for (size_t i = 0; i < N_GROUPS; i++)
  135.                     {
  136.                         orderedGroups[teamsInGroups[i][0]] = teamsInGroups[i];
  137.                         ++groupOccurrences[teamsInGroups[i]];
  138.                     }
  139.                     ++groupCombinationOccurrences[orderedGroups];
  140.                 } while (std::next_permutation(drawOrder[3].begin(), drawOrder[3].end()));
  141.             } while (std::next_permutation(drawOrder[2].begin(), drawOrder[2].end()));
  142.         } while (std::next_permutation(drawOrder[1].begin(), drawOrder[1].end()));
  143.     } while (std::next_permutation(drawOrder[0].begin(), drawOrder[0].end()));
  144.  
  145.     const double nPermutations = std::pow(factorial(N_GROUPS), N_POOLS);
  146.  
  147.     std::cout.precision(2);
  148.     std::cout << std::fixed;
  149.  
  150.     for (const auto& [groupCombination, occurrence] : groupCombinationOccurrences)
  151.     {
  152.         std::cout << "Group combination occurs " << 100 * occurrence / nPermutations << "% of the time\n";
  153.         for (const auto& group : groupCombination)
  154.         {
  155.             for (int i = 0; i < group.size(); ++i)
  156.             {
  157.                 std::cout << teamsInPools[i][group[i]].name << ' ';
  158.             }
  159.             std::cout << '\n';
  160.         }
  161.     }
  162.  
  163.     std::cout << '\n';
  164.     for (const auto& [group, occurrence] : groupOccurrences)
  165.     {
  166.         std::cout << "Group occurs " << 100 * occurrence / nPermutations << "% of the time\n";
  167.         for (int i = 0; i < group.size(); ++i)
  168.         {
  169.             std::cout << teamsInPools[i][group[i]].name << ' ';
  170.         }
  171.         std::cout << '\n';
  172.     }
  173.    
  174.     return 0;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment