Write a program that accepts a name as input and outputs the lyrics to the Shirley Ellis song "The Name Game"

Task
The Name Game
You are encouraged to solve this task according to the task description, using any language you may know.

The regular verse

Unless your name begins with a vowel (A, E, I, O, U), 'B', 'F' or 'M' you don't have to care about special rules. The verse for the name 'Gary' would be like this:

   Gary, Gary, bo-bary
   Banana-fana fo-fary
   Fee-fi-mo-mary
   Gary! 

At the end of every line, the name gets repeated without the first letter: Gary becomes ary If we take (X) as the full name (Gary) and (Y) as the name without the first letter (ary) the verse would look like this:

   (X), (X), bo-b(Y)
   Banana-fana fo-f(Y)
   Fee-fi-mo-m(Y)
   (X)! 

Vowel as first letter of the name

If you have a vowel as the first letter of your name (e.g. Earl) you do not truncate the name. The verse looks like this:

   Earl, Earl, bo-bearl
   Banana-fana fo-fearl
   Fee-fi-mo-mearl
   Earl! 

'B', 'F' or 'M' as first letter of the name

In case of a 'B', an 'F' or an 'M' (e.g. Billy, Felix, Mary) there is a special rule. The line which would 'rebuild' the name (e.g. bo-billy) is sang without the first letter of the name. The verse for the name Billy looks like this:

   Billy, Billy, bo-illy
   Banana-fana fo-filly
   Fee-fi-mo-milly
   Billy! 

For the name 'Felix', this would be right:

   Felix, Felix, bo-belix
   Banana-fana fo-elix
   Fee-fi-mo-melix
   Felix!

C

Translation of: Kotlin

<lang c>#include <stdio.h>

  1. include <string.h>

void print_verse(const char *name) {

   char *x, *y; 
   int b = 1, f = 1, m = 1, i = 1;
   /* ensure name is in title-case */
   x = strdup(name);     
   x[0] = toupper(x[0]);
   for (; x[i]; ++i) x[i] = tolower(x[i]);
  
   if (strchr("AEIOU", x[0])) {
       y = strdup(x);
       y[0] = tolower(y[0]); 
   }
   else {
       y = x + 1;
   }
   switch(x[0]) {
       case 'B': b = 0; break;
       case 'F': f = 0; break;
       case 'M': m = 0; break;
       default : break;
   }
     
   printf("%s, %s, bo-%s%s\n", x, x, (b) ? "b" : "", y);
   printf("Banana-fana fo-%s%s\n", (f) ? "f" : "", y);
   printf("Fee-fi-mo-%s%s\n", (m) ? "m" : "", y);
   printf("%s!\n\n", x);

}

int main() {

   int i;
   const char *names[6] = {"gARY", "Earl", "Billy", "Felix", "Mary", "sHIRley"};
   for (i = 0; i < 6; ++i) print_verse(names[i]);
   return 0;

}</lang>

Output:
Gary, Gary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-mary
Gary!

Earl, Earl, bo-bearl
Banana-fana fo-fearl
Fee-fi-mo-mearl
Earl!

Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!

Felix, Felix, bo-belix
Banana-fana fo-elix
Fee-fi-mo-melix
Felix!

Mary, Mary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-ary
Mary!

Shirley, Shirley, bo-bhirley
Banana-fana fo-fhirley
Fee-fi-mo-mhirley
Shirley!

F#

The function

<lang fsharp> // The Name Game. Nigel Galloway: March 28th., 2018 let fN g =

 let fG α β γ = printfn "%s, %s, bo-%s\nBanana-fana fo-%s\nFee-fi-mo-%s\n%s!" g g α β γ g
 match g.ToLower().[0] with
 |'a'|'e'|'i'|'o'|'u' as n  -> fG ("b"+(string n)+g.[1..]) ("f"+(string n)+g.[1..]) ("m"+(string n)+g.[1..])
 |'b'                       -> fG (g.[1..]) ("f"+g.[1..]) ("m"+g.[1..])
 |'f'                       -> fG ("b"+g.[1..]) (g.[1..]) ("m"+g.[1..])
 |'m'                       -> fG ("b"+g.[1..]) ("f"+g.[1..]) (g.[1..])
 |_                         -> fG ("b"+g.[1..]) ("f"+g.[1..]) ("m"+g.[1..])

</lang>

The Task

<lang fsharp> fN "Nigel" </lang>

Output:
Nigel, Nigel, bo-bigel
Banana-fana fo-figel
Fee-fi-mo-migel
Nigel!

<lang fsharp> fN "Earl" </lang>

Output:
Earl, Earl, bo-bearl
Banana-fana fo-fearl
Fee-fi-mo-mearl
Earl!

<lang fsharp> fN "Billy" </lang>

Output:
Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!

<lang fsharp> fN "Fred" </lang>

Output:
Fred, Fred, bo-bred
Banana-fana fo-red
Fee-fi-mo-mred
Fred!

<lang fsharp> fN "Mum" </lang>

Output:
Mum, Mum, bo-bum
Banana-fana fo-fum
Fee-fi-mo-um
Mum!

Factor

Translation of: Kotlin

<lang factor>USING: ascii combinators interpolate kernel locals pair-rocket qw sequences ; IN: rosetta-code.name-game

vowel? ( char -- ? ) "AEIOU" member? ;
name-game ( Name -- )
   Name first  :> L
   Name >lower :> name! L vowel? [ name rest name! ] unless
   "b"         :> B!
   "f"         :> F!
   "m"         :> M!
   
   L { CHAR: B => [ "" B! ]
       CHAR: F => [ "" F! ]
       CHAR: M => [ "" M! ] [ drop ] } case
       

Name Name B name F name M name Name

"${0}, ${1}, bo-${2}${3} Banana-fana fo-${4}${5} Fee-fi-mo-${6}${7} ${8}!\n\n" 9 ninterpolate ;

qw{ Gary Earl Billy Felix Milton Steve } [ name-game ] each</lang>

Output:
Gary, Gary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-mary
Gary!

Earl, Earl, bo-bearl
Banana-fana fo-fearl
Fee-fi-mo-mearl
Earl!

Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!

Felix, Felix, bo-belix
Banana-fana fo-elix
Fee-fi-mo-melix
Felix!

Milton, Milton, bo-bilton
Banana-fana fo-filton
Fee-fi-mo-ilton
Milton!

Steve, Steve, bo-bteve
Banana-fana fo-fteve
Fee-fi-mo-mteve
Steve!

Kotlin

<lang scala>// version 1.2.31

fun printVerse(name: String) {

   val x = name.toLowerCase().capitalize()
   val y = if (x[0] in "AEIOU") x.toLowerCase() else x.substring(1)
   var b = "b$y"
   var f = "f$y"
   var m = "m$y"
   when (x[0]) {
       'B'  -> b = "$y"
       'F'  -> f = "$y"
       'M'  -> m = "$y"
       else -> {} // no adjustment needed
   }
   println("$x, $x, bo-$b")
   println("Banana-fana fo-$f")
   println("Fee-fi-mo-$m")
   println("$x!\n")

}

fun main(args: Array<String>) {

   listOf("Gary", "Earl", "Billy", "Felix", "Mary", "Steve").forEach { printVerse(it) }

}</lang>

Output:
Gary, Gary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-mary
Gary!

Earl, Earl, bo-bearl
Banana-fana fo-fearl
Fee-fi-mo-mearl
Earl!

Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!

Felix, Felix, bo-belix
Banana-fana fo-elix
Fee-fi-mo-melix
Felix!

Mary, Mary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-ary
Mary!

Steve, Steve, bo-bteve
Banana-fana fo-fteve
Fee-fi-mo-mteve
Steve!

Perl 6

Works with: Rakudo version 2018.03

Meh. The rules leave out some corner cases (see Steve) but what the heck, technically correct is the best kind of correct.

<lang perl6>sub mangle ($name, $initial) {

   my $fl = $name.lc.substr(0,1);
   $fl ~~ /<[aeiou]>/
   ?? $initial~$name.lc
   !! $fl eq $initial
   ?? $name.substr(1)
   !! $initial~$name.substr(1)

}

sub name-game (Str $name) {

   qq:to/NAME-GAME/;
   $name, $name, bo-{ mangle $name, 'b' }
   Banana-fana fo-{ mangle $name, 'f' }
   Fee-fi-mo-{ mangle $name, 'm' }
   $name!
   NAME-GAME

}

say .&name-game for <Gary Earl Billy Felix Mike Steve></lang>

Output:
Gary, Gary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-mary
Gary!

Earl, Earl, bo-bearl
Banana-fana fo-fearl
Fee-fi-mo-mearl
Earl!

Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!

Felix, Felix, bo-belix
Banana-fana fo-elix
Fee-fi-mo-melix
Felix!

Mike, Mike, bo-bike
Banana-fana fo-fike
Fee-fi-mo-ike
Mike!

Steve, Steve, bo-bteve
Banana-fana fo-fteve
Fee-fi-mo-mteve
Steve!

VBA

<lang vb>Option Explicit

Sub Main() Dim a, r, i As Integer Const SCHEM As String = "(X), (X), bo-b(Y)^Banana-fana fo-f(Y)^Fee-fi-mo-m(Y)^(X)!^"

  'init
  a = Array("GaRY", "Earl", "Billy", "Felix", "Mary", "Mike", "Frank")
  'compute
  r = TheGameName(a, SCHEM)
  'return
  For i = LBound(r) To UBound(r)
     Debug.Print r(i)
  Next i

End Sub

Private Function TheGameName(MyArr, S As String) As String() Dim i As Integer, s1 As String, s2 As String, tp As String, t() As String

  ReDim t(UBound(MyArr))
  For i = LBound(MyArr) To UBound(MyArr)
     tp = Replace(S, "^", vbCrLf)
     s2 = LCase(Mid(MyArr(i), 2)): s1 = UCase(Left(MyArr(i), 1)) & s2
     Select Case UCase(Left(MyArr(i), 1))
        Case "A", "E", "I", "O", "U": tp = Replace(tp, "(Y)", LCase(MyArr(i)))
        Case "B", "F", "M"
           tp = Replace(tp, "(Y)", s2)
           tp = Replace(tp, LCase(MyArr(i)), s2)
        Case Else: tp = Replace(tp, "(Y)", s2)
     End Select
     t(i) = Replace(tp, "(X)", s1)
  Next
  TheGameName = t

End Function</lang>

Output:
Gary, Gary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-mary
Gary!

Earl, Earl, bo-bearl
Banana-fana fo-fearl
Fee-fi-mo-mearl
Earl!

Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!

Felix, Felix, bo-belix
Banana-fana fo-elix
Fee-fi-mo-melix
Felix!

Mary, Mary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-ary
Mary!

Mike, Mike, bo-bike
Banana-fana fo-fike
Fee-fi-mo-ike
Mike!

Frank, Frank, bo-brank
Banana-fana fo-rank
Fee-fi-mo-mrank
Frank!

zkl

Translation of: Kotlin

<lang zkl>fcn printVerse(name){

  z,x := name[0].toLower(), z.toUpper() + name[1,*].toLower();
  y:=( if("aeiou".holds(z)) name.toLower() else x[1,*] );
  b,f,m := T("b","f","m").apply('wrap(c){ z==c and y or c+y });
  println("%s, %s, bo-%s".fmt(x,x,b));
  println("Banana-fana fo-",f);
  println("Fee-fi-mo-",m);
  println(x,"!\n");

}</lang> <lang zkl>List("Gary", "Earl", "Billy", "Felix", "Mary", "Steve").apply2(printVerse);</lang>

Output:
Gary, Gary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-mary
Gary!

Earl, Earl, bo-bearl
Banana-fana fo-fearl
Fee-fi-mo-mearl
Earl!

Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!

Felix, Felix, bo-belix
Banana-fana fo-elix
Fee-fi-mo-melix
Felix!

Mary, Mary, bo-bary
Banana-fana fo-fary
Fee-fi-mo-ary
Mary!

Steve, Steve, bo-bteve
Banana-fana fo-fteve
Fee-fi-mo-mteve
Steve!