Jouer au jeu de nom


9

Écrivez un programme pour jouer au jeu des noms .

Contribution

Votre programme doit accepter un nom unique comme entrée de l'utilisateur d'une certaine manière (par exemple, lire à partir de l'entrée standard ou comme argument de ligne de commande). Vous pouvez supposer que le nom est un seul mot composé d'une lettre majuscule suivie d'une ou plusieurs lettres minuscules.

Production

Votre programme doit imprimer la rime pour le nom donné, comme expliqué dans la chanson, en remplissant le modèle suivant:

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

Ici, (X)c'est le nom d'origine, et (Y)c'est le nom en minuscule avec toutes les consonnes initiales supprimées.

Il y a cependant une exception. Si le nom d'origine commence par m, fou b, il doit être écrit sans cette lettre sur la ligne correspondante. Par exemple, si le nom était Bob, la ligne "b" devrait se terminer par bo-ob. Notez que dans ce cas, toutes les autres consonnes sont conservées, donc pour Fredc'est fo-redpas fo-ed.

Exemples

Shirley:

Shirley, Shirley, bo-birley
Banana-fana fo-firley
Fee-fi-mo-mirley
Shirley!

Arnold:

Arnold, Arnold, bo-barnold
Banana-fana fo-farnold
Fee-fi-mo-marnold
Arnold!

Bob:

Bob, Bob, bo-ob
Banana-fana fo-fob
Fee-fi-mo-mob
Bob!

Fred:

Fred, Fred, bo-bed
Banana-fana fo-red
Fee-fi-mo-med
Fred!

Notation

Le code le plus court gagne.


1
Je suppose que Yc'est traité comme une voix, Yvesc'est comme Ivesou Arnold.
utilisateur inconnu

1
Mais qu'en est-il de Yates, Yestin, Yolanda ou Yulia?
éphémère

@ephemient: Je suppose que vous ne pouvez traiter Ycomme une voyelle que si elle est suivie d'une consonne. Cela devrait au moins couvrir ces cas.
hammar

13
Je suis désolé pour Tucker.
Peter Olson

Réponses:


3

vi, 118 115

Y2PA,<ESC>Ypj~Y2PIbo-b<c-o>wBanana-fana fo-f<c-o>wFee-fi-mo-m<c-o>2$!<ESC>HJJ:%s/\vo-(([bfm])\2([^aeiou]*))?([bfm]?)[^aeiou]*/o-\3\4
ZZ

Le code comprend 5 caractères de contrôle, que j'ai mis entre parenthèses. Chacun ne compte que comme un seul caractère pour le nombre de caractères.

EDIT: Déplacer la première jointure (J) vers plus tard et changer le collage avant (P) en un collage après (p) m'a sauvé 1 caractère. De plus, ne pas capturer l'o- dans l'expression régulière m'a sauvé 2 caractères supplémentaires.


3

SNOBOL4, 437 430 octets

 N = TRIM(INPUT)
 D = REPLACE(N,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+'abcdefghijklmnopqrstuvwxyz')
 B = "b" D
 F = "f" D
 M = "m" D
 &ANCHOR = 1
 D SPAN('bcdfghjklmnpqrstvwxyz') . I REM . R :F(Y)
 B = "b" R
 F = "f" R
 M = "m" R
 I "b" :S(U)
 I "f" :S(V)
 I "m" :S(W) F(Y)
U D "b" REM . B :(Y)
V D "f" REM . F :(Y)
W D "m" REM . M
Y OUTPUT = N ", " N ", bo-" B
 OUTPUT = "Banana-fana fo-" F
 OUTPUT = "Fee-fi-mo-" M
 OUTPUT = N "!"
END

Non golfé (en plus j'ai ajouté une invite; celle ci-dessus n'attend qu'un nom à taper):

      OUTPUT = "Please enter your name."
      Name = TRIM(INPUT)
      UC = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      LC = 'abcdefghijklmnopqrstuvwxyz'
      Low = REPLACE(Name, UC, LC)
      BName = "b" Low
      FName = "f" Low
      MName = "m" Low
      Consonants = SPAN('bcdfghjklmnpqrstvwxyz')
      &ANCHOR = 1
      Low Consonants . First REM . Rest  :F(READY)
      BName = "b" Rest
      FName = "f" Rest
      MName = "m" Rest
      First "b"                   :S(BINIT)
      First "f"                   :S(FINIT)
      First "m"                   :S(MINIT) F(READY)
BINIT Low "b" REM . BName         :(READY)
FINIT Low "f" REM . FName         :(READY)
MINIT Low "m" REM . MName
READY OUTPUT = Name ", " Name ", bo-" BName
      OUTPUT = "Banana-fana fo-" FName
      OUTPUT = "Fee-fi-mo-" MName
      OUTPUT = Name "!"
END

Ceci est le premier programme SNOBOL que j'ai jamais écrit.

SNOBOL est un langage orienté ligne, comme FORTRAN, COBOL ou BASIC. Chaque ligne se compose d'une étiquette facultative commençant dans la colonne 1, du code de la ligne qui peut impliquer des affectations et une correspondance de modèle, et d'une branche facultative. Oui, les lignes se terminent par (facultatif) GOTO. Ils se présentent sous deux formes:

        :(TARGET)

Branches à étiqueter TARGET, tout en

        :S(SUCCESS) F(FAILURE)

Se branche sur SUCCESSsi la correspondance de modèle a réussi, ou FAILUREautrement. Vous pouvez également vous contenter du succès et passer à la ligne suivante en cas d'échec, ou vice versa.

Les lignes de suite commencent par un +ou .. Les commentaires commencent par un *.

Comment ça marche?

Lisez un nom, convertissez-le en minuscules. Configurez les noms B, F et M en supposant que cela commence par une voyelle. Vérifiez ensuite si cela commence par une série de consonnes. Sinon, nous sommes prêts à partir! Si c'est le cas, supprimez les consonnes principales et définissez les noms B, F et M en supposant que cela ne commence par aucune de ces lettres. Enfin, vérifiez si cela commence par chacune de ces lettres à tour de rôle, en fixant les noms au besoin. Ensuite, nous sommes prêts à jouer au jeu des noms!

Exemple d'exécution:

 # $RUN *SNOBOL4 5=GOLF.SNO+*SOURCE* 6=*DUMMY*(1,28)+*SINK*(1,4)+*DUMMY*
 # Execution begins   16:57:25
   Snowman
   Snowman, Snowman, bo-bowman
   Banana-fana fo-fowman
   Fee-fi-mo-mowman
   Snowman!
 # Execution terminated   16:57:30  T=0.013

J'ai exécuté cela sur l' émulateur de mainframe Hercules S / 370 exécutant la version 6.0a du Michigan Terminal System en utilisant SNOBOL4 version 3.10 à partir du 1er avril 1973, conçu pour MTS le 1er mai 1975, mais il existe probablement des moyens plus faciles d'exécuter SNOBOL4 sur un système moderne. :)

Edit: Suppression d'une branche de réussite redondante équivalente à une solution de remplacement (je ne savais pas que je pouvais mettre une branche de défaillance seule) qui élimine une étiquette de branche inutile et a transformé un goto inconditionnel en une branche de défaillance sur la ligne précédente, pour une économie de 7 octets.

Maintenant que TIO est compatible SNOBOL4, vous pouvez l' essayer en ligne! Remarque: la taille est 429 au lieu de 430, car lorsque je l'ai collée ici, le saut de ligne final a été supprimé. J'ai essayé de changer la ligne de continuation (celle commençant par +) en une seule ligne, ce qui n'était pas légal sur la version mainframe car la ligne était trop longue, et cela a fonctionné et l'a ramenée à 427. Évidemment, CSNOBOL4 autorise des lignes plus longues. Je vais laisser mon score à 430, cependant, car c'est le nombre d'octets du script sur ma machine, et en plus, SNOBOL est assez non compétitif.


Vous pouvez maintenant exécuter SNOBOL4 sur Try it online
Giuseppe

@Giuseppe Wow, c'est cool! Merci de me le faire savoir.
David Conrad

CSNOBOL4 a quelques autres différences, car l'affectation ne nécessite que l'espace de tête, de sorte que toutes vos lignes N = TRIM(INPUT)peuvent l'être N =TRIM(INPUT).
Giuseppe

2

J , 149 caractères

1!:2&2>|.(n,'!');('Fee-fi-mo-';'Banana-fana fo-';n,', ',n,', bo-'),&.>;/'mfb'(,`(}.@])`($:}.)@.((=+.2*5='aeiou'i.]){.)"0 _)a.{~32(23 b.)a.i.n=.1!:1]3

2

Javascript, 115 octets

r=x=>x.match(/[aeiou]\w*/i)[0];f=x=>`${x}, ${x}, bo-b${r(x)}\nBanana-fana fo-f${r(x)}\nFee-fi-mo-m${r(x)}\n${x}!`

Explication:

cette fonction renvoie le nom sans les consonnes initiales

r=x=>x.match(/[aeiouAEIOU]\w*/)[0]

Ensuite, le reste est une fonction renvoyant la chaîne complète.

f=x=>`${x}, ${x}, bo-b${r(x)}\nBanana-fana fo-f${r(x)}\nFee-fi-mo-m${r(x)}\n${x}!`

Edit: de 119 à 115 octets grâce à @Martin Ender


1
Bienvenue chez PPCG! Je pense que vous pouvez raccourcir ce regex /[aeiou]\w*/i.
Martin Ender

1
Vous pouvez remplacer la version originale par la version raccourcie. L'ancien sera conservé dans l'historique des modifications du message. Si vous le souhaitez, vous pouvez inclure les scores précédents comme JavaScript, <s>119</s> 115 bytesdans l'en-tête pour donner aux gens un indice qu'il y avait à l'origine une version plus longue s'ils étaient intéressés.
Martin Ender

Ah cool. Publié à nouveau :)
eniallator

1

Clojure , 292 caractères après minimisation

Voici une première tentative, presque positive, je peux continuer à le faire:

(defn name-game
  [n]
  (let [[b f m] (map (fn [x] (if (some #(= % (first n) (last x)) "bfm")
                              (str (apply str (butlast x)) (apply str (rest n)))
                              (str x (apply str (drop-while (fn [x] (not (some #(= % x) "aeiou"))) n))))) [", bo-b" "\nBanana-fana-fo-f" "\nFee-fi-mo-m"])]
    (str n ", " n b f m "\n" n "!")))

J'apprends juste le clojure et j'ai pensé que ce serait amusant de tenter le coup. Voici mon raisonnement:

- Pour supprimer les consonnes du début de la chaîne: (drop-while (fn [x] (not (some #(= % x) "aeiou"))) name)

- Pour gérer les règles supplémentaires pour "b", "f" et "m", j'ai divisé le texte en liste de phrases: [", bo-b" "\nBanana-fana-fo-f" "\nFee-fi-mo-m"]

- Ensuite, j'ai appliqué une fonction qui demande si la phrase se termine avec la même lettre que le nom commence et utilisée pour transformer ces 3 phrases en fonction des règles du puzzle

- La dernière étape consiste à construire une chaîne avec les résultats


1

Scala 281

J'ai remplacé (X) et (Y) dans le motif par #et 012. Sest juste un nouveau nom Stringet a(b,c,d)est une définition abrégée deb.replaceAll(c,d)

val v="""#, #, bo-b0
Banana-fana fo-f1
Fee-fi-mo-m2
#!"""
type S=String
def a(b:S,c:S,d:S)=b.replaceAll(c,d)
def r(t:S,n:S,i:Int)=if(n(0)=="bfm"(i).toUpper)a(t,"."+i,n.tail)else
a(t,""+i,a(n,"^[^AEIOUaeiou]*([aeiou].*)","$1")).toLowerCase
def x(n:S)=a(r(r(r(v,n,0),n,1),n,2),"#",n)

Appel de test:

val l = List ("Shirley", "Arnold", "Bob", "Fred") 
for (n <- l) println (x (n) + "\n")

Et non golfé:

val templ = """#, #, bo-b0
Banana-fana fo-f1
Fee-fi-mo-m2
#!"""

val names = List ("Shirley", "Arnold", "Bob", "Fred") 
val keys = "bfm"

def recode (template: String, n: String, i: Int) = 
 if (n(0) == keys(i).toUpper)
   template.replaceFirst ("." + i, n.tail) else 
 template.replaceAll ("" + i, (n.replaceAll ("^[^AEIOUYaeiouy]*([aeiou].*)", "$1").toLowerCase))

for (name <- names)
  println (recode (recode (recode (templ, name, 0), name, 1), name, 2).replaceAll ("#", name) + "\n")

1

Python 3, 148 145 145 142 octets

Oui je sais qu'il est un peu tard mais ...

n=input();i=0
r=n[i:].lower()
while n[i]not in'aeiouAEIOU':i+=1;r=n[i:]
print(f'{n}, {n}, bo-b{r}\nBanana-fana fo-f{r}\nFee-fi-mo-m{r}\n{n}!')

Il utilise les nouvelles chaînes f pour formater la chaîne résultante.

Je ne pense pas que TIO supporte encore les chaînes f, malheureusement.

Ancienne version

def f(n,i=0):
 r=n[i:].lower()
 while n[i].lower()not in'aeiou':i+=1;r=n[i:]
 return f'{n}, {n}, bo-b{r}\nBanana-fana fo-f{r}\nFee-fi-mo-m{r}\n{n}!'

Enregistré 3 octets grâce à @officialaimm


économisez trois octets en utilisant le littéral 'AEIOUaeiou' et en évitant la baisse () en 3e ligne
officialaimm

1

Sed, 162 octets

sed 'h;G;G;G' |sed '1s/.*/&, &, bo-b\L&/i;2s/^.*/Banana-fana fo-f\L&/;3s/^.*/Fee-fi-mo-m\L&/;4s/$/!/;tx;:x;s/o-\([bfm]\)\1/o-/i;tz;s/\(o-[bfm]\)[^aeiou]\+/\1/;:z'

Je ne connaissais pas très bien sed avant de faire ça. Je le sais beaucoup mieux maintenant. Le premier sed du pipeline duplique le nom trois fois, il devient donc "Bob \ nBob \ nBob \ nBob" au lieu de "Bob". Le prochain sed fait le gros du travail.

Attend une entrée sur stdin comme echo Name |sed ...

Non golfé:

sed 'h                           ;# copy to hold buffer
G                                ;# append newline + hold buffer to pattern
G                                ;# ditto for next two G's
G' |sed '1s/.*/&, &, bo-b\L&/i   ;# 1st line -> X, X bo-bx (lowercase)
2s/^.*/Banana-fana fo-f\L&/      ;# 2nd line -> Banana-fana fo-fx
3s/^.*/Fee-fi-mo-m\L&/           ;# 3rd line -> Fee-fi-mo-mx
4s/$/!/                          ;# bang the 4th line!
tx                               ;# jump to :x if any s/// has matched
:x                               ;# spoiler alert: it has! reset t-flag
s/o-\([bfm]\)\1/o-/i             ;# match some o-cc where c = [bfm]
tz                               ;# if that matched, branch to :z
s/\(o-[bfm]\)[^aeiou]\+/\1/      ;# replace o-[bfm] plus consonants with o-[bfm]
:z                               ;# target of tz, skips over previous s///'

Quelques notes. Les quatre premières correspondances, 1s, 2s, 3s, 4s, transforment la sortie en quelque chose de pas tout à fait correct. Bob est devenu bo-bbob, Fred est devenu fo-ffred et Mike est devenu mo-mmike. Kay deviendrait mo-mkay, mkay?

Ensuite, nous devons remplacer soit bo-bbob par bo-ob, soit bo-bkay par bo-bay. Pour ce faire, nous pouvons utiliser une fonctionnalité dans laquelle nous effectuons une substitution s ///, puis une branche si elle a réussi, en sautant par-dessus la seconde que nous voulons maintenant ignorer. Mais s'il a raté, nous voulons passer par la branche et faire la prochaine substitution.

La commande t [label] fait cela, en se ramifiant uniquement si un s /// précédent correspond. Mais au début du script, j'ai déjà fait un s /// pour chaque ligne (les premiers chiffres en 1s, 2s, etc. sont des adresses; ils signifient que la commande n'est exécutée que si l'adresse correspond). Donc, quelle que soit la ligne sur laquelle nous nous trouvons, 1, 2, 3 ou 4, au moins un s /// correspond. (J'ai essayé de le faire dans l'autre sens, en massant les noms puis en ajoutant le "Banana-etc." Après, mais je suis resté bloqué de cette façon, et essayer de tout faire en même temps provoquerait des répétitions.) Heureusement, le drapeau peut être effacé en prenant une branche, nous le faisons donc avec "tx;: x". tx se ramifie à l'étiquette x et: x est l'étiquette x.

Ouf! Cela dégage le palais pour les deux dernières substitutions. Nous essayons l'un, et s'il réussit, nous nous branchons sur l'autre, sinon nous faisons le second. Quoi qu'il en soit, nous nous retrouvons avec l'étiquette: z et le tampon de modèle contient une ligne de paroles imprimée sur stdout.

Merci de m'avoir incité à passer assez de temps avec la page de manuel sed et le manuel Texinfo pour enfin comprendre comment faire plus que sed s / foo / bar /


Oh, je compte toute la longueur du script avec la commande sed et le |et tout. Peut-être que je devrais appeler ça bash / sed, ou le compter différemment? Je ne sais pas. J'en suis satisfait tel quel mais faites-moi savoir s'il devrait être différent selon les normes de PPCG.
David Conrad

0

Python, 161

x=raw_input('')
a,b,c=x[0],x[1:],'bfm'
if b[0] in c:b=b[1:]
d="X, X, bo-@\nBanana-fana fo-@\nFee-fi-mo-@\nX!".replace('X',a)
for y in c:d=d.replace('@',y+b,1)
print d

Je viens de réaliser que mon code échoue ...
- Ne supprime pas les constantes initiales.
- Ne gère pas l'activité «bo-ob».

C'est le plus loin que j'ai, peut-être que quelqu'un peut le finir.


0

Groovy, 146

r={n->m={n[0]==it[0]?n[1..-1]:it[1]+(n.toLowerCase()=~'[aeiou].*')[0]};"$n, $n, bo-${m 'Bb'}\nBanana-fana fo-${m 'Ff'}\nFee-fi-mo-${m 'Mm'}\n$n!"}

assert ['Shirley', 'Arnold', 'Bob', 'Fred'].collect { r(it) } == [
'''Shirley, Shirley, bo-birley
Banana-fana fo-firley
Fee-fi-mo-mirley
Shirley!''',
'''Arnold, Arnold, bo-barnold
Banana-fana fo-farnold
Fee-fi-mo-marnold
Arnold!''',
'''Bob, Bob, bo-ob
Banana-fana fo-fob
Fee-fi-mo-mob
Bob!''',
'''Fred, Fred, bo-bed
Banana-fana fo-red
Fee-fi-mo-med
Fred!'''
]

0

R, 189 caractères

x=scan(,'');f=function(b)if(grepl(b,x))sub('.','',x)else tolower(sub('^[^aoueiy]*',b,x,i=T));cat(sprintf('%s, %1$s, bo-%s\nBanana-fana fo-%s\nFee-fi-mo-%s\n%1$s!\n',x,f('B'),f('F'),f('M')))

Mais avec un seul caractère de plus, vous pouvez saisir plusieurs noms en une seule fois:

x=scan(,'');f=function(b)ifelse(grepl(b,x),sub('.','',x),tolower(sub('^[^aoueiy]*',b,x,i=T)));cat(sprintf('%s, %1$s, bo-%s\nBanana-fana fo-%s\nFee-fi-mo-%s\n%1$s!\n',x,f('B'),f('F'),f('M')))

0

Pyth , 111 octets SBCS

V"BFM"IqhzN=aYtrz0.?=aY+rN0:rz0"^[^aeiou]+"k))+%." s­ÞXY:lÍ"*]z2@Y0+." o1}1ÃЬÛJî½"@Y1+."-o Âkq°ë¹è"@Y2+z\!

Suite de tests

Le code utilise des caractères non imprimables et ne s'affiche donc pas correctement sur Stack Exchange. Le lien fourni contient ces caractères et est la version correcte du programme.


-1

Python

n=raw_input('')
if n[0].lower() in ("m", "f", "b"): r=n[1:]
else:
    i = iter(n.lower())
    for a in range(len(n)):
        if i.next() in ("a","e","i","o","u"):
            r = n[a:]
            break
print "%s, %s, bo-b%s\nBanana-fana fo-f%s\nFee-fi-mo-m%s\n%s!" %(name,name,rhyme,rhyme,rhyme,name)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.