Jugando el juego del nombre

9

Escribe un programa para jugar el juego de nombres .

Entrada

Su programa debe aceptar un solo nombre como entrada del usuario de alguna manera (por ejemplo, leer desde una entrada estándar o como un argumento de línea de comandos). Puede suponer que el nombre es una sola palabra que consiste en una letra mayúscula seguida de una o más letras minúsculas.

Salida

Su programa debe imprimir la rima para el nombre de pila, como se explica en la canción, completando la siguiente plantilla:

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

Aquí, (X)es el nombre original, y (Y)es el nombre en minúsculas con cualquier consonante inicial eliminada.

Hay una excepción, sin embargo. Si el nombre original comenzó con m, fo b, debe escribirse sin esta letra en la línea correspondiente. Por ejemplo, si el nombre era Bob, la línea "b" debería terminar con bo-ob. Tenga en cuenta que en este caso, cualquier otra consonante se mantiene, por lo que Fredno es fo-redasí fo-ed.

Ejemplos

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!

Beto:

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!

Puntuación

El código más corto gana.

hammar
fuente
1
Supongo que Yse maneja como una voz, así Yveses como Iveso Arnold.
usuario desconocido el
1
¿Pero qué hay de Yates, Yestin, Yolanda o Yulia?
Ephemient
@ephemient: supongo que podrías tratar Ycomo una vocal solo si es seguida por una consonante. Eso debería cubrir esos casos al menos.
hammar
13
Lo siento por Tucker.
Peter Olson

Respuestas:

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

El código incluye 5 caracteres de control, que he puesto entre paréntesis. Cada uno solo cuenta como un solo personaje para el recuento de caracteres.

EDITAR: Mover la primera unión (J) a la posterior y cambiar el pegar antes (P) a pegar después (p) me salvó 1 personaje. Además, no capturar la o- en la expresión regular me ahorró 2 caracteres más.

migimaru
fuente
3

SNOBOL4, 437 430 bytes

 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

Sin golf (además, agregué un mensaje; el de arriba solo espera a que se escriba un nombre):

      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

Este es el primer programa SNOBOL que he escrito.

SNOBOL es un lenguaje orientado a líneas, como FORTRAN, COBOL o BASIC. Cada línea consta de una etiqueta opcional que comienza en la columna 1, el código de la línea que puede implicar asignaciones y coincidencia de patrones, y una rama opcional. Sí, las líneas terminan con GOTO (opcionales). Vienen en dos formas:

        :(TARGET)

Ramas para etiquetar TARGET, mientras

        :S(SUCCESS) F(FAILURE)

Se bifurca SUCCESSsi la coincidencia de patrón tuvo éxito o FAILUREno. También puede simplemente ramificarse en el éxito y pasar a la siguiente línea en caso de falla, o viceversa.

Las líneas de continuación comienzan con a +o .. Los comentarios comienzan con a *.

¿Como funciona?

Leer en un nombre, convertirlo a minúsculas. Configure los nombres B, F y M, suponiendo que comience con una vocal. Luego verifique si comienza con un intervalo de consonantes. Si no, ¡estamos listos para partir! Si es así, elimine las consonantes iniciales y configure los nombres B, F y M, suponiendo que no comience con ninguna de esas letras. Finalmente, verifique si comienza con cada una de esas letras, arreglando los nombres según sea necesario. ¡Entonces estamos listos para jugar el juego de los nombres!

Ejecución de muestra:

 # $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

Ejecuté esto en el emulador de mainframe Hercules S / 370 que ejecuta la versión 6.0a del Sistema de terminales de Michigan utilizando SNOBOL4 versión 3.10 del 1 de abril de 1973 creado para MTS el 1 de mayo de 1975, pero probablemente haya formas más fáciles de ejecutar SNOBOL4 en un sistema moderno :)

Editar: se eliminó una rama de éxito redundante que era equivalente a una falla (no me di cuenta de que podía poner solo una rama de falla por sí misma) que elimina una etiqueta de rama innecesaria, y convirtió un goto incondicional en una rama de falla en la línea anterior, para un ahorro de 7 bytes.

Ahora que TIO tiene soporte SNOBOL4, ¡puede probarlo en línea! Nota: Muestra el tamaño como 429 en lugar de 430 porque cuando lo pegué allí, se eliminó el avance de línea final. Traté de cambiar la línea de continuación (la que comienza con +) a una sola línea, que no era legal en la versión de mainframe porque la línea era demasiado larga, y funcionó y la redujo a 427. Obviamente CSNOBOL4 permite líneas más largas. Sin embargo, voy a dejar mi puntaje en 430, porque esa es la cantidad de bytes que tenía el script en mi máquina, y además, SNOBOL es bastante poco competitivo.

David Conrad
fuente
Ahora puede ejecutar SNOBOL4 en Pruébelo en línea
Giuseppe
@Giuseppe Wow, eso es genial! Gracias por hacérmelo saber.
David Conrad el
CSNOBOL4 tiene un par de otras diferencias, ya que la asignación solo requiere el espacio inicial, por lo que todas sus líneas N = TRIM(INPUT)pueden ser N =TRIM(INPUT).
Giuseppe
2

J , 149 caracteres

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
efímero
fuente
2

Javascript, 115 bytes

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

Explicación:

esta función devuelve el nombre sin las consonantes iniciales

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

Entonces el resto es una función que devuelve la cadena cadena completa.

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

Editar: de 119 a 115 bytes gracias a @Martin Ender

eniallator
fuente
1
Bienvenido a PPCG! Creo que puedes acortar esa expresión regular /[aeiou]\w*/i.
Martin Ender
1
Puede reemplazar la versión original por la abreviada. El antiguo se conservará en el historial de edición de la publicación. Si lo desea, puede incluir puntajes anteriores, como JavaScript, <s>119</s> 115 bytesen el encabezado, para dar a las personas una pista de que originalmente había una versión más larga si están interesados.
Martin Ender
Ah, guay. Editado de nuevo :)
eniallator
1

Clojure , 292 caracteres después de minimizar

Aquí hay un primer intento, casi positivo, puedo reducirlo aún más:

(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 "!")))

Estoy aprendiendo clojure y pensé que sería divertido intentarlo. Aquí está mi razonamiento:

- Para quitar las consonantes desde el comienzo de la cadena: (drop-while (fn [x] (not (some #(= % x) "aeiou"))) name)

- Para manejar las reglas adicionales para "b", "f" y "m", dividí el texto en una lista de frases: [", bo-b" "\nBanana-fana-fo-f" "\nFee-fi-mo-m"]

- Luego, apliqué una función que pregunta si la frase termina con la misma letra con la que comienza el nombre, y la usó para transformar esas 3 frases según las reglas del rompecabezas

: el paso final es construir una cadena con resultados

Updadingdave
fuente
1

Scala 281

Reemplacé (X) e (Y) en el patrón con #y 012. Ses solo un nuevo nombre para Stringy a(b,c,d)es una definición abreviada 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)

Invocación de prueba:

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

Y sin golfos:

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")
usuario desconocido
fuente
1

Python 3, 148 145 142 bytes

Sí, sé que es un poco tarde, pero ...

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

Utiliza las nuevas cadenas f para formatear la cadena resultante.

No creo que TIO admita f-strings todavía, desafortunadamente.

Versión antigua

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

Guardado 3 bytes gracias a @officialaimm

caird coinheringaahing
fuente
ahorre tres bytes utilizando el literal 'AEIOUaeiou' y evite el uso de lower () en la tercera línea
officialaimm
1

Sed, 162 bytes

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'

No sabía muy bien antes de hacer esto. Lo sé mucho mejor ahora. El primer sed en la tubería duplica el nombre tres veces para que se convierta en "Bob \ nBob \ nBob \ nBob" en lugar de simplemente "Bob". El siguiente sed hace el trabajo pesado.

Espera entrada en stdin como echo Name |sed ...

Sin 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///'

Un par de notas Los primeros cuatro partidos, 1s, 2s, 3s, 4s, transforman la salida en algo que no es del todo correcto. Bob se ha convertido en bo-bbob, Fred se ha convertido en fo-ffred, y Mike se ha convertido en mo-mmike. Kay se convertiría en mo-mkay, mkay?

Luego, debemos reemplazar bo-bbob con bo-ob o bo-bkay con bo-bay. Para hacer eso, podemos usar una función en la que hacemos una s /// sustitución, y luego bifurcar si tuvo éxito, saltando sobre la segunda que ahora queremos omitir. Pero si falla, queremos pasar por la rama y hacer la próxima sustitución.

El comando t [etiqueta] hace eso, bifurcando solo si una s /// anterior coincide. Pero al comienzo del script ya hice un s /// para cada línea (los números iniciales en 1s, 2s, etc. son direcciones; significan que el comando solo se ejecuta si la dirección coincide). Entonces, no importa en qué línea estemos, 1, 2, 3 o 4, al menos un s /// ha coincidido. (Traté de hacerlo al revés, masajeando los nombres y luego agregando "Banana-etc." Después, pero me quedé atrapado de esa manera, y tratar de hacerlo todo de una vez causaría cierta repetición). Afortunadamente, la bandera puede se borrará tomando una rama, así que hacemos eso con "tx;: x". tx se ramifica a la etiqueta x, y: x es la etiqueta x.

¡Uf! Eso despeja el paladar para las dos sustituciones finales. Probamos uno y, si tiene éxito, nos ramificamos sobre el otro; de lo contrario, hacemos el segundo. De cualquier manera, terminamos en la etiqueta: z y el búfer de patrón contiene una línea de letras que se imprime en stdout.

Gracias por engañarme para que pase suficiente tiempo con la página de manual de sed y el manual de Texinfo para finalmente entender cómo hacer más que sed s / foo / bar /

David Conrad
fuente
Oh, estoy contando toda la longitud del guión con el comando sed y el |y todo. ¿Tal vez debería llamar a esto bash / sed, o contarlo de manera diferente? No lo sé. Estoy contento con él tal cual, pero avíseme si debería ser diferente para los estándares de PPCG.
David Conrad el
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

Acabo de
darme cuenta de que mi código falla ... - No elimina los constonantes iniciales.
- No gestiona el negocio 'bo-ob'.

Es lo más lejos que tengo, tal vez alguien pueda terminarlo.

Anti tierra
fuente
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!'''
]
Armand
fuente
0

R, 189 caracteres

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

Pero con solo un personaje más, puede ingresar muchos nombres de una vez:

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')))
Tommy
fuente
0

Pyth , SBCS de 111 bytes

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

Banco de pruebas

El código utiliza caracteres no imprimibles y, como tal, no se muestra correctamente en Stack Exchange. El enlace proporcionado contiene estos caracteres y es la versión correcta del programa.

hakr14
fuente
-1

Pitón

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)
usuario1027046
fuente