2025-03-20 22:23:41 +01:00
|
|
|
#include <vector>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <string_view>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <numeric>
|
|
|
|
|
#include <execution>
|
|
|
|
|
#include <format>
|
2025-03-20 21:44:22 +01:00
|
|
|
|
|
|
|
|
const std::vector<std::wstring_view> BAD_WORDS = {
|
|
|
|
|
L"recovery",
|
|
|
|
|
L"techie",
|
|
|
|
|
L"http",
|
|
|
|
|
L"https",
|
|
|
|
|
L"digital",
|
|
|
|
|
L"hack",
|
|
|
|
|
L"::",
|
|
|
|
|
L"//",
|
|
|
|
|
L"com",
|
|
|
|
|
L"@",
|
|
|
|
|
L"crypto",
|
|
|
|
|
L"bitcoin",
|
|
|
|
|
L"wallet",
|
|
|
|
|
L"hacker",
|
|
|
|
|
L"welcome",
|
|
|
|
|
L"whatsapp",
|
|
|
|
|
L"email",
|
|
|
|
|
L"cryptocurrency",
|
|
|
|
|
L"stolen",
|
|
|
|
|
L"freeze",
|
|
|
|
|
L"quick",
|
|
|
|
|
L"crucial",
|
|
|
|
|
L"tracing",
|
|
|
|
|
L"scammers",
|
|
|
|
|
L"expers",
|
|
|
|
|
L"hire",
|
|
|
|
|
L"century",
|
|
|
|
|
L"transaction",
|
|
|
|
|
L"essential",
|
|
|
|
|
L"managing",
|
|
|
|
|
L"contact",
|
|
|
|
|
L"contacting",
|
|
|
|
|
L"understanding",
|
|
|
|
|
L"assets",
|
|
|
|
|
L"funds",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct AnalysisResult {
|
|
|
|
|
std::size_t totalWordCount = 0;
|
|
|
|
|
std::size_t totalCapitalizedCount = 0;
|
|
|
|
|
std::size_t totalSentenceCount = 0;
|
|
|
|
|
std::size_t totalNumberCount = 0;
|
|
|
|
|
std::size_t totalForbiddenCount = 0;
|
|
|
|
|
|
|
|
|
|
operator std::string() const {
|
|
|
|
|
return std::format(
|
|
|
|
|
"Word Count: {}\nCapitalized Count: {}\nSentence Count: {}\nNumber Count: {}\nForbidden Count: {}",
|
|
|
|
|
totalWordCount, totalCapitalizedCount, totalSentenceCount, totalNumberCount, totalForbiddenCount
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AnalysisResult operator+(const AnalysisResult &other) const {
|
|
|
|
|
return {
|
|
|
|
|
totalWordCount + other.totalWordCount,
|
|
|
|
|
totalCapitalizedCount + other.totalCapitalizedCount,
|
|
|
|
|
totalSentenceCount + other.totalSentenceCount,
|
|
|
|
|
totalNumberCount + other.totalNumberCount,
|
|
|
|
|
totalForbiddenCount + other.totalForbiddenCount
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-20 22:23:41 +01:00
|
|
|
// Overloaded operator<< for AnalysisResult
|
|
|
|
|
std::ostream& operator<<(std::ostream& os, const AnalysisResult& result) {
|
|
|
|
|
os << "Word Count: " << result.totalWordCount << "\n"
|
|
|
|
|
<< "Capitalized Count: " << result.totalCapitalizedCount << "\n"
|
|
|
|
|
<< "Sentence Count: " << result.totalSentenceCount << "\n"
|
|
|
|
|
<< "Number Count: " << result.totalNumberCount << "\n"
|
|
|
|
|
<< "Forbidden Count: " << result.totalForbiddenCount;
|
|
|
|
|
return os;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-20 21:44:22 +01:00
|
|
|
void check_word(const std::wstring &word, std::size_t &forbiddenCount) {
|
|
|
|
|
if (std::find(BAD_WORDS.begin(), BAD_WORDS.end(), word) != BAD_WORDS.end()) {
|
|
|
|
|
forbiddenCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AnalysisResult parseFile(const std::string_view &filename) {
|
|
|
|
|
std::wifstream file;
|
|
|
|
|
|
2025-03-20 22:23:41 +01:00
|
|
|
file.open(std::string(filename)); // Modified line
|
2025-03-20 21:44:22 +01:00
|
|
|
if (!file.is_open()) {
|
2025-03-20 22:23:41 +01:00
|
|
|
std::cout << "File doesn't exist: " << filename << std::endl;
|
2025-03-20 21:44:22 +01:00
|
|
|
return { };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AnalysisResult result{ };
|
|
|
|
|
|
|
|
|
|
bool inWord = false;
|
|
|
|
|
wchar_t c;
|
|
|
|
|
|
|
|
|
|
std::wstring word;
|
|
|
|
|
while (file.get(c)) {
|
|
|
|
|
if (c == '.') {
|
|
|
|
|
result.totalSentenceCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (std::isspace(c) || c == '.' || c == '?' || c == '!' || c == ';' || c == ':') {
|
|
|
|
|
inWord = false;
|
|
|
|
|
|
|
|
|
|
check_word(word, result.totalForbiddenCount);
|
|
|
|
|
word.clear();
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
if (!inWord) {
|
|
|
|
|
result.totalWordCount++;
|
|
|
|
|
if (std::isupper(c)) {
|
|
|
|
|
result.totalCapitalizedCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
inWord = true;
|
|
|
|
|
|
|
|
|
|
if (std::isdigit(c)) {
|
|
|
|
|
result.totalNumberCount++;
|
|
|
|
|
while (file.get(c) && std::isdigit(c)) { }
|
|
|
|
|
file.unget();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
word.push_back(c);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!word.empty()) {
|
|
|
|
|
check_word(word, result.totalForbiddenCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(const int argc, char *argv[]) {
|
|
|
|
|
if (argc < 2) {
|
2025-03-20 22:23:41 +01:00
|
|
|
std::cout << "Usage: " << argv[0] << " <file1> <file2> ... <fileN>" << std::endl;
|
2025-03-20 21:44:22 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const AnalysisResult result = std::transform_reduce(std::execution::par, std::next(argv), argv + argc, AnalysisResult{ }, std::plus{ },
|
|
|
|
|
parseFile
|
|
|
|
|
);
|
|
|
|
|
|
2025-03-20 22:23:41 +01:00
|
|
|
std::cout << result << std::endl; // This will now work
|
2025-03-20 21:44:22 +01:00
|
|
|
return 0;
|
2025-03-20 22:23:41 +01:00
|
|
|
}
|