Anyone remember Boaty?

You could totally make any old word, right?

  • Write a function to turn a string into Somethingy McSomethingface.
  • It should accept one string as input. Ignore the case of the input.
  • If the word ends in 'y', your function should not add an additional 'y' to the first instance, but should remove it in the second instance.
  • If the word ends in 'ey', it should not have an additional 'y' added in the first instance, but should remove both in the second instance.
  • The output should only have upper case letters in the first character, the 'M' of 'Mc' and the first character after 'Mc'.
  • it only needs to work with strings of 3 or more characters.


boat                  =>  Boaty McBoatface
Face                  =>  Facey McFaceface
DOG                   =>  Dogy McDogface
Family                =>  Family McFamilface
Lady                  =>  Lady McLadface
Donkey                =>  Donkey McDonkface
Player                =>  Playery McPlayerface
yyy                   =>  Yyy McYyface
DJ Grand Master Flash =>  Dj grand master flashy McDj grand master flashface
  • \$\begingroup\$ What about spaces in the string, do we leave them intact? Examples: ' y' and ' ' \$\endgroup\$ – touch my body Mar 27 '18 at 17:02
  • 2
    \$\begingroup\$ I’m going to implement a suggestion from @Arnauld and make it three characters minimum. Treat whitespace just like another letter. \$\endgroup\$ – AJFaraday Mar 27 '18 at 17:04
  • \$\begingroup\$ Related: Code Johnny Code, Code! \$\endgroup\$ – Kevin Cruijssen Mar 28 '18 at 9:42
  • \$\begingroup\$ Can we assume the input will only contain upper and lowercase letters? \$\endgroup\$ – Kevin Cruijssen Mar 28 '18 at 13:16
  • \$\begingroup\$ @KevinCruijssen I haven't put any non-letters in the test cases, so they're effectively not concerned. \$\endgroup\$ – AJFaraday Mar 28 '18 at 13:17

37 Answers 37


Stax, 26 bytes


Run and debug it

^           convert input to upper case                     "FACE"
B~          chop first character and push it back to input  70 "ACE"
v+          lowercase and concatenate                       "Face"
c'yb        copy, push "y", then copy both                  "Face" "Face" "y" "Face" "y"
:]          string ends with?                               "Face" "Face" "y" 0
T           trim this many character                        "Face" "Face" "y"
+           concatenate                                     "Face" "Facey"
p           output with no newline                          "Face"
"e?y$"z     push some strings                               "Face" "e?y$" ""
" Mc`Rface  execute string template; `R means regex replace " Mc Faceface"
            result is printed because string is unterminated

Run this one


V, 27 28 30 bytes


Try it online!

<Esc> represents 0x1b

  • Golfed two bytes after learning that we did not need to support inputs with less than 3 characters.

  • 1 byte saved thanks to @DJMcMayhem by working on the second line before the first one, thus removing the G

The input is in the buffer. The program begins by converting everything to lowercase

V selects the line and u lowercases it

~ toggles the case of the first character (converting it to uppercase)

and Ù duplicates this line above, leaving the cursor at the bottom line

ó and replaces e¿y$, compressed form of e\?y$ (optional e and a y at the end of the line), with nothing (happens on the second line)

H goes to the first line

ó replaces y$ (y at the end of the line) with nothing on the first line

Á appends a y to the end of the first line

J and joins the last line with the first with a space in the middle, and the cursor is moved to this space

a appends Mc (<Esc> returns to normal mode)

A finally, appends face at the end of the line


Python, 144 bytes

def f(s):
 y=lambda s:s[:-1]if s[-1]=='y'else s
 u=s[:-2]if s[-2:]=='ey'else y(s)
 return t+'y Mc%sface'%u

Try it online here

  • 2
    \$\begingroup\$ my first ever code golf attempt... \$\endgroup\$ – touch my body Mar 27 '18 at 16:44
  • 3
    \$\begingroup\$ welcome to PPCG! might I suggest adding a link to Try it Online! for verification of correctness? \$\endgroup\$ – Giuseppe Mar 27 '18 at 16:46
  • 1
    \$\begingroup\$ f("Face") does not comply with the current test cases (TIO). \$\endgroup\$ – Jonathan Frech Mar 27 '18 at 17:13
  • \$\begingroup\$ Edited post for correctness, also added a Try It Online! link \$\endgroup\$ – touch my body Mar 27 '18 at 17:30
  • 1
    \$\begingroup\$ 97 bytes. \$\endgroup\$ – totallyhuman Mar 27 '18 at 19:04

Excel, 204 144 137 165 bytes

=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(REPT(REPLACE(LOWER(A1),1,1,UPPER(LEFT(A1)))&"~",2),"~","y Mc",1),"yy ","y "),"ey~","~"),"y~","~"),"~","face")

From the inside outwards:

REPLACE(LOWER(A1),1,1,UPPER(LEFT(A1)))      Replaces PROPER to handle space-delimited cases
REPT(%&"~",2)                   Duplicate.                    Donkey~Donkey~
SUBSTITUTE(%,"~","y Mc",1)      Replace first ~.              Donkeyy McDonkey~
SUBSTITUTE(%,"yy ","y ")        Handle words ending in 'y'.   Donkey McDonkey~
SUBSTITUTE(%,"ey~","~")         Handle words ending in 'ey'   Donkey McDonk~
SUBSTITUTE(%,"y~","~")          Handle words ending in 'y'    Donkey McDonk~
SUBSTITUTE(%,"~","face")        Adding face.                  Donkey McDonkface

Old answer, creating all bits separately, and then concatenating (176 bytes). Does not handle space-delimited cases correctly.

=PROPER(A1)&IF(LOWER(RIGHT(A1,1))="y",,"y")&" Mc"&IF(LOWER(RIGHT(A1,2))="ey",LEFT(PROPER(A1),LEN(A1)-2),IF(LOWER(RIGHT(A1,1))="y",LEFT(PROPER(A1),LEN(A1)-1),PROPER(A1)))&"face"
  • \$\begingroup\$ Unfortunately, due to the requirement of handling space-delimited cases, PROPER(A1) is invalid (see the DJ Grand Master Flash input case), the best replacement that I could find while working on my VBA solution was LEFT(UPPER(A1))&MID(LOWER(A1),2,LEN(A1)) - please let me know if you end up golfing that down. \$\endgroup\$ – Taylor Scott Apr 10 '18 at 1:21
  • 1
    \$\begingroup\$ Thank you @TaylorScott. Found 'REPLACE(LOWER(A1),1,1,UPPER(LEFT(A1)))` which is 2 bytes shorter. \$\endgroup\$ – Wernisch Apr 12 '18 at 9:26

Perl 6, 42 37 35 bytes

{S/y$//~"y Mc{S/e?y$//}face"}o&tclc

Try it online!


C# (.NET Core), 122 108 139 175 180 179 154 bytes

Thanks a lot, lee!

s=>((s.EndsWith("y")?s:s+"y")+" Mc"+(s+"$").Replace("ey$","")+"face").Replace(s,s.ToUpper()[0]+s.Substring(1).ToLower()).Replace("y$","").Replace("$","");

Try it online!

C# (.NET Core, with LINQ), 152 bytes

s=>((s.Last()=='y'?s:s+"y")+" Mc"+(s+"$").Replace("ey$","")+"face").Replace(s,s.ToUpper()[0]+s.Substring(1).ToLower()).Replace("y$","").Replace("$","");

Try it online!

  • 3
    \$\begingroup\$ Welcome to the site! :) \$\endgroup\$ – James Mar 28 '18 at 16:55

Ruby, 61 49 bytes

->s{s.capitalize=~/(e)?y$|$/;"#$`#$1y Mc#$`face"}

Try it online!

Saved 12 sweet bytes thanks to @MartinEnder:

  • 1
    \$\begingroup\$ Using the regex from my Retina answer and making a bit more use of string interpolation gets this down to 49: tio.run/##DcxBCsIwEEDRqwxJBF3Y4lpSN0U3igcQwTQmGFptMVNkTOLVY3bvb/… \$\endgroup\$ – Martin Ender Mar 28 '18 at 13:42
  • \$\begingroup\$ @MartinEnder Wow, that is quite a difference. I don't think I've seen string interpolation without brackets. I'll take it if you don't want to use it for your own Ruby answer. \$\endgroup\$ – Reinstate Monica -- notmaynard Mar 28 '18 at 15:04
  • \$\begingroup\$ Nah, it's fine, I wouldn't have come up with using =~ and building the whole string instead of using sub. String interpolation can be used without brackets if the variable is a global, instance or class variable. \$\endgroup\$ – Martin Ender Mar 28 '18 at 15:05
  • \$\begingroup\$ You can get this down to 44+1 bytes by using the -p flag and using sub: tio.run/… \$\endgroup\$ – Jordan Sep 1 '18 at 20:45

SOGL V0.12, 38 bytes

lW y≠F
u⁽³:F y*+pF‽j:lW e=⌡j}"‰θ`√►׀‘p

Try it Here!


Python 3, 80 bytes

Long time avid reader, my first submission at last !

lambda y:re.sub("([\w ]+?)((e)?y)?$",r"\1\3y Mc\1face",y.capitalize())
import re

Try it online

  • 1
    \$\begingroup\$ Welcome to PPCG, and very nice first post! \$\endgroup\$ – Zacharý Mar 30 '18 at 14:38

Retina, 29 bytes

$1y Mc$`face

Try it online!


Python 2, 88 92 bytes

lambda s:(s+'y'*-~-(s[-1]in'yY')).title()+' Mc'+re.sub('e?y$','',s.title())+'face'
import re

Try it online!

  • 3
    \$\begingroup\$ Fails with 'FamilY' \$\endgroup\$ – Dead Possum Mar 28 '18 at 9:35
  • \$\begingroup\$ @Dead Possum: Fixed. Thks! \$\endgroup\$ – Chas Brown Mar 28 '18 at 18:04

Java 8, 121 112 107 106 bytes

s->(s=(char)(s.charAt(0)&95)+s.toLowerCase().substring(1)).split("y$")[0]+"y Mc"+s.split("e?y$")[0]+"face"

-1 byte thanks to @OliverGrégoire.


Try it online.

s->                         // Method with String as both parameter and return-type
  (s=                       //  Replace and return the input with:
     (char)(s.charAt(0)&95) //   The first character of the input as Uppercase
                            //   + the rest as lowercase
  .split("y$")[0]           //  Remove single trailing "y" (if present)
  +"y Mc"                   //  Appended with "y Mc"
  +s.split("e?y$")[0]       //  Appended with the modified input, with "y" or "ey" removed
  +"face"                   //  Appended with "face"
  • \$\begingroup\$ What if the first char is not alphabetical? Or maybe we can get a rule added about that.. \$\endgroup\$ – streetster Mar 28 '18 at 13:14
  • 1
    \$\begingroup\$ @streetster Just asked OP, and it seems the input will only contains uppercase and/or lowercase letters. \$\endgroup\$ – Kevin Cruijssen Mar 28 '18 at 13:20
  • 1
    \$\begingroup\$ ~32 -> 95 for 1 byte saved \$\endgroup\$ – Olivier Grégoire Mar 29 '18 at 9:38
  • \$\begingroup\$ @OlivierGrégoire I really need to start learning a bit more about bitwise operations.. >.> \$\endgroup\$ – Kevin Cruijssen Mar 29 '18 at 9:56

JavaScript, 103 96 94 bytes

Pretty naïve first pass at this.

s=>(g=r=>s[0].toUpperCase()+s.slice(1).toLowerCase().split(r)[0])(/y$/)+`y Mc${g(/e?y$/)}face`

Try it online

  • \$\begingroup\$ s=>${s=s[0].toUpperCase()+s.slice(1).toLowerCase().replace(/y$/,``)}y Mc${s.replace(/e?y$/,``)}face \$\endgroup\$ – Benjamin Gruenbaum Mar 27 '18 at 18:44
  • \$\begingroup\$ One less: s=>${s=s[0].toUpperCase()+s.slice(1).toLowerCase().replace(/y$/,'')}y Mc${s.replace(/e$/,``)}face \$\endgroup\$ – Benjamin Gruenbaum Mar 27 '18 at 18:50
  • \$\begingroup\$ Thanks, @BenjaminGruenbaum, but the first fails for Donkey and the second for Face. \$\endgroup\$ – Shaggy Mar 27 '18 at 19:04
  • \$\begingroup\$ The markdown is ruining the code: gist.github.com/benjamingr/8fec077b5436846cc9c52be353238037 \$\endgroup\$ – Benjamin Gruenbaum Mar 27 '18 at 19:05
  • \$\begingroup\$ @Shaggy i managed to reduce the g function by some chars :). you can look in my solution \$\endgroup\$ – DanielIndie Mar 28 '18 at 16:55

vim, 35 34 bytes

kgJiy Mc<ESC>Aface<ESC>

<ESC> is 0x1b


Vu~                      # Caseify McCaseface
Yp                       # dup line
:%s/y$                   # Get the suffixes right
kgJiy Mc<ESC>Aface<ESC>  # Join lines and add the extra chars

Try it online!

Saved 1 byte thanks to DJMcMayhem

  • 1
    \$\begingroup\$ You can do Y instead of yy \$\endgroup\$ – James Mar 28 '18 at 4:06

Perl 5 -p, 47 39 bytes

Saved 6 bytes with @OlegV.Volkov's suggestions, 1 with @mwellnhof's, and 1 on my own

$_=lc^$";$_=s/y?$/y Mc/r.s/e?y$//r.face

Try it online!

  • \$\begingroup\$ You can get rid of ucfirst: $_=lc^$"; \$\endgroup\$ – Oleg V. Volkov Mar 28 '18 at 14:39
  • \$\begingroup\$ $_=s/y$//r."y Mc".s/e?y$//r.face is one byte shorter. \$\endgroup\$ – nwellnhof Mar 28 '18 at 14:55
  • 1
    \$\begingroup\$ /y$|$/ -> /y?$/ \$\endgroup\$ – Oleg V. Volkov Mar 28 '18 at 20:34
  • \$\begingroup\$ Duh. I should have realized that. \$\endgroup\$ – Xcali Mar 29 '18 at 2:53

C++ 14 (g++), 181 171 148 147 134 bytes

[](auto s){s[0]&=95;int i=1,b;for(;s[i];)s[i++]|=32;b=s[--i]-'y';return s+(b?"y":"")+" Mc"+(b?s:s.substr(0,s[i-1]-'e'?i:i-1))+"face";}

Note that clang will not compile this.

Credit goes to Kevin Cruijssen and Olivier Grégoire for the &95 trick.

Thanks to Chris for golfing 11 bytes.

Try it online here.

Ungolfed version:

[] (auto s) { // lambda taking an std::string as argument and returning an std::string
    s[0] &= 95; // convert the first character to upper case
    int i = 1, // for iterating over the string
    b; // we'll need this later
    for(; s[i] ;) // iterate over the rest of the string
        s[i++] |= 32; // converting it to lower case
    // i is now s.length()
    b = s[--i] - 'y'; // whether the last character is not a 'y'
    // i is now s.length()-1
    return s + (b ? "y" : "") // append 'y' if not already present
    + " Mc"
    + (b ? s : s.substr(0, s[i-1] - 'e' ? i : i-1)) // remove one, two, or zero chars from the end depending on b and whether the second to last character is 'e'
    + "face";
  • \$\begingroup\$ I don't know C++ that well, but you can golf 9 bytes: Try it online 172 bytes. Summary of changes: s[0]=s[0]&~32; to s[0]&=~32;; s[i++]=s[i]|32; to s[i++]|=32; and int i=1,n=s.length()-1,b; so you only need 1 int. \$\endgroup\$ – Kevin Cruijssen Mar 28 '18 at 14:05
  • \$\begingroup\$ Oh, and one more byte by removing the space at #include<string> \$\endgroup\$ – Kevin Cruijssen Mar 28 '18 at 14:06
  • \$\begingroup\$ @KevinCruijssen thanks for catching that! I have edited. \$\endgroup\$ – O.O.Balance Mar 28 '18 at 14:19
  • \$\begingroup\$ You can save 11 bytes by not defining n and just using the value of i after the while loop. Try it online! \$\endgroup\$ – Chris Mar 30 '18 at 18:34
  • \$\begingroup\$ @Chris Thanks! I managed to shave off 2 more bytes. \$\endgroup\$ – O.O.Balance Mar 30 '18 at 23:19

V, 38 36 32 bytes

-5 byte thanks to @Cows quack

A Mc<esc>póe¿y$

<esc> is a literal escape character and [^ is encoded as \x84

Try it online!

  • \$\begingroup\$ gu$ can become Vu \$\endgroup\$ – user41805 Mar 27 '18 at 18:23
  • 2
    \$\begingroup\$ Since [^ is a regex shortcut (see here), you can use 0x84 instead of [^ to save a byte. Similarly, \? can be simplified into <M-?> to save another byte. And $a => A \$\endgroup\$ – user41805 Mar 27 '18 at 18:37

05AB1E, 30 bytes


Try it online! or as a Test suite


Python 3, 117 114 bytes

-3 bytes thanks to Dead Possum

def f(s):s=s.title();return s+'y'*(s[-1]!='y')+' Mc'+([s,s[:-1],0,s[:-2]][(s[-1]=='y')+((s[-2:]=='ey')*2)])+'face'

Try it online!

  • \$\begingroup\$ 3rd element of list [s,s[:-1],'',s[:-2] can be changed to 0 to save 1 byte. \$\endgroup\$ – Dead Possum Mar 28 '18 at 9:34
  • \$\begingroup\$ In 'y'*1 *1 is not needed. 2 more bytes \$\endgroup\$ – Dead Possum Mar 28 '18 at 9:34
  • \$\begingroup\$ Switching from Python 3 to Python 2, and replacing return with print is 1 byte shorter. \$\endgroup\$ – Kevin Cruijssen Mar 28 '18 at 12:57

JavaScript (Node.js), 87 bytes

  • thanks to @Shaggy for 5 reducing 5 bytes
s=>(g=r=>Buffer(s.replace(r,"")).map((x,i)=>i?x|32:x&~32))(/y$/)+`y Mc${g(/e?y$/)}face`

Try it online!

  • 2
    \$\begingroup\$ You don't have to name non-recursive functions. \$\endgroup\$ – Dennis Mar 28 '18 at 17:01
  • 1
    \$\begingroup\$ Nicely done. I never think to use Buffer, will have to try to remember it for future challenges. Got it down to 87 bytes for you. \$\endgroup\$ – Shaggy Mar 28 '18 at 17:25

K4, 74 69 68 bytes


{$[r;x;x,"y"]," Mc",_[r:0&1-2/:"ye"=2#|x;x:@[_x;0;.q.upper]],"face"}


q)k)f:{$[r;x;x,"y"]," Mc",_[r:0&1-2/:"ye"=2#|x;x:@[_x;0;.q.upper]],"face"}
q)f each ("boat";"Face";"DOG";"Family";"Lady";"Donkey";"Player")
"Boaty McBoatface"
"Facey McFaceface"
"Dogy McDogface"
"Family McFamilface"
"Lady McLadface"
"Donkey McDonkface"
"Playery McPlayerface"


Figure out if the last characters are equal to "ey", convert result to base-2 so we can ignore words that end "e?". Index into a list of numbers of characters to trim.

Managed to shave 5 bytes off my code to determine whether the last two chars at "ey" but struggling to better it...

{$[r;x;x,"y"]," Mc",_[r:0&1-2/:"ye"=2#|x;x:@[_x;0;.q.upper]],"face"} / the solution
{                                                                  } / lambda function
                                                            ,"face"  / join with "face"
                    _[                  ;                  ]         / cut function
                                           @[_x; ;        ]          / apply (@) to lowercased input
                                                0                    / at index 0
                                                  .q.upper           / uppercase function
                                         x:                          / save back into x
                                      |x                             / reverse x
                                    2#                               / take first two chars of x
                               "ye"=                                 / equal to "ye"?
                             2/:                                     / convert to base 2
                           1-                                        / subtract from 1
                         0&                                          / and with 0 (take min)
                       r:                                            / save as r
             ," Mc",                                                 / join with " Mc"
 $[r;x;x,"y"]                                                        / join with x (add "y" if required)


67 byte port in K (oK):

{$[r;x;x,"y"]," Mc",((r:0&1-2/"ye"=2#|x)_x:@[_x;0;`c$-32+]),"face"}

Try it online!

  • 1
    \$\begingroup\$ What's the point in the K4 if your oK port defeats it? \$\endgroup\$ – Zacharý Mar 27 '18 at 21:33
  • \$\begingroup\$ I didn't think it would, and the port doesn't work if the first char isn't alphabetical as I blindly subtract 32 from the ASCII value - there's no "upper" built-in. \$\endgroup\$ – streetster Mar 28 '18 at 13:11

Ruby, 69 bytes

->s{"#{(s.capitalize!||s)[-1]==?y?s:s+?y} Mc#{s.gsub /e?y$/,""}face"}


->s{                                                                } # lambda 
    "#{                                 } Mc#{                }face" # string interpolation
       (s.capitalize!||s) # returns string capitalized or nil, in that case just use the original string
                         [-1]==?y # if the last character == character literal for y
                                 ?s:s+?y # then s, else s + "y"
                                              s.gsub /e?y$/,"" # global substitute
                                                               # remove "ey" from end

Try it online!

  • \$\begingroup\$ Could you add a TIO link? I don't know Ruby, but does s.capitalize replace the previous s? If not, does /e?y$/ handle a test case ending in Y, EY, or Ey correctly? \$\endgroup\$ – Kevin Cruijssen Mar 28 '18 at 13:57
  • 1
    \$\begingroup\$ @KevinCruijssen s.capitalize vs s.capitalize! (different functions). s.capitalize! clobbers the old version. \$\endgroup\$ – anna328p Mar 28 '18 at 19:32
  • \$\begingroup\$ @KevinCruijssen I've added a TIO link. \$\endgroup\$ – anna328p Mar 28 '18 at 19:35
  • \$\begingroup\$ @KevinCruijssen Also added an explanation \$\endgroup\$ – anna328p Mar 28 '18 at 19:41
  • \$\begingroup\$ Ah ok, thanks for the explanation and the information about s.capitalize!. Never programmed in Ruby, but adding an explanation mark to replace the previous value is pretty cool. +1 from me. \$\endgroup\$ – Kevin Cruijssen Mar 29 '18 at 8:14

Jstx, 27 bytes

h</►yT↓►y/◙♂ Mc♀/◄eyg►yg/íå


      # Command line args are automatically loaded onto the stack
h     # Title case the top of the stack
<     # Duplicate the top value on the stack twice
/     # Print the top value on the stack
►y    # Load 'y' onto the stack
T     # Returns true if the 2nd element on the stack ends with the top
↓     # Execute block if the top of the stack is false
  ►y  # Load 'y' onto the stack
  /   # Print the top value on the stack
◙     # End the conditional block
♂ Mc♀ # Load ' Mc' onto the stack
/     # Print the top value on the stack
◄ey   # Load 'ey' onto the stack
g     # Delete the top of the stack from the end of the 2nd element on the stack if it exists
►y    # Load 'y' onto the stack
g     # Delete the top of the stack from the end of the 2nd element on the stack if it exists
/     # Print the top of the stack
íå    # Load 'face' onto the stack
      # Print with newline is implied as the program exits

Try it online!

  • \$\begingroup\$ I haven't seen this language before. It looks interesting. Is there documentation? \$\endgroup\$ – recursive Mar 31 '18 at 22:29
  • 1
    \$\begingroup\$ @recursive Here's some documentation. \$\endgroup\$ – Quantum64 Apr 1 '18 at 4:44
  • \$\begingroup\$ Wow, this is really impressive. Especially for so little development time. I'm excited to see where this goes. \$\endgroup\$ – recursive Apr 1 '18 at 5:08

Red, 143 142 bytes

func[s][s: lowercase s s/1: uppercase s/1
w: copy s if"y"<> last s[append w"y"]rejoin[w" Mc"parse s[collect keep to[opt["y"|"ey"]end]]"face"]]

Try it online!


f: func[s][
   s: lowercase s                      ; make the entire string lowercase
   s/1: uppercase s/1                  ; raise only its first symbol to uppercase 
   w: copy s                           ; save a copy of it to w
   if "y" <> last s[append w "y"]     ; append 'y' to w if it doesn't have one at its end
   rejoin[w                            ; assemble the result by joining:
          " Mc"
          ; keep the string until "y", "ey" or its end
          parse s[collect keep to [opt ["y" | "ey"] end]]

PHP: 132

<?php function f($s){$s=ucfirst(strtolower($s));return $s.(substr($s,-1)=='y'?'':'y').' Mc'.preg_replace('/(ey|y)$/','',$s).'face';}



function f($s)
    // Take the string, make it all lowercase, then make the first character uppercase
    $s = ucfirst(strtolower($s));

    // Return the string, followed by a 'y' if not already at the end, then ' Mc'
    // and the string again (this time, removing 'y' or 'ey' at the end), then
    // finally tacking on 'face'.
    return $s
        . (substr($s, -1) == 'y' ? '' : 'y')
        . ' Mc'
        . preg_replace('/(ey|y)$/', '', $s)
        . 'face';

Jelly, 77 75 74 73 bytes

Çṫ0n”yẋ@”y;@Ç;“ Mc”

Try it online!

Any golfing suggestions are welcome (and wanted)!


Pyth, 36 34 bytes

++Jrz4*\yqJK:J"e?y$"k+" Mc"+K"face

Try it online!


++Jrz4*\yqJK:J"(e)?y$"k+" Mc"+K"face

  Jrz4                                  Set J to the titlecase of z (input)
           K:J"e?y$"k                   Set K to (replace all matches of the regex e?y$ in J with k (empty string))
         qJ                             Compare if equal to J
      *\y                               Multiply by "y" (if True, aka if no matches, this gives "y", else it gives "")
 +                                      Concatenate (with J)
                             +K"face    Concatenate K with "face"
                       +" Mc"           Concatenate " Mc" with that
+                                       Concatenate
  • \$\begingroup\$ Sadly this doesn't work, as the last test case fails. \$\endgroup\$ – Zacharý Mar 30 '18 at 16:16
  • \$\begingroup\$ Switch rz3 to rz4 to get this to work properly for the last test case. \$\endgroup\$ – hakr14 Mar 30 '18 at 18:10
  • \$\begingroup\$ Oh whoops, I'll fix that :P \$\endgroup\$ – RK. Mar 30 '18 at 22:50

Elixir, 112 110 107 106 bytes

now as short as java

fn x->x=String.capitalize x;"#{x<>if x=~~r/y$/,do: "",else: "y"} Mc#{String.replace x,~r/e?y$/,""}face"end

Try it online!


x=String.capitalize x

Gets x with the first character in uppercase and all others lowercase.

#{ code }

Evaluate the code and insert it into the string.

#{x<>if x=~ ~r/y$/, do: "", else: "y"}

Concatenates x with y if it does not end with y (ie it does not match the regex y$).

#{String.replace x, ~r/e?y$/, "")}

Removes trailing ey and trailing y.


PHP, 45 46 bytes

<?=($s=ucfirst(fgets(STDIN)))."y Mc{$s}face";

Try it online!

  • \$\begingroup\$ Fails in two different ways with input boAty. (Wrong caps, 'y' not removed). \$\endgroup\$ – Oleg V. Volkov Mar 29 '18 at 13:50

Pyth, 60 59 bytesSBCS

K"ey"Jrz4Iq>2JK=<2J=kK.?=k\yIqeJk=<1J))%." s÷   WZÞàQ"[JkJ

Test suite

They don't display here, but three bytes, \x9c, \x82, and \x8c are in the packed string between s and ÷. Rest assured, the link includes them.

Python 3 translation:
if J[-2:]==K:
    if J[-1]==k:
print("{}{} Mc{}face".format(J,k,J))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.