summaryrefslogtreecommitdiffstats
path: root/main.cpp
diff options
context:
space:
mode:
authorLeonetienne <leonetienne@hotmail.de>2022-02-09 03:47:43 +0100
committerLeonetienne <leonetienne@hotmail.de>2022-02-09 03:47:43 +0100
commit3133bc9d3920489cf221e3a8c7fa10da9a617cb6 (patch)
tree85c5c0fde5e38378906fb78277515cf5e438001e /main.cpp
parentb76db3ceab5a950bfa22bfed72964fbb8fbf6465 (diff)
Pwogwammed twe uwuifie
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp270
1 files changed, 269 insertions, 1 deletions
diff --git a/main.cpp b/main.cpp
index bc8f460..96e358a 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,6 +1,274 @@
#include <iostream>
+#include <StringTools/Stringtools.h>
+#include <string>
+#include <sstream>
+#include <functional>
+
+constexpr char UPPERCASE = (1<<5);
+constexpr char LOWERCASE = 0;
+
+bool IsUpper(char c) {
+ return !(c & (1<<5));
+}
+
+char MakeUpper(char c) {
+ if (IsUpper(c))
+ return c;
+ else
+ return c & ~(1<<5);
+}
+
+char MakeLower(char c) {
+ if (!IsUpper(c))
+ return c;
+ else
+ return c | (1<<5);
+}
+
+char CopySign(char sign, char c) {
+ if (IsUpper(sign))
+ return MakeUpper(c);
+ else
+ return MakeLower(c);
+}
+
+std::string ReplaceButKeepCapitalization(
+ const std::string& str,
+ std::string find,
+ const std::string& sub,
+ std::function<bool(const std::string&, int)> onlyIf = [](const std::string&, int){return true;}
+) {
+
+ // Quick accepts-and rejects
+ if (str.length() == 0)
+ return "";
+ else if (find.length() == 0)
+ return str;
+
+ std::stringstream ss;
+
+ // Better safe than sorry
+ find = StringTools::Lower(find);
+
+ for (std::size_t i = 0; i < str.length(); i++)
+ {
+ const std::string foundInText = str.substr(i, find.length());
+ const std::string foundInText_lower = StringTools::Lower(foundInText);
+ if (foundInText_lower == find)
+ {
+ // Advance i accordingly
+ i += foundInText.length()-1;
+
+ // Ask the callback if we should replace this one
+ if (onlyIf(foundInText, i))
+ {
+ // Here we've found our occurrence...
+ // We have three possible cases:
+ // 1: len(find) == len(sub), in this case we want to sync capitalization by index.
+ // 2: len(find) < len(sub), in this case we sync by index, BUT...
+ // 2.1: len(sub) - len(find) == 1, ...following characters of sub are lowercase
+ // 2.1: len(sub) - len(find) > 1, ...following characters of sub are the same case as the following char.
+ // Take find[-1] instead, if the following char is not a letter
+ // 3: len(find) > len(sub): sync capitalization by index
+
+ // We want to sync capitalization by index
+ // This accounts for both cases: 1 and 3
+ if (foundInText.length() >= sub.length())
+ {
+ for (std::size_t j = 0; j < sub.length(); j++)
+ {
+ const char cf = foundInText[j];
+ const char cs = sub[j];
+
+ ss << CopySign(cf, cs);
+ }
+ }
+
+ // in this case we sync by index, BUT...
+ else if (foundInText.length() < sub.length())
+ {
+ char followingCharsSign = 0;
+ bool doHaveFollowingChar = false;
+ // Do we even have a following char?
+ if (str.length() >= i + foundInText.length() + 1)
+ {
+ const char followingChar = str[i + foundInText.length()];
+
+ // Is it a letter?
+ if ((followingChar >= 'a' && followingChar <= 'z') ||
+ (followingChar >= 'A' && followingChar <= 'Z'))
+ {
+ // Copy its sign
+ followingCharsSign = followingChar & (1 << 5);
+ doHaveFollowingChar = true;
+ }
+ }
+
+ // ... following characters of sub are lowercase, or the same sign of the following character
+ if (sub.length() - foundInText.length() == 1)
+ {
+ ss << CopySign(foundInText[0], sub[0]);
+
+ for (std::size_t j = 1; j < sub.length(); j++)
+ {
+ const char charSignToUse = doHaveFollowingChar ? followingCharsSign : LOWERCASE;
+ ss << CopySign(charSignToUse, sub[j]);
+ }
+ }
+
+ // ...following characters of sub are the same case as the following char.
+ // Take find[-1] instead, if the following char is not a letter
+ else if (sub.length() - foundInText.length() > 1)
+ {
+ char lastCharCharSign = 0;
+
+ for (std::size_t j = 0; j < sub.length(); j++)
+ {
+ const char cs = sub[j];
+
+ // Do we still have chars of 'find' left?
+ if (j < foundInText.length()) {
+ const char cf = foundInText[j];
+ lastCharCharSign = cf & (1 << 5);
+ }
+
+ const char charSignToUse = doHaveFollowingChar ? followingCharsSign : lastCharCharSign;
+ ss << CopySign(charSignToUse, cs);
+ }
+ }
+ }
+ }
+ else
+ {
+ // We do not have an occurrence... just insert the char as is
+ ss << str[i];
+ }
+ }
+ else
+ {
+ // We do not have an occurrence... just insert the char as is
+ ss << str[i];
+ }
+ }
+
+ return ss.str();
+}
+
+std::string MakeUwu(std::string boringString) {
+ // Easy ones first
+ // none, lol
+
+ // Slightly more complex... Multichar replacements, but we have to keep capitalization...
+ boringString = ReplaceButKeepCapitalization(boringString, "th", "tw");
+ boringString = ReplaceButKeepCapitalization(boringString, "you", "chou");
+ boringString = ReplaceButKeepCapitalization(boringString, "ove", "uv");
+ boringString = ReplaceButKeepCapitalization(boringString, "up", "uwp");
+
+ // Replace N with Ny, but only if succeeded by a vowel
+ boringString = ReplaceButKeepCapitalization(
+ boringString,
+ "n",
+ "ny",
+ [boringString](const std::string& found, int index)
+ {
+ // Don't replace, if we are on the last char
+ if (index == boringString.length() - 1)
+ return false;
+
+ // Only replace if the next char is a vowel
+ const std::string vowels = "euioa";
+ const char nextChar = MakeLower(boringString[index + found.length()]);
+
+ // Is this a vowel?
+ for (const char vowel : vowels)
+ if (vowel == nextChar)
+ return true;
+
+ // Else, don't replace
+ return false;
+ }
+ );
+
+ // Replace R with W, but only if not preceded by a vowel
+ boringString = ReplaceButKeepCapitalization(
+ boringString,
+ "r",
+ "w",
+ [boringString](const std::string& found, int index)
+ {
+ // Do replace, if we are on the first char
+ if (index == 0)
+ return true;
+
+ // Only replace if the last char is not a vowel
+ const std::string vowels = "euioa";
+ const char lastChar = MakeLower(boringString[index - 1]);
+
+ // Is this a vowel?
+ for (const char vowel : vowels)
+ if (vowel == lastChar)
+ return false;
+
+ // Else, replace
+ return true;
+ }
+ );
+
+ // Replace R with nothing, but only if preceded by a vowel
+ boringString = ReplaceButKeepCapitalization(
+ boringString,
+ "r",
+ "",
+ [boringString](const std::string& found, int index)
+ {
+ // Do replace, if we are on the first char
+ if (index == 0)
+ return true;
+
+ // Only replace if the last char is not a vowel
+ const std::string vowels = "euioa";
+ const char lastChar = MakeLower(boringString[index - 1]);
+
+ // Is this a vowel?
+ for (const char vowel : vowels)
+ if (vowel == lastChar)
+ return true;
+
+ // Else, don't replace
+ return false;
+ }
+ );
+
+
+ // Replace L with W, but only if not followed or preceded by another L
+ boringString = ReplaceButKeepCapitalization(
+ boringString,
+ "l",
+ "w",
+ [boringString](const std::string& found, int index)
+ {
+ const char lastChar = MakeLower(boringString[index - 1]);
+ const char nextChar = MakeLower(boringString[index + found.length()]);
+
+ return (lastChar != 'l') && (nextChar != 'l');
+ }
+ );
+
+
+ // Also replace some ascii-"emojis'
+ boringString = StringTools::Replace(boringString, ":)", "UwU :D");
+ boringString = StringTools::Replace(boringString, ":-)", "UwwwU :D");
+ boringString = StringTools::Replace(boringString, "lol", "XDD");
+ boringString = StringTools::Replace(boringString, "^^", "^.^ UwU");
+
+ return boringString;
+}
int main() {
- std::cout << "Hello, World!" << std::endl;
+
+ std::string buf;
+ while (std::getline(std::cin, buf))
+ std::cout << MakeUwu(buf) << std::endl;
+
return 0;
}