The Name Game

From Rosetta Code
Revision as of 23:19, 24 March 2018 by PureFox (talk | contribs) (Added C)
The Name Game is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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

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!

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) {

   var x = name.toLowerCase().capitalize()
   var 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!