#include #include #include #include #include #include "defs.hpp" std::vector word_list; void build_word_list() { spdlog::info("building word list..."); std::ifstream is("data/words.txt"); std::string line; while (std::getline(is, line)) if (line.size() >= 5) word_list.push_back(line); } void stat_word(const DataSource &source) { timeit(fmt::format("stat_word({})", magic_enum::enum_name(source))); if (word_list.empty()) build_word_list(); std::vector passwords_vec; std::vector> words; std::vector result; std::map stat; auto eval = [](auto const &str) { std::string lower = tolower(str); std::vector ret; for (auto const &word : word_list) if (lower.find(word) != std::string::npos) ret.push_back(word); return ret; }; auto merge = [](auto const &l, auto const &r) { std::vector ret = l; ret.insert(ret.end(), r.begin(), r.end()); return ret; }; std::ranges::copy(passwords(source), std::back_inserter(passwords_vec)); words.resize(passwords_vec.size()); { timeit("split words"); std::transform(std::execution::par, passwords_vec.begin(), passwords_vec.end(), words.begin(), eval); } { timeit("merge results"); result = std::reduce(std::execution::par, words.begin(), words.end(), std::vector{}, merge); } for (auto const &word : result) stat[word]++; std::vector> vec(stat.begin(), stat.end()); std::sort(vec.begin(), vec.end(), [](auto const &lhs, auto const &rhs) { return lhs.second > rhs.second; }); for (auto const &[word, count] : vec | std::views::take(10)) spdlog::info("{}: {}", word, count); }