# C++ (gcc), 181 bytes <!-- language-all: lang-c++ --> #include <string> auto m(auto s){s[0]=s[0]&~32;for(int i=1;s[i];)s[i++]=s[i]|32;int n=s.length()-1,b=s[n]=='y';return s+(b?"":"y")+" Mc"+(b?s.substr(0,s[n-1]=='e'?n-1:n):s)+"face";} Note that clang will not compile this due to the use of `auto` in a function prototype/return type. Credit goes to [Kevin Cruijssen][1] for the `&~32` trick. Try it online [here][2]. Ungolfed version: #include <string> auto m(auto s) { // abuse of auto, input and output are std::string s[0] = s[0] & ~32; // convert the first character to upper case for(int i=1;s[i];) // iterate over the rest of the string s[i++] = s[i] | 32; // converting it to lower case int n=s.length()-1, // the position of the last character b=s[n]=='y'; // whether or not the last character is a 'y' return s+(b?"":"y") // append 'y' if not already present +" Mc" +(b?s.substr(0,s[n-1]=='e'?n-1:n):s) // remove one, two, or zero chars from the end depending on b and whether the second to last character is 'e' +"face"; } [1]: https://codegolf.stackexchange.com/a/160529/79343 [2]: https://tio.run/##dY8/b4MwEMXn8iksV2qwCFFoN/4kS5Uurdo9YTDGoVbBRNgMKE2/Or2DqIpUWHyn9@537yxOJ78Qou/vlRZlm0sSG9soXWwc3tqaVO5QDDub/TpN8Hn4eXqMjnXjKm2JSoLI7FUaMXg9DydU@g0DaOrErEqpC/vpMj9YZmDqNEkW3SJqpG0bTYznZltKQ9pR5lHyJigKZmXaDM5w10sg/AAZudhCF2oWGpg8ciFpdLm5WtUASF5tnIor7TJydu6MzcNw/A7Jam5JQihWGl09UbeWxDH8EmWGLT3oP/uK7iAM0d0Q@g9FeQ59fn9BEsoECOp8ZKXKbgzFbjIWjbkFrzwfcKwTMMqzN9f6Sw7w2E1dPhhzCz5K3skGF4zdxILRmFvQdUM8lAkU1Bvu0v8C