The Name Game

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

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


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 sung 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!
Other tasks related to string operations:
Metrics
Counting
Remove/replace
Anagrams/Derangements/shuffling
Find/Search/Determine
Formatting
Song lyrics/poems/Mad Libs/phrases
Tokenize
Sequences



11l

Translation of: Python
F print_verse(n)
   V l = [String(‘b’), ‘f’, ‘m’]
   V s = n[1..]
   V? i = l.find(n[0].lowercase())
   I i != N
      l[i] = ‘’
   E I n[0] C (‘A’, ‘E’, ‘I’, ‘O’, ‘U’)
      s = n.lowercase()
   print("#., #., bo-#.#.\nBanana-fana fo-#.#.\nFee-fi-mo-#.#.\n#.!\n".format(n, n, l[0], s, l[1], s, l[2], s, n))

L(n) [‘Gary’, ‘Earl’, ‘Billy’, ‘Felix’, ‘Mary’]
   print_verse(n)

Ada

Works with: Ada version 2012
with Ada.Characters.Handling;
with Ada.Strings.Unbounded;
with Ada.Text_IO;

procedure The_Name_Game
is
   package ACH renames Ada.Characters.Handling;
   package ASU renames Ada.Strings.Unbounded;
   function "+"(input : in String) return ASU.Unbounded_String renames ASU.To_Unbounded_String;
   function "+"(input : in ASU.Unbounded_String) return String renames ASU.To_String;
   
   function Normalize_Case(input : in String) return String is
   begin
      return ACH.To_Upper(input(input'First))
        & ACH.To_Lower(input(input'First + 1 .. input'Last));
   end Normalize_Case;

   function Transform(input : in String; letter : in Character) return String is
   begin
      case input(input'First) is
         when 'A' | 'E' | 'I' | 'O' | 'U' =>
            return letter & ACH.To_Lower(input);
         when others =>
            if ACH.To_Lower(input(input'First)) = letter then
               return input(input'First + 1 .. input'Last);
            else
               return letter & input(input'First + 1 .. input'Last);
            end if;
      end case;
   end Transform;
   
   procedure Lyrics(name : in String)
   is
      normalized : constant String := Normalize_Case(name);
   begin
      Ada.Text_IO.Put_Line(normalized & ", " & normalized & ", bo-" & Transform(normalized, 'b'));
      Ada.Text_IO.Put_Line("Banana-fana, fo-" & Transform(normalized, 'f'));
      Ada.Text_IO.Put_Line("fi-fee-mo-" & Transform(normalized, 'm'));
      Ada.Text_IO.Put_Line(normalized & '!');
      Ada.Text_IO.New_Line;
   end Lyrics;

   names : constant array(1 .. 5) of ASU.Unbounded_String :=
     (+"Gary",
      +"EARL",
      +"billy",
      +"FeLiX",
      +"Mary");
begin
   for name of names loop
      Lyrics(+name);
   end loop;
end The_Name_Game;
Output:
Gary, Gary, bo-bary
Banana-fana, fo-fary
fi-fee-mo-mary
Gary!

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

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

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

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

ALGOL 68

Works with: ALGOL 68G
main:(
  PROC print lyrics = (STRING name) VOID:
    BEGIN
      PROC change name = (STRING name, CHAR initial) STRING:
        BEGIN
          CHAR lower first = to lower(name[1]);
          IF char in string(lower first, NIL, "aeiou") THEN
            lower first + name[2:]
          ELIF lower first = initial THEN
            name[2:]
          ELSE
            initial + name[2:]
          FI
        END;

    print((name, ", ", name, ", bo-", change name(name, "b"), new line,
           "Banana-fana fo-", change name(name, "f"), new line,
           "Fee-fi-mo-", change name(name, "m"), new line,
           name, "!", new line))
  END;

  []STRING names = ("Gary", "Earl", "Billy", "Felix", "Mary");

  FOR i FROM LWB names TO UPB names DO
    print lyrics(names[i]);
    print(new line)
  OD
)

Arturo

nameGame: function [Name][
    L: take Name 1
    name: lower Name
    unless in? L "AEIOU" -> drop 'name
    [B F M]: ["b" "f" "m"]

    if L="B" -> B: ""
    if L="F" -> F: ""
    if L="M" -> M: ""

    ~{
        |Name|, |Name|, bo-|B||name|
        Banana-fana fo-|F||name|
        Fee-fi-mo-|M||name|
        |Name|!
    }
]

["Gary" "Earl" "Billy" "Felicia" "Marissa" "Sarah"]
    | map => nameGame
    | loop => [print & ++ "\n"]
Output:
Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!

Felicia, Felicia, bo-belicia
Banana-fana fo-elicia
Fee-fi-mo-melicia
Felicia!

Marissa, Marissa, bo-barissa
Banana-fana fo-farissa
Fee-fi-mo-arissa
Marissa!

Sarah, Sarah, bo-barah
Banana-fana fo-farah
Fee-fi-mo-marah
Sarah!

AutoHotkey

for i, x in StrSplit("Gary,Earl,Billy,Felix,Mary", ","){
	BFM := false
	if (SubStr(x, 1, 1) ~= "i)^[AEIOU]")	; Vowel 
		y := x
	else if (SubStr(x, 1, 1) ~= "i)^[BFM]")	; BFM
		y := SubStr(x,2), BFM := true
	else
		y := SubStr(x,2)
	StringLower, y, y
	output := X ", " X ", bo-"	(SubStr(x,1,1)="b"&&BFM ? "" : "b") Y 
	. "`nBanana-fana fo-"		(SubStr(x,1,1)="f"&&BFM ? "" : "f") Y 
	. "`nFee-fi-mo-"		(SubStr(x,1,1)="m"&&BFM ? "" : "m") Y 
	. "`n" X "!" 
	result .= output "`n`n"
}
MsgBox, 262144, ,% result
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!

AWK

# syntax: GAWK -f THE_NAME_GAME.AWK
BEGIN {
    n = split("gary,earl,billy,felix,mary,shirley",arr,",")
    for (i=1; i<=n; i++) {
      print_verse(arr[i])
    }
    exit(0)
}
function print_verse(name,  c,x,y) {
    x = toupper(substr(name,1,1)) tolower(substr(name,2))
    y = (x ~ /^[AEIOU]/) ? tolower(x) : substr(x,2)
    c = substr(x,1,1)
    printf("%s, %s, bo-%s%s\n",x,x,(c~/B/)?"":"b",y)
    printf("Banana-fana fo-%s%s\n",(c~/F/)?"":"f",y)
    printf("Fee-fi-mo-%s%s\n",(c~/M/)?"":"m",y)
    printf("%s!\n\n",x)
}
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!


BASIC256

Translation of: FreeBASIC
subroutine TheGameName(nombre)
	x = lower(nombre)
	x = upper(mid(x,1,1)) + (mid(x,2,length(x)-1))
	x0 = upper(mid(x,1,1))

	if x0 = "A" or x0 = "e" or x0 = "I" or x0 = "O" or x0 = "U" then
		y = lower(x)
	else
		y = mid(x,2,length(x)-1)
	end If

	b = "b" + y
	f = "f" + y
	m = "m" + y

	begin case
		case x0 = "B"
			b = y
		case x0 = "F"
			f = y
		case x0 = "M"
			m = y
	end case

	print x + ", " + x + ", bo-" + b
	print "Banana-fana fo-" + f
	print "Fee-fi-mo-" + m
	print x + "!" + chr(10)
end subroutine

dim listanombres[5]
listanombres = {"Gary", "EARL", "billy", "FeLiX", "Mary", "ShirleY"}
for i = 0 to listanombres[?]-1
	call TheGameName(listanombres[i])
next i
end
Output:
Igual que la entrada de FreeBASIC.


C

Translation of: Kotlin
#include <stdio.h>
#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;
}
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!

C#

Translation of: Java
using System;
using System.Collections.Generic;
using System.Text;

namespace TheNameGame {
    class Program {
        static void PrintVerse(string name) {
            StringBuilder sb = new StringBuilder(name.ToLower());
            sb[0] = Char.ToUpper(sb[0]);
            string x = sb.ToString();
            string y = "AEIOU".IndexOf(x[0]) > -1 ? x.ToLower() : x.Substring(1);
            string b = "b" + y;
            string f = "f" + y;
            string m = "m" + y;
            switch (x[0]) {
                case 'B':
                    b = y;
                    break;
                case 'F':
                    f = y;
                    break;
                case 'M':
                    m = y;
                    break;
            }
            Console.WriteLine("{0}, {0}, bo-{1}", x, b);
            Console.WriteLine("Banana-fana fo-{0}", f);
            Console.WriteLine("Fee-fi-mo-{0}", m);
            Console.WriteLine("{0}!", x);
            Console.WriteLine();
        }

        static void Main(string[] args) {
            List<string> nameList = new List<string>() { "Gary", "Earl", "Billy", "Felix", "Mary", "Steve" };
            nameList.ForEach(PrintVerse);
        }
    }
}
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!

C++

Translation of: C#
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

static void printVerse(const std::string& name) {
    std::string x = name;
    std::transform(x.begin(), x.end(), x.begin(), ::tolower);
    x[0] = toupper(x[0]);

    std::string y;
    switch (x[0]) {
    case 'A':
    case 'E':
    case 'I':
    case 'O':
    case 'U':
        y = x;
        std::transform(y.begin(), y.end(), y.begin(), ::tolower);
        break;
    default:
        y = x.substr(1);
        break;
    }

    std::string b("b" + y);
    std::string f("f" + y);
    std::string m("m" + y);

    switch (x[0]) {
    case 'B':
        b = y;
        break;
    case 'F':
        f = y;
        break;
    case 'M':
        m = y;
        break;
    default:
        break;
    }

    printf("%s, %s, bo-%s\n", x.c_str(), x.c_str(), b.c_str());
    printf("Banana-fana fo-%s\n", f.c_str());
    printf("Fee-fi-mo-%s\n", m.c_str());
    printf("%s!\n\n", x.c_str());
}

int main() {
    using namespace std;

    vector<string> nameList{ "Gary", "Earl", "Billy", "Felix", "Mary", "Steve" };
    for (auto& name : nameList) {
        printVerse(name);
    }

    return 0;
}
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!

Commodore BASIC

This should be adaptable to most other 8-bit BASICs. After looking at some of the other examples, this example decides to tackle the task of checking for consonant blends (th, fr, sh, ch, chr, etc.) at the start of the name and handle it appropriately.

Note also the code on lines 30 and 75 to convert the case of the first letter... On some Commodore machines, the default is to render text in ALL CAPS, shifted letters become graphic symbols. This program sets the mode to display mixed case [chr$(14)] and then converts the first letter of the name for the purpose of uniform pattern matching in case the user types the name properly with a capitalized first letter.

1 rem name game
2 rem rosetta code
5 dim cn$(3),bl$(3,32):gosub 1000

10 print chr$(147);chr$(14);"Name Game":print
15 cn$(0)="":cn$(1)="b":cn$(2)="f":cn$(3)="m"
20 print chr$(147);chr$(14);"Name Game":print:input "Enter any name";n$
25 rem ensure first letter is lowercase
30 n$=chr$(asc(n$) and 95)+right$(n$,len(n$)-1)
35 rem check vowels
40 v$="aeiou":i$=left$(n$,1):v=0
45 for i=1 to 5:v=i$=mid$(v$,i,1):if not v then next i
50 if v then tn$=n$:goto 70
55 gosub 500
60 if bl then goto 70
65 tn$=right$(n$,len(n$)-1):gosub 600
70 rem capitalize first letter in name 
75 n$=chr$(asc(n$) or 128)+right$(n$,len(n$)-1)
80 gosub 700
83 print:print "Again? (Y/N)"
85 get k$:if k$<>"y" and k$<>"n" then 85
90 if k$="y" then goto 10
95 end

500 rem check blends
510 bl=0:for g=3 to 1 step -1
520 l$=left$(n$,g+1):tn$=right$(n$,len(n$)-(g+1))
530 for i=1 to 32:if l$=bl$(g,i) then bl=-1:return
540 next i:next g
550 return

600 rem check b, f, and m
610 for i=1 to 3:if cn$(i)=chr$(asc(n$)) then cn$(i)=""
620 next i:return

700 rem sing the verse
710 print:print n$;", ";n$;", bo-";cn$(1);tn$
720 print "   Banana-fana fo-";cn$(2);tn$
730 print "   Fee-fi-mo-";cn$(3);tn$
740 print n$;"!"
750 return

1000 rem load blends
1010 for g=1 to 3 
1015 for i=1 to 32
1020 read bl$(g,i):if bl$(g,i)="xx" then next g:return
1030 next i

2000 rem digraphs
2005 data bl,br,ch,ck,cl,cr,dr,fl,fr,gh,gl,gr,ng
2010 data ph,pl,pr,qu,sc,sh,sk,sl,sm,sn,sp,st,sw
2020 data th,tr,tw,wh,wr
2029 data xx
2030 rem trigraphs
2040 data chr,sch,scr,shr,spl,spr,squ,str,thr
2049 data xx
2050 rem quadgraph
2060 data schr,schl
2069 data xx
Output:
Name Game

Enter a name? Gary

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

Again? (Y/N) Y

Name Game

Enter a name? Steve

Steve, Steve, bo-beve
   Banana-fana fo-feve
   Fee-fi-mo-meve
Steve!

Again? (Y/N) Y

Name Game

Enter a name? Erik

Erik, Erik, bo-berik
   Banana-fana fo-ferik
   Fee-fi-mo-merik
Erik!

Again? (Y/N) Y

Enter a name? Charlie

Charlie, Charlie, bo-barlie
   Banana-fana fo-farlie
   Fee-fi-mo-marlie
Charlie!

Again? (Y/N) Y

Name Game

Enter a name? Matthew

Matthew, Matthew, bo-batthew
   Banana-fana fo-fatthew
   Fee-fi-mo-atthew
Matthew!

Again? (Y/N) N

ready.

D

import std.algorithm;
import std.array;
import std.conv;
import std.stdio;
import std.uni;

void printVerse(string name) {
    auto sb = name.map!toLower.array;
    sb[0] = sb[0].toUpper;

    string x = sb.to!string;
    string y;
    switch(sb[0]) {
        case 'A':
        case 'E':
        case 'I':
        case 'O':
        case 'U':
            y = x.map!toLower.to!string;
            break;
        default:
            y = x[1..$];
            break;
    }
    string b = "b" ~ y;
    string f = "f" ~ y;
    string m = "m" ~ y;
    switch (x[0]) {
        case 'B':
            b = y;
            break;
        case 'F':
            f = y;
            break;
        case 'M':
            m = y;
            break;
        default:
            // no adjustment needed
            break;
    }

    writeln(x, ", ", x, ", bo-", b);
    writeln("Banana-fana fo-", f);
    writeln("Fee-fi-mo-", m);
    writeln(x, "!\n");
}

void main() {
    foreach (name; ["Gary","Earl","Billy","Felix","Mary","steve"]) {
        printVerse(name);
    }
}

Delphi

Works with: Delphi version 6.0


function WaitForString(Memo: TMemo; Prompt: string): string;
{Wait for key stroke on TMemo component}
var KW: TKeyWaiter;
begin
{Use custom object to wait and capture key strokes}
KW:=TKeyWaiter.Create(Memo);
try
Memo.Lines.Add(Prompt);
Memo.SelStart:=Memo.SelStart-1;
Memo.SetFocus;
Result:=KW.WaitForString;
finally KW.Free; end;
end;


procedure NameGame(Memo: TMemo);
var Name: string;
var Str2: string;
var FL: Char;

	function GetPattern: string;
	var BStr,FStr,MStr: string;
	begin
	if FL='b' then BStr:='bo-' else BStr:='bo-b';
	if FL='f' then FStr:='fo-' else FStr:='fo-f';
	if FL='m' then MStr:='mo-' else MStr:='mo-m';
	Result:=Format('%S, %S, %S%S',[Name,Name,BStr,Str2])+CRLF;
	Result:=Result+Format('Banana-fana %S%S',[FStr,Str2])+CRLF;
	Result:=Result+Format('Fee-fi-%S%S',[MStr,Str2])+CRLF;
	Result:=Result+Format('%S!',[Name])+CRLF;
	end;

begin
while true do
	begin
	Name:=WaitForString(Memo,'Enter a name: ');
	if Name='' then break;
	Str2:=LowerCase(Name);
	FL:=Str2[1];
	if not (FL in ['a','e','i','o','u']) then Delete(Str2,1,1);

	Memo.Lines.Add(GetPattern);
	end;
end;
Output:
Enter a name: 
Gary

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

Enter a name: 
Earl

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

Enter a name: 
Billy

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

Enter a name: 
Felix

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

Enter a name: 
Mary

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

Enter a name: 
Elapsed Time: 01:18.249 min


Dyalect

func printVerse(name) {
    let x = name[..1].Upper() + name[1..].Lower();
    let y = "AEIOU".IndexOf(x[0]) > -1 ? x.Lower() : x[1..]
    let b = x[0] is 'B' ? y : "b" + y
    let f = x[0] is 'F' ? y : "f" + y
    let m = x[0] is 'M' ? y : "m" + y
 
    print("\(x), \(x), bo-\(b)")
    print("Banana-fana fo-\(f)")
    print("Fee-fi-mo-\(m)")
    print("\(x)!", x)
    print()
}
 
let seq = yields { "Gary", "Earl", "Billy", "Felix", "Mary", "Steve" }
 
for x in seq {
    printVerse(x)
}
Output:
GAary, GAary, bo-bAary
Banana-fana fo-fAary
Fee-fi-mo-mAary
GAary!,GAary

EAarl, EAarl, bo-beaarl
Banana-fana fo-feaarl
Fee-fi-mo-meaarl
EAarl!,EAarl

BIilly, BIilly, bo-Iilly
Banana-fana fo-fIilly
Fee-fi-mo-mIilly
BIilly!,BIilly

FEelix, FEelix, bo-bEelix
Banana-fana fo-Eelix
Fee-fi-mo-mEelix
FEelix!,FEelix

MAary, MAary, bo-bAary
Banana-fana fo-fAary
Fee-fi-mo-Aary
MAary!,MAary

STteve, STteve, bo-bTteve
Banana-fana fo-fTteve
Fee-fi-mo-mTteve
STteve!,STteve

EasyLang

Unlike most other implementations presented in this page, this one actually handles consonant clusters, just like the original song.

proc toLowercase string$ . result$ .
   for i = 1 to len string$
      code = strcode substr string$ i 1
      if code >= 65 and code <= 90
         code += 32
      .
      result$ &= strchar code
   .
.
proc findInStrArray array$[] item$ . index .
   for i = 1 to len array$[]
      if array$[i] = item$
         index = i
         return
      .
   .
   index = 0
.
# This version actually handles consonant clusters
name$ = input
toLowercase name$ lowerName$
vowels$[] = [ "a" "e" "i" "o" "u" ]
for i = 1 to len lowerName$
   letter$ = substr lowerName$ i 1
   findInStrArray vowels$[] letter$ index
   if index <> 0
      truncName1$ = substr lowerName$ i len lowerName$
      break 1
   .
   truncName1$ = ""
.
firstLetter$ = substr lowerName$ 1 1
if firstLetter$ <> "b"
   b$ = "b"
.
if firstLetter$ <> "f"
   f$ = "f"
.
if firstLetter$ <> "m"
   m$ = "m"
.
if b$ = "" or f$ = "" or m$ = ""
   truncName2$ = substr lowerName$ 2 len lowerName$
.
# Determine the appropriate name for each line
if b$ = ""
   bName$ = truncName2$
else
   bName$ = truncName1$
.
if f$ = ""
   fName$ = truncName2$
else
   fName$ = truncName1$
.
if m$ = ""
   mName$ = truncName2$
else
   mName$ = truncName1$
.
# Print the song
print name$ & ", " & name$ & ", " & "bo-" & b$ & bName$
print "Banana-fana fo-" & f$ & fName$
print "Fee-fi-mo-" & m$ & mName$
print name$ & "!"
Input:
Gary
Earl
Billy
Shirley
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!
Shirley, Shirley, bo-birley
Banana-fana fo-firley
Fee-fi-mo-mirley
Shirley!

F#

The function

// 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..])

The Task

fN "Nigel"
Output:
Nigel, Nigel, bo-bigel
Banana-fana fo-figel
Fee-fi-mo-migel
Nigel!
fN "Earl"
Output:
Earl, Earl, bo-bearl
Banana-fana fo-fearl
Fee-fi-mo-mearl
Earl!
fN "Billy"
Output:
Billy, Billy, bo-illy
Banana-fana fo-filly
Fee-fi-mo-milly
Billy!
fN "Fred"
Output:
Fred, Fred, bo-bred
Banana-fana fo-red
Fee-fi-mo-mred
Fred!
fN "Mum"
Output:
Mum, Mum, bo-bum
Banana-fana fo-fum
Fee-fi-mo-um
Mum!

Factor

Translation of: Kotlin
Works with: Factor version 0.98
USING: ascii combinators interpolate io 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

[I ${Name}, ${Name}, bo-${B}${name}
Banana-fana fo-${F}${name}
Fee-fi-mo-${M}${name}
${Name}!I] nl nl ;

qw{ Gary Earl Billy Felix Milton Steve } [ name-game ] each
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!

FreeBASIC

Sub TheGameName(nombre As String)
    Dim As String x = Lcase(nombre)
    x = Ucase(Mid(x,1,1)) + (Mid(x,2,Len(x)-1))
    Dim As String x0 = Ucase(Mid(x,1,1))
    
    Dim As String y
    If x0 = "A" Or x0 = "E" Or x0 = "I" Or x0 = "O" Or x0 = "U" Then
        y = Lcase(x)
    Else
        y = Mid(x,2)
    End If
    
    Dim As String b = "b" + y, f = "f" + y, m = "m" + y

    Select Case x0
    Case "B" : b = y
    Case "F" : f = y
    Case "M" : m = y
    End Select
    
    Print x + ", " + x + ", bo-" + b
    Print "Banana-fana fo-" + f
    Print "Fee-fi-mo-" + m
    Print x + "!" + Chr(10)
End Sub

Dim listanombres(5) As String = {"Gary", "EARL", "billy", "FeLiX", "Mary", "ShirlEY"}
For i As Integer = 0 To Ubound(listanombres)
    TheGameName(listanombres(i))
Next i
Sleep
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ōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website.

In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.

Solution

File:Fōrmulæ - The Name Game 01.png

Test cases

File:Fōrmulæ - The Name Game 02.png

File:Fōrmulæ - The Name Game 03.png

Go

Translation of: Kotlin
package main

import (
    "fmt"
    "strings"
)

func printVerse(name string) {
    x := strings.Title(strings.ToLower(name))
    y := x[1:]
    if strings.Contains("AEIOU", x[:1]) {
        y = strings.ToLower(x)
    }
    b := "b" + y
    f := "f" + y
    m := "m" + y
    switch x[0] {
    case 'B':
        b = y
    case 'F':
        f = y
    case 'M':
        m = y
    }
    fmt.Printf("%s, %s, bo-%s\n", x, x, b)
    fmt.Printf("Banana-fana fo-%s\n", f)
    fmt.Printf("Fee-fi-mo-%s\n", m)
    fmt.Printf("%s!\n\n", x)
}

func main() {
    names := [6]string{"gARY", "Earl", "Billy", "Felix", "Mary", "SHIRley"}
    for _, name := range names {
        printVerse(name)
    }
}
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!

Haskell

-- The Name Game, Ethan Riley, 22nd May 2018
import Data.Char 

isVowel :: Char -> Bool
isVowel c  
    | char == 'A' = True
    | char == 'E' = True
    | char == 'I' = True
    | char == 'O' = True
    | char == 'U' = True
    | otherwise = False
    where char = toUpper c 

isSpecial :: Char -> Bool
isSpecial c 
    | char == 'B' = True
    | char == 'F' = True
    | char == 'M' = True
    | otherwise = False
    where char = toUpper c

shorten :: String -> String
shorten name  
    | isVowel $ head name = map toLower name
    | otherwise = map toLower $ tail name

line :: String -> Char -> String -> String 
line prefix letter name 
    | letter == char = prefix ++ shorten name ++ "\n"
    | otherwise = prefix ++ letter:[] ++ shorten name ++ "\n"
    where char = toLower $ head name

theNameGame :: String -> String
theNameGame name =
    line (name ++ ", " ++ name ++ ", bo-") 'b' name ++ 
    line "Banana-fana fo-" 'f' name ++ 
    line "Fee-fi-mo-" 'm' name ++ 
    name ++ "!\n" 
    
main = 
    mapM_ (putStrLn . theNameGame) ["Gary", "Earl", "Billy", "Felix", "Mike", "Steve"]
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!

J

Substitutions must conform to the region they replace. Cannot directly substitute 'Gary' where 'X' occurs in the template. Work instead with boxes, then at the end raze them to recover the verse.

T=:TEMPLATE=: noun define
   (X), (X), bo-b(Y)
   Banana-fana fo-f(Y)
   Fee-fi-mo-m(Y)
   (X)!
)

nameGame=: monad define
 X=. y
 Y=. tolower }.^:('aeiouAEIOU' -.@:e.~ {.) y
 heady=. tolower {. y
 t=. TEMPLATE -. '()'
 'ix iy'=. I. 'XY' =/ t
 tbox=. ;/ t
 match=. heady = (<: iy){::"0 _ tbox
 remove =. match # iy
 special_rule_box=. a: (<: remove)}tbox
 ybox=. (< Y) iy} special_rule_box
 XBox=. (< X) ix} ybox
 ; XBox
)
   nameGame&> ;:'Gary Earl Billy Felix Mary'
   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!
   

Java

Translation of: Kotlin
import java.util.stream.Stream;

public class NameGame {
    private static void printVerse(String name) {
        StringBuilder sb = new StringBuilder(name.toLowerCase());
        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
        String x = sb.toString();
        String y = "AEIOU".indexOf(x.charAt(0)) > -1 ? x.toLowerCase() : x.substring(1);
        String b = "b" + y;
        String f = "f" + y;
        String m = "m" + y;
        switch (x.charAt(0)) {
            case 'B':
                b = y;
                break;
            case 'F':
                f = y;
                break;
            case 'M':
                m = y;
                break;
            default:
                // no adjustment needed
                break;
        }
        System.out.printf("%s, %s, bo-%s\n", x, x, b);
        System.out.printf("Banana-fana fo-%s\n", f);
        System.out.printf("Fee-fi-mo-%s\n", m);
        System.out.printf("%s!\n\n", x);
    }

    public static void main(String[] args) {
        Stream.of("Gary", "Earl", "Billy", "Felix", "Mary", "Steve").forEach(NameGame::printVerse);
    }
}
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!

JavaScript

function singNameGame(name) {

  // normalize name
  name = name.toLowerCase();
  name = name[0].toUpperCase() + name.slice(1);

  // ... and sometimes y
  // let's pray this works
  let firstVowelPos = (function() {
    let vowels =
      'aeiouàáâãäåæèéêëìíîïòóôõöøùúûüāăąēĕėęěĩīĭįıijōŏőœũūŭůűų'
    .split('');
    function isVowel(char) {
      return vowels.indexOf(char) >= 0;
    }
    if (isVowel(name[0].toLowerCase())) return 0;
    if (name[0] == 'Y' && !isVowel(name[1])) return 0;
    if (name[0] == 'Y' && isVowel(name[1])) return 1;
    vowels = vowels.concat(vowels, 'yÿý'.split(''));
    for (let i = 1; i < name.length; i++)
      if (isVowel(name[i])) return i;
  })();

  let init  = name[0].toLowerCase(),
      trunk = name.slice(firstVowelPos).toLowerCase(),
      b = trunk, f = trunk, m = trunk;

  switch (init) {
    case 'b': f = 'f' + trunk; m = 'm' + trunk; break;
    case 'f': b = 'b' + trunk; m = 'm' + trunk; break;
    case 'm': b = 'b' + trunk; f = 'f' + trunk; break;
    default: b = 'b' + trunk; f = 'f' + trunk; m = 'm' + trunk;
  }

  return `
    <p>${name}, ${name}, bo-${b}<br>
    Banana-fana fo-${f}<br>
    Fee-fi-fo-mo-${m}<br>
    ${name}!<br></p>
  `
}

// testing
let names =
  'Gary Earl Billy Felix Mary Christine Brian Yvonne Yannick'.split(' ');
for (let i = 0; i < names.length; i++)
  document.write(singNameGame(names[i]));
Output:

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

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

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

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

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

Christine, Christine, bo-bistine Banana-fana fo-fistine Fee-fi-fo-mo-mistine Christine!

Brian, Brian, bo-ian Banana-fana fo-fian Fee-fi-fo-mo-mian Brian!

Yvonne, Yvonne, bo-byvonne Banana-fana fo-fyvonne Fee-fi-fo-mo-myvonne Yvonne!

Yannick, Yannick, bo-bannick Banana-fana fo-fannick Fee-fi-fo-mo-mannick Yannick!

jq

Adapted from #Python

Works with: jq

Also works with gojq, the Go implementation of jq, and with fq.

def capitalize:
  if length==0 then .
  else .[0:1] as $c
  | ($c|ascii_upcase) as $C
  | if $c == $C then .
    else $C + .[1:]
    end
  end;
    
def printVerse:
  {x: (ascii_downcase|capitalize)}
  | .x[0:1] as $x0
  | .y = (if $x0|test("[AEIOU]") then .x | ascii_downcase else .x[1:] end)
  | .b = ((select($x0 == "B") | "") // "b")
  | .f = ((select($x0 == "F") | "") // "f")
  | .m = ((select($x0 == "M") | "") // "m")
  | "\(.x), \(.x), bo-\(.b)\(.y)",
   "Banana-fana fo-\(.f)\(.y)",
   "Fee-fi-mo-\(.m)\(.y)",
   "\(.x)!\n" ;

"Gary", "Earl", "Billy", "Felix", "Mary", "Steve"
| printVerse
Output:

As for Wren.

Julia

import Compat: uppercasefirst

function printverse(name::AbstractString)
    X = uppercasefirst(lowercase(name))
    Y = X[1]  ('A', 'E', 'I', 'O', 'U') ? X : SubString(X, 2)
    b = X[1] == 'B' ? "" : "b"
    f = X[1] == 'F' ? "" : "f"
    m = X[1] == 'M' ? "" : "m"
    println("""\
    $(X), $(X), bo-$b$(Y)
    Banana-fana fo-$f$(Y)
    Fee-fi-mo-$m$(Y)
    $(X)!
    """)
    return nothing
end

foreach(TheNameGame.printverse, ("gARY", "Earl", "Billy", "Felix", "Mary", "sHIRley"))
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!

Kotlin

// 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) }
}
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!

Lua

Translation of: C#
function printVerse(name)
    local sb = string.lower(name)
    sb = sb:gsub("^%l", string.upper)
    local x = sb
    local x0 = x:sub(1,1)

    local y
    if x0 == 'A' or x0 == 'E' or x0 == 'I' or x0 == 'O' or x0 == 'U' then
        y = string.lower(x)
    else
        y = x:sub(2)
    end

    local b = "b" .. y
    local f = "f" .. y
    local m = "m" .. y

    if x0 == 'B' then
        b = y
    elseif x0 == 'F' then
        f = y
    elseif x0 == 'M' then
        m = y
    end

    print(x .. ", " .. x .. ", bo-" .. b)
    print("Banana-fana fo-" .. f)
    print("Fee-fi-mo-" .. m)
    print(x .. "!")
    print()

    return nil
end

local nameList = { "Gary", "Earl", "Billy", "Felix", "Mary", "Steve" }
for _,name in pairs(nameList) do
    printVerse(name)
end
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!

M2000 Interpreter

Function format$ with one parameter (a string) process escape codes so we can alter line song$ ...

     song$=format$("\r\n{0}, {0}, bo-{2}{1}\r\nBanana-fana fo-{3}{1}\r\nFee-fi-mo-{4}{1}\r\n{0}!\r\n")
Module The.Name.Game {
      Flush 
      Data "Gary", "Earl","Billy","Felix"
      Document doc$="The Name Game"+{
      }
      Report doc$
      song$={
         {0}, {0}, bo-{2}{1}
         Banana-fana fo-{3}{1}
         Fee-fi-mo-{4}{1}
         {0}!    
         }
      While not empty {
            Read x$
            x$=ucase$(left$(x$,1))+lcase$(mid$(x$,2))
            b$=if$(x$ ~ "B*"->"", "b")
            f$=if$(x$ ~ "F*"->"", "f")
            m$=if$(x$ ~ "M*"->"", "m")
            y$=if$(x$ ~ "[AEIOU]*"->lcase$(x$),Mid$(x$, 2))
            toprint$=format$(song$, x$, y$, b$, f$, m$)
            doc$=toprint$
            report toprint$
      }
      Clipboard doc$
}
The.Name.Game
Output:
The Name Game

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!    

Mathematica / Wolfram Language

ClearAll[NameGame]
NameGame[n_] := Module[{y, b, f, m},
  If[StringStartsQ[ToLowerCase[n], "a" | "e" | "i" | "u" | "o"],
   y = ToLowerCase[n]
   ,
   y = StringDrop[n, 1]
   ];
  b = "b" <> y;
  f = "f" <> y;
  m = "m" <> y;
  Switch[ToLowerCase@StringTake[n, 1],
   "b", b = y,
   "f", f = y,
   "m", m = y
   ];
  StringReplace["(X), (X), bo-(B)\nBanana-fana fo-(F)\nFee-fi-mo-(M)\n(X)! ", {"(X)" -> n, "(B)" -> b, "(F)" -> f, "(M)" -> m}]
]
NameGame["Gary"]
NameGame["Earl"]
NameGame["Billy"]
NameGame["Felix"]
NameGame["Mary"]
NameGame["Steve"]
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!

min

Works with: min version 0.19.3
Translation of: Factor
("AEIOU" "" split swap in?) :vowel?

(
  :Name
  Name "" split first :L
  Name lowercase :name (L vowel?) (name "" split rest "" join @name) unless
  "b" :B
  "f" :F
  "m" :M
  (
    ((L "B" ==) ("" @B))
    ((L "F" ==) ("" @F))
    ((L "M" ==) ("" @M))
  ) case
  "$1, $1, bo-$3$2\nBanana-fana fo-$4$2\nFee-fi-mo-$5$2\n$1!\n"
  (Name name B F M) => % puts!
) :name-game

("Gary" "Earl" "Billy" "Felix" "Milton" "Steve") 'name-game foreach
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!

MIPS Assembly

The cartridge header and print routines were omitted so that the reader can focus on the logic.

	la $a0,theNameGame
	la $s0,theName
	jal PrintString_NameGame
	nop
	jal NewLine
	nop
	
	la $a0,theNameGame
	la $s0,theName2
	jal PrintString_NameGame
	nop
	jal NewLine
	nop	
	
	la $a0,theNameGame
	la $s0,theName3
	jal PrintString_NameGame
	nop
	jal NewLine
	nop	
	
shutdown:
	nop			;project 64 detects an infinite loop and throws an error, unless an extra nop is here.
	b shutdown
	nop
	
PrintString_NameGame:
	pushall
		
DrawChars_NameGame:
		lbu a1,0(a0) 		;Load a character
		.ifdef buildPSX
			nop				;load delay slot - not needed on MIPS III or higher
		.endif
		beqz a1,PrintString_Done	;Done?
		nop
		li $a2,'%'
		bne $a1,$a2,skip_NameGameLC
		nop
			jal insertNameLetterChange
			nop
			addiu a0,1
			b DrawChars_NameGame
			nop
skip_NameGameLC:
		li $a2,'?'
		bne $a1,$a2,skip_NameGameAsIs
		nop
			jal insertName
			nop
			addiu a0,1
			b DrawChars_NameGame
			nop
skip_NameGameAsIs:
		li $a2,10
		bne $a1,$a2,skip_Linefeed
		nop
			jal NewLine
			nop
skip_Linefeed:
		addiu a0,1 					;branch delay slot - Move to next Char
		
		jal PrintChar	;Show Character A0 to the screen
		nop
		
		j DrawChars_NameGame	;Repeat
		nop
PrintString_Done_NameGame:
	popall
	jr ra
	nop
insertName:
	push a0
	push ra
		move $a0,$s0
		jal PrintString
		nop
	pop ra
	pop a0
	jr ra
	nop
insertNameLetterChange:
	push a0
	push ra
		subiu $a0,3
		lbu $a1,($a0)	;we may need to replace the first letter of the name with this character.
		.ifdef buildPSX
			nop				;load delay slot - not needed on MIPS III or higher
		.endif
		move $a0,$s0
		lbu $a2,($a0)
		.ifdef buildPSX
			nop				;load delay slot - not needed on MIPS III or higher
		.endif
		beq $a1,$a2,skipFirstLetter
		nop
			jal PrintChar
			nop
skipFirstLetter:
		;now we check if the $a2 is a vowel, if it is, skip the addiu
		li $a3,'a'
		beq $a3,$a2,FirstLetterIsVowel
		nop
		li $a3,'e'
		beq $a3,$a2,FirstLetterIsVowel
		nop
		li $a3,'i'
		beq $a3,$a2,FirstLetterIsVowel
		nop
		li $a3,'o'
		beq $a3,$a2,FirstLetterIsVowel
		nop
		li $a3,'u'
		beq $a3,$a2,FirstLetterIsVowel
		nop
		addiu $a0,1
FirstLetterIsVowel:
		jal PrintString
		nop
	pop ra
	pop a0
	jr ra
	nop
	
theName:
	.ascii "gary"
	.byte 0		;null terminator
	.align 4	
	
theName2:
	.ascii "earl"
	.byte 0
	.align 4
	
theName3:
	.ascii "billy"
	.byte 0
	.align 4
	
	
theNameGame:
	.ascii "?,?,bo-%"
	.byte 10	;line feed
	.ascii "banana-fana fo-%"
	.byte 10
	.ascii "fee-fi-mo-%"
	.byte 10
	.ascii "?!"
	.byte 0
	.align 4
Output:

Screenshot of emulator

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!

Modula-2

MODULE NameGame;
FROM Strings IMPORT Concat;
FROM ExStrings IMPORT Lowercase;
FROM Terminal IMPORT WriteString, WriteLn, ReadChar;

PROCEDURE PrintVerse(name : ARRAY OF CHAR);
TYPE String = ARRAY[0..64] OF CHAR;
VAR y,b,f,m : String;
BEGIN
    Lowercase(name);

    CASE name[0] OF
        'a','e','i','o','u' : y := name;
    ELSE
        y := name[1..LENGTH(name)];
    END;

    Concat("b", y, b);
    Concat("f", y, f);
    Concat("m", y, m);

    CASE name[0] OF
        'b' : b := y; |
        'f' : f := y; |
        'm' : m := y;
    ELSE
    END;

    name[0] := CAP(name[0]);

    (* Line 1 *)
    WriteString(name);
    WriteString(", ");
    WriteString(name);
    WriteString(", bo-");
    WriteString(b);
    WriteLn;

    (* Line 2 *)
    WriteString("Banana-fana fo-");
    WriteString(f);
    WriteLn;

    (* Line 3 *)
    WriteString("Fee-fi-mo-");
    WriteString(m);
    WriteLn;

    (* Line 4 *)
    WriteString(name);
    WriteString("!");
    WriteLn;

    WriteLn;
END PrintVerse;

BEGIN
    PrintVerse("Gary");
    PrintVerse("Earl");
    PrintVerse("Billy");
    PrintVerse("Felix");
    PrintVerse("Mary");
    PrintVerse("Steve");

    ReadChar;
END NameGame.

Nanoquery

Translation of: Python
def print_verse(n)
        l = {"b", "f", "m"}
        s = n.substring(1)
        if lower(n[0]) in l
                ind = l[lower(n[0])]
                l[ind] = ""
        else if n[0] in {"A", "E", "I", "O", "U"}
                s = lower(n)
        end

        println format("%s, %s, bo-%s%s", n, n, l[0], s)
        println format("Banana-fana fo-%s%s", l[1], s)
        println format("Fee-fi-mo-%s%s", l[2], s)
        println n + "!\n"
end

names = {"Gary", "Earl", "Billy", "Felix", "Mary"}
for n in names
        print_verse(n)
end


Nim

import strutils

const
  StdFmt = "$1, $1, bo-b$2\nBanana-fana fo-f$2\nFee-fi-mo-m$2\n$1!"
  WovelFmt = "$1, $1, bo-b$2\nBanana-fana fo-f$2\nFee-fi-mo-m$2\n$1!"
  BFmt = "$1, $1, bo-$2\nBanana-fana fo-f$2\nFee-fi-mo-m$2\n$1!"
  FFmt = "$1, $1, bo-b$2\nBanana-fana fo-$2\nFee-fi-mo-m$2\n$1!"
  MFmt = "$1, $1, bo-b$2\nBanana-fana fo-f$2\nFee-fi-mo-$2\n$1!"

proc lyrics(name: string): string =
  let tail = name[1..^1]
  result = case name[0].toUpperAscii
           of 'A', 'E', 'I', 'O', 'U', 'Y':
             WovelFmt.format(name, name.toLowerAscii)
           of 'B':
             BFmt.format(name, tail)
           of 'F':
             FFmt.format(name, tail)
           of 'M':
             MFmt.format(name, tail)
           else:
             StdFmt.format(name, tail)
  result = result.capitalizeAscii()

for name in ["Gary", "Earl", "Billy", "Felix", "Mary"]:
  echo name.lyrics()
  echo()
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!

Perl

Translation of: Lua
sub printVerse {
    $x  = ucfirst lc shift;
    $x0 = substr $x, 0, 1;
    $y  = $x0 =~ /[AEIOU]/ ? lc $x : substr $x, 1;
    $b  = $x0 eq 'B' ? $y : 'b' . $y;
    $f  = $x0 eq 'F' ? $y : 'f' . $y;
    $m  = $x0 eq 'M' ? $y : 'm' . $y;
    print "$x, $x, bo-$b\n" . 
          "Banana-fana fo-$f\n" . 
          "Fee-fi-mo-$m\n" . 
          "$x!\n\n";
}

printVerse($_) for <Gary Earl Billy Felix Mary Steve>;
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!

Phix

Translation of: Go
constant fmt = """
%s, %s, bo-%s
Banana-fana fo-%s
Fee-fi-mo-%s
%s!
 
"""
procedure printVerse(string name)
    string x = lower(name)
    integer x1 = upper(x[1]),
            vowel = find(x1,"AEIUO")!=0
    string y = x[2-vowel..$],
           b = 'b'&y, f = 'f'&y, m = 'm'&y
    x[1] = x1
    switch x1 do
        case 'B': b = y
        case 'F': f = y
        case 'M': m = y
    end switch
    printf(1,fmt,{x, x, b, f, m, x})
end procedure
 
constant tests = {"gARY", "Earl", "Billy", "Felix", "Mary", "SHIRley"}
for i=1 to length(tests) do printVerse(tests[i]) end for
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!

Picat

Works with: Picat
print_name_game(Name), Name = [V|Rest], membchk(V, ['A', 'E', 'I', 'O', 'U'])  =>
    L = to_lowercase(V),
    Low = [L|Rest],
    print_verse(Name, [b|Low], [f|Low], [m|Low]).

print_name_game(Name), Name = ['B'|Rest] =>
    print_verse(Name, Rest, [f|Rest], [m|Rest]).

print_name_game(Name), Name = ['F'|Rest] =>
    print_verse(Name, [b|Rest], Rest, [m|Rest]).

print_name_game(Name), Name = ['M'|Rest] =>
    print_verse(Name, [b|Rest], [f|Rest], Rest).

print_name_game(Name), Name = [C|Rest] =>
    print_verse(Name, [b|Rest], [f|Rest], [m|Rest]).

print_verse(Full, B, F, M) =>
    printf("%w, %w, bo-%w\nBanana-fana fo-%w\nFee-fi-mo-%w\n%w!\n\n",
        Full,
        Full,
        B,
        F,
        M,
        Full
    ).

main(Args) =>
    foreach (Name in Args)
        print_name_game(Name)
    end.
Output:
$ picat name_game.pi Gary Earl Billy Felix Mary
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!

PowerShell

Translation of: Chris
## Clear Host from old Ouput
Clear-Host

$Name = Read-Host "Please enter your name"
$Char = ($name.ToUpper())[0]
IF (($Char -eq "A") -or ($Char -eq "E") -or ($Char -eq "I") -or ($Char -eq "O") -or ($Char -eq "U"))
  {
    Write-Host "$Name, $Name, bo-b$($Name.ToLower())"
  }
else
  {
    IF ($Char -eq "B")
      {
        Write-Host "$Name, $Name, bo-$($Name.Substring(1))" 
      }
    else
      {
        Write-Host "$Name, $Name, bo-b$($Name.Substring(1))"        
      }     
  }

  IF (($Char -eq "A") -or ($Char -eq "E") -or ($Char -eq "I") -or ($Char -eq "O") -or ($Char -eq "U"))
  {
    Write-Host "Banana-fana fo-f$($Name.ToLower())"
  }
else
  {
    IF ($Char -eq "F")
      {
        Write-Host "Banana-fana fo-$($Name.Substring(1))" 
      }
    else
      {
        Write-Host "Banana-fana fo-f$($Name.Substring(1))"        
      } 
  }

  IF (($Name[0] -eq "A") -or ($Name[0] -eq "E") -or ($Name[0] -eq "I") -or ($Name[0] -eq "O") -or ($Name[0] -eq "U"))
  {
    Write-Host "Fee-fi-mo-m$($Name.tolower())"
  }
else
  {
    IF ($Char -eq "M")
      {
        Write-Host "Fee-fi-mo-$($Name.Substring(1))" 
      }
    else
      {
        Write-Host "Fee-fi-mo-m$($Name.Substring(1))"        
      }
  }
Write-Host "$Name"

Prolog

map_name1(C, Cs, C, Cs).
map_name1(C, Cs, Fc, [Fc,C|Cs]) :- member(C, ['a','e','i','o','u']).
map_name1(C, Cs, Fc, [Fc|Cs]) :- 
    \+ member(C, ['a','e','i','o','u']), 
    dif(C, Fc).

map_name(C, Cs, Fc, Name) :-
    map_name1(C, Cs, Fc, NChars),
    atom_chars(Name, NChars).

song(Name) :-
   string_lower(Name, LName),
   atom_chars(LName, [First|Chars]),
   
   map_name(First, Chars, 'b', BName),
   map_name(First, Chars, 'f', FName),
   map_name(First, Chars, 'm', MName),
   
   maplist(write, 
           [Name, ", ", Name, ", bo-", BName, '\n',
            "Banana-fana fo-", FName, '\n',
            "Fee-fi-mo-", MName, '\n',
            Name, "!\n\n"]).

test :-
    maplist(song, ["Gary", "Earl", "Billy", "Felix", "Mary"]).
Output:
1 ?- test.
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!

true

Python

def print_verse(n):
    l = ['b', 'f', 'm']
    s = n[1:]
    if str.lower(n[0]) in l:
        l[l.index(str.lower(n[0]))] = ''
    elif n[0] in ['A', 'E', 'I', 'O', 'U']:
        s = str.lower(n)
    print('{0}, {0}, bo-{2}{1}\nBanana-fana fo-{3}{1}\nFee-fi-mo-{4}{1}\n{0}!\n'.format(n, s, *l))

# Assume that the names are in title-case and they're more than one character long
for n in ['Gary', 'Earl', 'Billy', 'Felix', 'Mary']:
    print_verse(n)

q

String search and replace

game_ssr:{[Name]
  V:raze 1 lower\"AEIOUY";                                        / vowels
  tn:lower((Name in V)?1b) _ Name;                                / truncated Name
  s3:{1(-1_)\x,"o-",x}lower first Name;                           / 3rd ssr
  s:"$1, $1, bo-b$2\nBanana-fana-fo-f$2\nFee-fimo-m$2\n$1!\n\n";
  (ssr/).(s;("$1";"$2";s3 0);(Name;tn;s3 1)) }

Amend a list of strings

game_amend:{[Name]
  pfx:Name,", ",Name,", ";                                    / prefix
  n:lower Name;
  sfx:((n in "aeiouy")?1b)_n;                                 / suffix
  s:("bo-b";"Banana-fana fo-f";"Fee-fimo-m";"!";"");          / song template
  @[;0;pfx,] @[;3;Name,] @[;0 1 2;,[;sfx]] @[;where n[0]=last each s;-1_] s }

// test
1 "\n"sv raze game_ssr each ("Gary";"Earl";"Felix";"Stephen";"Ryan";"Jo");
Output:
Gary, Gary, bo-bary
Banana-fana fo-fary
Fee-fimo-mary
Gary!

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

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

Stephen, Stephen, bo-bephen
Banana-fana fo-fephen
Fee-fimo-mephen
Stephen!

Ryan, Ryan, bo-byan
Banana-fana fo-fyan
Fee-fimo-myan
Ryan!

Jo, Jo, bo-bo
Banana-fana fo-fo
Fee-fimo-mo
Jo!

Raku

(formerly 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.

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>
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!

REXX

Extra code was added to the REXX program to capitalize the name (and lowercase all characters in the name except the 1st character).
Also, dual names are supported  (like Mary Ann).

/*REXX program  displays the lyrics of the song "The Name Game" by Shirley Ellis.  */
/* 20230526 Walter Pachl refurbished Gerald Schildberger's original program        */
Parse Arg namelist                          /*obtain optional argument(s) from C.L.*/
If namelist='' Then                         /*Not specified?                       */
  namelist="gAry, eARL, billy, FeLix, MarY" /*  Then use the default.              */
                                            /* [?]  names separated by commas.     */
Do While namelist>''
  namelist=space(namelist)                  /*elide superfluous blanks from list.  */
  Parse Var namelist name',' namelist       /*get name (could be 2 words) from list*/
  call song name                            /*invoke subroutine to display lyrics. */
  End
Exit                                        /*stick a fork in it,  we're all Done. */
/*---------------------------------------------------------------------------------*/
song:
  Parse Arg name
  Parse Value 'b f m' With bb ff mm
  lowercase='abcdefghijklmnopqrstuvwxyz'     /*build 2 alphabets*/
  uppercase=translate(lowercase)
  name =translate(left(name,1),uppercase,lowercase)||,
        translate(substr(name,2),lowercase,uppercase)
  namel=translate(name,lowercase,uppercase)
  Parse Var name first +1 rest
  Select
    When pos(first,'AEIOU')>0 Then Do
      Say name','  name", bo-b"namel
      Say 'Banana-fana fo-f'namel
      Say 'Fee-fi-mo-m'namel
      End
    When pos(first,'BFM')>0 Then Do
      Select
        When first=='B' Then bb=''
        When first=='F' Then ff=''
        When first=='M' Then mm=''
        End
      Say name',' name', bo-'bb||rest
      Say 'Banana-fana fo-'ff||rest
      Say 'Fee-fi-mo-'mm||rest
      End
    Otherwise Do
      Say name','  name', bo-b'rest
      Say 'Banana-fana fo-f'rest
      Say 'Fee-fi-mo-m'rest
      End
    End /*select*/
    Say name'!'
    Say ''
    Return
output   when using the default (internal) names:
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!

Ruby

Works with: Ruby version 2.7.1

More idiomatic Ruby while not being object-oriented. Also, like the Commodore Basic version, we handle consonants at the start of the name using a Regular Expression so we can handle appropriately names like Steve or Chris. Byron is an interesting edge-case because has a "y" and also starts with "b".

#!/usr/bin/env ruby

def print_verse(name)
  first_letter_and_consonants_re = /^.[^aeiyou]*/i

  full_name = name.capitalize # X
  suffixed  = case full_name[0] # Y
              when 'A','E','I','O','U'
                name.downcase
              else
                full_name.sub(first_letter_and_consonants_re, '')
              end

  b_name = "b#{suffixed}"
  f_name = "f#{suffixed}"
  m_name = "m#{suffixed}"

  case full_name[0]
  when 'B'
    b_name = suffixed
  when 'F'
    f_name = suffixed
  when 'M'
    m_name = suffixed
  end

  puts <<~END_VERSE
    #{full_name}, #{full_name}, bo-#{b_name}
    Banana-fana fo-#{f_name}
    Fee-fi-mo-#{m_name}
    #{full_name}!

  END_VERSE
end

%w[Gary Earl Billy Felix Mary Steve Chris Byron].each do |name|
    print_verse name
end
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-beve
Banana-fana fo-feve
Fee-fi-mo-meve
Steve!

Chris, Chris, bo-bis
Banana-fana fo-fis
Fee-fi-mo-mis
Chris!

Byron, Byron, bo-yron
Banana-fana fo-fyron
Fee-fi-mo-myron
Byron!

Scala

object NameGame extends App {
  private def printVerse(name: String): Unit = {
    val x = name.toLowerCase.capitalize

    val y = if ("AEIOU" contains x.head) x.toLowerCase else x.tail

    val (b, f, m) = x.head match {
      case 'B' => (y, "f" + y, "m" + y)
      case 'F' => ("b" + y, y, "m" + y)
      case 'M' => ("b" + y, "f" + y, y)
      case _   => ("b" + y, "f" + y, "m" + y)
    }

    printf("%s, %s, bo-%s\n", x, x, b)
    printf("Banana-fana fo-%s\n", f)
    println(s"Fee-fi-mo-$m")
    println(s"$x!\n")
  }

  Stream("gAry", "earl", "Billy", "Felix", "Mary", "Steve").foreach(printVerse)
}

See it running in your browser by Scastie (JVM).

UNIX Shell

This implements the required rules and also attempts to handle names that start with consonant clusters.

#!/usr/bin/env bash
namegame() {
  local name=$1 b=b f=f m=m
  local rhyme=${name#[^AaEeIiOoUu]}
  while [[ $rhyme == [^AaEeIiOoUuYy]* ]]; do
    rhyme=${rhyme#?}
  done
  if [[ "$rhyme" == [AEIOU]* ]]; then
    rhyme=$(tr A-Z a-z <<<"$rhyme")
  fi
  if [[ $name == [Bb]* ]]; then
    b=
  fi
  if [[ $name == [Ff]* ]]; then
    f=
  fi
  if [[ $name == [Mm]* ]]; then
    m=
  fi
  printf '%s, %s, bo-%s%s\n' "$name" "$name" "$b" "$rhyme"
  printf 'Banana-fana fo-%s%s\n' "$f" "$rhyme"
  printf 'Fee-fi-mo-%s%s\n' "$m" "$rhyme"
  printf '%s!\n' "$name"
}


for name in Gary Earl Billy Felix Mark Frank; do
  namegame "$name"
  echo
done
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!

Mark, Mark, bo-bark
Banana-fana fo-fark
Fee-fi-mo-ark
Mark!

Frank, Frank, bo-bank
Banana-fana fo-ank
Fee-fi-mo-mank
Frank!

VBA

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
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!

Visual Basic .NET

Translation of: C#
Option Strict On

Imports System.Text

Module Module1

    Sub PrintVerse(name As String)
        Dim sb As New StringBuilder(name.ToLower())
        sb(0) = Char.ToUpper(sb(0))

        Dim x = sb.ToString()
        Dim y = If("AEIOU".IndexOf(x(0)) > -1, x.ToLower(), x.Substring(1))
        Dim b = "b" + y
        Dim f = "f" + y
        Dim m = "m" + y
        Select Case x(0)
            Case "B"c
                b = y
                Exit Select
            Case "F"c
                f = y
                Exit Select
            Case "M"c
                m = y
                Exit Select
        End Select

        Console.WriteLine("{0}, {0}, bo-{1}", x, b)
        Console.WriteLine("Banana-fana fo-{0}", f)
        Console.WriteLine("Fee-fi-mo-{0}", m)
        Console.WriteLine("{0}!", x)
        Console.WriteLine()
    End Sub

    Sub Main()
        Dim nameList As New List(Of String) From {"Gary", "Earl", "Billy", "Felix", "Mary", "Steve"}
        nameList.ForEach(AddressOf PrintVerse)
    End Sub

End Module
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!

V (Vlang)

fn main() {
    list := ['Gary', 'Earl', 'Billy', 'Felix', 'Mary']
    for name in list {verse(name)}
}

fn verse(name string) {
    mut b, mut f, mut m, mut y :='','','','' 
    mut x := name.to_lower().title()
    y = x.substr(1, x.len)
    if 'AEIOU'.contains(x[0].ascii_str()) {y = x.to_lower()}
    b = 'b' + y
    f = 'f' + y
    m = 'm' + y
    match x[0].ascii_str() {
        'B' {b = y}
        'F' {f = y}
        'M' {m = y}
        else {}
    }
    println('$x, $x, bo-$b')
    println('Banana-fana fo-$f')
    println('Fee-fi-mo-$m')
    println('$x!\n')
}
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!

Wren

Translation of: Kotlin
Library: Wren-str
import "./str" for Str

var printVerse = Fn.new { |name|
    var x = Str.capitalize(Str.lower(name))
    var z = x[0]
    var y = "AEIOU".contains(z) ? Str.lower(x) : x[1..-1]
    var b = "b%(y)"
    var f = "f%(y)"
    var m = "m%(y)"
    if (z == "B") {
        b = y
    } else if (z == "F") {
        f = y
    } else if (z == "M") {
        m = y
    }
    System.print("%(x), %(x), bo-%(b)")
    System.print("Banana-fana fo-%(f)")
    System.print("Fee-fi-mo-%(m)")
    System.print("%(x)!\n")
}

["Gary", "Earl", "Billy", "Felix", "Mary", "Steve"].each { |name| printVerse.call(name) }
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!

XPL0

proc PrintVerse(Name);
char Name;
int  I, Vowel;

    proc PrintLine(Str, Let);
    int  Str, Let;
    [Text(0, Str);
    if Name(0) # Let then ChOut(0, Let!$20);    \bary
    if Vowel then ChOut(0, Name(0)!$20);        \earl
    Text(0, Name+1);
    CrLf(0);
    ];

[Name(0):= Name(0) & ~$20;      \to uppercase
I:= 1;
while Name(I) do                \to lowercase
    [Name(I):= Name(I) ! $20;  I:= I+1];
case Name(0) of
    ^A,^E,^I,^O,^U: Vowel:= true
other Vowel:= false;
Text(0, Name);  Text(0, ", ");  Text(0, Name);
PrintLine(", bo-", ^B);
PrintLine("Banana-fana fo-", ^F);
PrintLine("Fee-fi-mo-", ^M);
Text(0, Name);  Text(0, "!^m^j^m^j");
];

int Names, I;
[Names:= ["gARY", "Earl", "Billy", "Felix", "Mary", "sHIRley"];
for I:= 0 to 6-1 do PrintVerse(Names(I));
]
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!

Z80 Assembly

Translation of: MIPS Assembly
;;;;;;;;;;;;;;;;;;; HEADER   ;;;;;;;;;;;;;;;;;;;
read "\SrcCPC\winape_macros.asm"
read "\SrcCPC\MemoryMap.asm"
read "\SrcALL\winapeBuildCompat.asm"
;;;;;;;;;;;;;;;;;;; PROGRAM  ;;;;;;;;;;;;;;;;;;;

org &1000

ld hl,namegame
ld de,name1
call PrintString_NameGame


ld hl,namegame
ld de,name2
call PrintString_NameGame


ld hl,namegame
ld de,name3
call PrintString_NameGame

ret  ;return to basic
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintString_NameGame:
ld a,(hl)
or a    ;compare to zero
ret z	;exit on null terminator
cp '?'
jr z,printNameAsIs
cp '%'
jr z,insertName
;else, just print what you see.
call &bb5a   ;amstrad CPC kernel will print the contents of A as an ascii character

continue_NameGame:
inc hl
jr PrintString_NameGame
;;;;;;;;;;;;;;;; execution will never fall through this line without a jump
printNameAsIs:
ex de,hl
push hl
call PrintString
pop hl
ex de,hl
jr continue_NameGame
;;;;;;;;;;;;;;;; execution will never fall through this line without a jump
insertName:
push hl
dec hl
dec hl
dec hl
ld c,(hl)  ;get the b in "bo-%", or the f in "fo-%", etc.
pop hl
ex de,hl   ;swap to the name we wish to print
push hl
ld a,(hl)
cp c
jr z,dontPrintC
cp 'a'
jr z,beginsWithVowel
cp 'e'
jr z,beginsWithVowel
cp 'i'
jr z,beginsWithVowel
cp 'o'
jr z,beginsWithVowel
cp 'u'

ld a,c
call PrintChar
dontPrintC:
inc hl
call PrintString
pop hl
ex de,hl
jr continue_NameGame

beginsWithVowel:
;if name begins with vowel, we print C then the name as-is
ld a,c
call PrintChar
call PrintString ;print name as is

pop hl
ex de,hl
jr continue_NameGame
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintString:
	ld a,(hl)
	or a
	ret z
	call &BB5A
	inc hl
	jr PrintString
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
name1:
db "gary",0
name2:
db "earl",0
name3:
db "billy",0

namegame:
db "?, ?, bo-%",13,10
db "banana-fana fo-%",13,10
db "fee-fi-mo-%",13,10
db "?!",13,10,13,10
db 0
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!

zkl

Translation of: Kotlin
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");
}
List("Gary", "Earl", "Billy", "Felix", "Mary", "Steve").apply2(printVerse);
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!