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 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
<lang c>#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;
}</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
<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!
Go
<lang go>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) }
}</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!
Haskell
<lang 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
shorten :: String -> String shorten name
| isVowel $ head name = map toLower name | otherwise = map toLower $ tail name
theNameGame :: String -> String theNameGame name =
name ++ ", " ++ name ++ ", bo-b" ++ shorten name ++ "\n" ++ "Banana-fana fo-f" ++ shorten name ++ "\n" ++ "Fee-fi-mo-m" ++ shorten name ++ "\n" ++ name ++ "!\n"
main = do
mapM_ (putStrLn . theNameGame) ["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-billy Banana-fana fo-filly Fee-fi-mo-milly Billy! Felix, Felix, bo-belix Banana-fana fo-felix Fee-fi-mo-melix Felix! Mike, Mike, bo-bike Banana-fana fo-fike Fee-fi-mo-mike Mike! Steve, Steve, bo-bteve Banana-fana fo-fteve Fee-fi-mo-mteve Steve!
Java
<lang Java>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); }
}</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!
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!
Modula-2
<lang modula2>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.</lang>
Perl 6
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!
Python
<lang 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)</lang>
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).
<lang rexx>/*REXX program displays the lyrics of the song "The Name Game" by Shirley Ellis. */
parse arg $ /*obtain optional argument(s) from C.L.*/
if $= then $="gAry, eARL, billy, FeLix, MarY" /*Not specified? Then use the default.*/
/* [↑] names separated by commas. */ do j=1 until $=; $=space($) /*elide superfluous blanks from list. */ parse var $ name',' $ /*get name (could be 2 words) from list*/ call song name /*invoke subroutine to display lyrics. */ end /*j*/
exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ song: arg c 2 1 z; @b='b'; @f="f"; @m='m' /*obtain name; assign three variables.*/
@abc= 'abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU /*build 2 alphabets*/ z=c || translate( substr(z, 2),@abc,@abcU) /*capitalize name, lowercase the rest. */ parse var z f 2 1 z /*get name, 1st letter, rest of name. */ y=substr(z, 2); zl=translate(z, @abc, @abcU) /*lowercase 2 vars.*/ select when pos(f, 'AEIOU')\==0 then do; say z',' z", bo-b"zl say 'Banana-fana fo-f'zl say 'Fee-fi-mo-m'zl end when pos(f, 'BFM' )\==0 then do; if f=='B' then @b= if f=='F' then @f= if f=='M' then @m= say z',' z", bo-"@b || y say 'Banana-fana fo-'@f || y say 'Fee-fi-mo-'@m || y end otherwise say z',' z", bo-b"y say 'Banana-fana fo-f'y say 'Fee-fi-mo-m'y end /*select*/ say z'!'; say return</lang>
- 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!
Scala
<lang 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)
}</lang>
See it running in your browser by Scastie (JVM).
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
<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!