Advertisement
sementry

wordle_scores

Jun 7th, 2025
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.07 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <unordered_map>
  5. #include <cmath>
  6. #include <algorithm>
  7. #include <fstream>
  8. #include <codecvt>
  9.  
  10.  
  11. enum class LetterInfo {
  12.     GREY,
  13.     YELLOW,
  14.     GREEN
  15. };
  16.  
  17. LetterInfo get_letter_info(wchar_t letter, size_t pos, const std::wstring& ans) {
  18.     auto it = std::find(ans.begin(), ans.end(), letter);
  19.     if (it != ans.end()) {
  20.         return ans[pos] == letter ? LetterInfo::GREEN : LetterInfo::YELLOW;
  21.     } else {
  22.         return LetterInfo::GREY;
  23.     }
  24. }
  25.  
  26. std::vector<std::pair<wchar_t, LetterInfo>> try_guess(const std::wstring& guess, const std::wstring& ans) {
  27.     std::vector<std::pair<wchar_t, LetterInfo>> result;
  28.     for (size_t i = 0; i < guess.size(); ++i) {
  29.         result.emplace_back(guess[i], get_letter_info(guess[i], i, ans));
  30.     }
  31.     return result;
  32. }
  33.  
  34. bool compatible(const std::wstring& noun, const std::vector<std::pair<wchar_t, LetterInfo>>& guess_info) {
  35.     for (size_t i = 0; i < guess_info.size(); ++i) {
  36.         wchar_t letter = guess_info[i].first;
  37.         LetterInfo info = guess_info[i].second;
  38.  
  39.         bool in_noun = noun.find(letter) != std::wstring::npos;
  40.         if ((info == LetterInfo::GREY) ^ (!in_noun)) {
  41.             return false;
  42.         }
  43.  
  44.         if (info != LetterInfo::GREY) {
  45.             bool is_green = noun[i] == letter;
  46.             if ((info == LetterInfo::GREEN) ^ is_green) {
  47.                 return false;
  48.             }
  49.         }
  50.     }
  51.     return true;
  52. }
  53.  
  54. double score_fixed_guess(const std::vector<std::wstring>& nouns, const std::wstring& opener, const std::wstring& ans) {
  55.     auto guess_info = try_guess(opener, ans);
  56.     size_t total = nouns.size();
  57.     size_t total_compatible = 0;
  58.  
  59.     for (const auto& noun : nouns) {
  60.         if (compatible(noun, guess_info)) {
  61.             ++total_compatible;
  62.         }
  63.     }
  64.  
  65.     return std::log2(static_cast<double>(total) / total_compatible);
  66. }
  67.  
  68. double score(const std::vector<std::wstring>& nouns, const std::wstring& opener) {
  69.     double total_score = 0.0;
  70.     for (const auto& ans : nouns) {
  71.         total_score += score_fixed_guess(nouns, opener, ans);
  72.     }
  73.     return total_score / nouns.size();
  74. }
  75.  
  76. std::unordered_map<std::wstring, double> get_scores(const std::vector<std::wstring>& nouns) {
  77.     std::unordered_map<std::wstring, double> scores;
  78.     for (const auto& opener : nouns) {
  79.         scores[opener] = score(nouns, opener);
  80.  
  81.         if (scores.size() % 100 == 0) {
  82.             std::wcerr << "DBG: progress " << scores.size() << "/" << nouns.size() << "\n";
  83.         }
  84.     }
  85.     return scores;
  86. }
  87.  
  88. std::vector<std::wstring> read_nouns(std::string path) {
  89.     std::ifstream infile(path);
  90.  
  91.     if (!infile) {
  92.         std::cerr << "Error: Could not open file '" << path << "'\n";
  93.         return {};
  94.     }
  95.  
  96.     std::vector<std::wstring> nouns;
  97.     std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
  98.     std::string line;
  99.  
  100.     while (std::getline(infile, line)) {
  101.         if (!line.empty()) {
  102.             nouns.push_back(converter.from_bytes(line));
  103.         }
  104.     }
  105.  
  106.     infile.close();
  107.     return nouns;
  108. }
  109.  
  110. void write_scores(std::unordered_map<std::wstring, double> scores, std::string path) {
  111.     std::vector<std::pair<std::wstring, double>> scores_vec;
  112.     for (auto entry : scores) {
  113.         scores_vec.push_back(entry);
  114.     }
  115.     sort(scores_vec.begin(), scores_vec.end(), [](auto& a, auto& b) {return a.second > b.second; });
  116.  
  117.     std::ofstream outfile(path);
  118.  
  119.     if (!outfile) {
  120.         std::cerr << "Error: Could not open file '" << path << "'\n";
  121.         return;
  122.     }
  123.  
  124.     std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
  125.  
  126.     for (const auto& entry : scores_vec) {
  127.         outfile << entry.second << " " << converter.to_bytes(entry.first) << "\n";
  128.     }
  129.  
  130.     outfile.close();
  131. }
  132.  
  133. int main(int argc, char* argv[]) {
  134.     if (argc != 3) {
  135.         std::cerr << "Usage: opener_scores <words> <output>\n";
  136.         return 0;
  137.     }
  138.  
  139.     auto nouns = read_nouns(argv[1]);
  140.     auto scores = get_scores(nouns);
  141.     write_scores(scores, argv[2]);
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement