Das Namensspiel spielen

9

Schreiben Sie ein Programm, um das Namensspiel zu spielen .

Eingang

Ihr Programm sollte in irgendeiner Weise einen einzelnen Namen als Eingabe vom Benutzer akzeptieren (z. B. von der Standardeingabe lesen oder als Befehlszeilenargument). Sie können davon ausgehen, dass der Name ein einzelnes Wort ist, das aus einem Großbuchstaben gefolgt von einem oder mehreren Kleinbuchstaben besteht.

Ausgabe

Ihr Programm muss den Reim für den angegebenen Namen drucken, wie im Lied erläutert, indem Sie die folgende Vorlage ausfüllen:

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

Hier (X)ist der ursprüngliche Name und (Y)der Name in Kleinbuchstaben, wobei alle Anfangskonsonanten entfernt wurden.

Es gibt jedoch eine Ausnahme. Wenn der ursprüngliche Name mit begann m, foder b, sollte es ohne diesen Brief auf der entsprechenden Zeile geschrieben werden. Wenn der Name beispielsweise war Bob, sollte die Zeile "b" mit enden bo-ob. Beachten Sie, dass in diesem Fall alle anderen Konsonanten gehalten werden, so dass für Fredsie ist fo-red, nicht fo-ed.

Beispiele

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!

Wertung

Der kürzeste Code gewinnt.

Hammar
quelle
1
Ich denke, Yes wird als Gesang behandelt, also Yvesist es wie Ivesoder Arnold.
Benutzer unbekannt
1
Aber was ist mit Yates, Yestin, Yolanda oder Yulia?
Ephemient
@ephemient: Ich denke, du könntest Ynur dann als Vokal behandeln, wenn ihm ein Konsonant folgt. Das sollte zumindest diese Fälle abdecken.
Hammar
13
Tucker tut mir leid.
Peter Olson

Antworten:

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

Der Code enthält 5 Steuerzeichen, die ich in Klammern gesetzt habe. Jedes zählt nur als einzelnes Zeichen für die Zeichenanzahl.

BEARBEITEN: Durch Verschieben des ersten Joins (J) nach später und Ändern des Einfügens vor (P) in ein Einfügen nach (p) wurde mir 1 Zeichen gespeichert. Außerdem hat mir das Nichterfassen des O in der Regex 2 weitere Zeichen erspart.

Migimaru
quelle
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

Ungolfed (und ich habe eine Eingabeaufforderung hinzugefügt; die obige wartet nur darauf, dass ein Name eingegeben wird):

      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

Dies ist das erste SNOBOL-Programm, das ich jemals geschrieben habe.

SNOBOL ist eine zeilenorientierte Sprache wie FORTRAN, COBOL oder BASIC. Jede Zeile besteht aus einer optionalen Beschriftung ab Spalte 1, dem Code für die Zeile, der Zuweisungen und Musterabgleich beinhalten kann, und einem optionalen Zweig. Ja, Zeilen enden mit (optionalen) GOTOs. Sie kommen in zwei Formen:

        :(TARGET)

Zweige zu beschriften TARGET, während

        :S(SUCCESS) F(FAILURE)

Verzweigt zu, SUCCESSob die Musterübereinstimmung erfolgreich war oder FAILUREnicht. Sie können auch einfach nach Erfolg verzweigen und bei Misserfolg in die nächste Zeile wechseln oder umgekehrt.

Fortsetzungszeilen beginnen mit einem +oder .. Kommentare beginnen mit a *.

Wie funktioniert es?

Lesen Sie einen Namen ein und konvertieren Sie ihn in Kleinbuchstaben. Richten Sie die B-, F- und M-Namen so ein, dass sie mit einem Vokal beginnen. Überprüfen Sie dann, ob es mit einer Reihe von Konsonanten beginnt. Wenn nicht, sind wir bereit zu gehen! Wenn ja, entfernen Sie die führenden Konsonanten und richten Sie die B-, F- und M-Namen ein, vorausgesetzt, sie beginnen nicht mit einem dieser Buchstaben. Überprüfen Sie abschließend, ob es nacheinander mit jedem dieser Buchstaben beginnt, und korrigieren Sie die Namen nach Bedarf. Dann sind wir bereit, das Namensspiel zu spielen!

Probelauf:

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

Ich habe dies auf dem Hercules S / 370-Mainframe-Emulator ausgeführt, auf dem die Version 6.0a des Michigan Terminal Systems mit SNOBOL4 Version 3.10 vom 1. April 1973 ausgeführt wurde, die am 1. Mai 1975 für MTS erstellt wurde, aber es gibt wahrscheinlich einfachere Möglichkeiten, SNOBOL4 auf einem auszuführen modernes System. :) :)

Bearbeiten: Ein redundanter Erfolgszweig wurde entfernt, der einem Durchfall entspricht (ich wusste nicht, dass ich nur einen Fehlerzweig selbst einfügen kann), wodurch ein nicht benötigtes Zweigetikett entfernt wird, und ein bedingungsloser Goto in einen Fehlerzweig in der vorherigen Zeile umgewandelt. für eine Einsparung von 7 Bytes.

Jetzt, da TIO SNOBOL4 unterstützt, können Sie es online ausprobieren ! Hinweis: Die Größe wird als 429 anstatt als 430 angezeigt, da beim Einfügen dort der endgültige Zeilenvorschub entfernt wurde. Ich habe versucht, die Fortsetzungszeile (die mit beginnt +) in eine einzelne Zeile zu ändern , was in der Mainframe-Version nicht zulässig war, da die Zeile zu lang war, und es hat funktioniert und sie auf 427 reduziert. Offensichtlich erlaubt CSNOBOL4 längere Zeilen. Ich werde meine Punktzahl jedoch bei 430 belassen, da das Skript so viele Bytes auf meinem Computer hatte und SNOBOL außerdem nicht wettbewerbsfähig ist.

David Conrad
quelle
Sie können jetzt SNOBOL4 auf Try it online
Giuseppe
@ Giuseppe Wow, das ist cool! Danke für die Information.
David Conrad
CSNOBOL4 weist noch einige andere Unterschiede auf, da die Zuweisung nur den führenden Platz erfordert, sodass alle Ihre Zeilen wie sein N = TRIM(INPUT)können N =TRIM(INPUT).
Giuseppe
2

J , 149 Zeichen

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

Erläuterung:

Diese Funktion gibt den Namen ohne die Anfangskonsonanten zurück

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

Dann ist der Rest eine Funktion, die die vollständige Zeichenfolge zurückgibt.

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

Bearbeiten: von 119 bis 115 Bytes dank @Martin Ender

Eniallator
quelle
1
Willkommen bei PPCG! Ich glaube, Sie können diesen regulären Ausdruck auf verkürzen /[aeiou]\w*/i.
Martin Ender
1
Sie können die Originalversion durch die verkürzte ersetzen. Das alte wird im Bearbeitungsverlauf des Beitrags beibehalten. Wenn Sie möchten, können Sie frühere Ergebnisse wie JavaScript, <s>119</s> 115 bytesin der Kopfzeile einfügen, um den Leuten einen Hinweis zu geben, dass es ursprünglich eine längere Version gab, wenn sie interessiert sind.
Martin Ender
Achso cool. Wieder bearbeitet :)
Eniallator
1

Clojure , 292 Zeichen nach dem Minimieren

Hier ist ein erster Versuch, fast positiv, ich kann ihn weiter vertiefen:

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

Ich lerne gerade Clojure und dachte, es würde Spaß machen, dies zu versuchen. Hier ist meine Argumentation:

- Um Konsonanten vom Anfang der Zeichenfolge zu entfernen: (drop-while (fn [x] (not (some #(= % x) "aeiou"))) name)

- Um die zusätzlichen Regeln für "b", "f" und "m" zu handhaben, habe ich Text in eine Liste von Phrasen aufgeteilt: [", bo-b" "\nBanana-fana-fo-f" "\nFee-fi-mo-m"]

- Dann habe ich eine Funktion angewendet, die fragt, ob die Phrase endet mit dem gleichen Buchstaben, mit dem der Name beginnt, und der verwendet wurde, um diese 3 Phrasen basierend auf den Regeln des Puzzles zu transformieren

- Der letzte Schritt besteht darin, eine Zeichenfolge mit Ergebnissen zu erstellen

Upgradingdave
quelle
1

Scala 281

Ich habe (X) und (Y) im Muster durch #und ersetzt 012. Sist nur ein neuer Name für Stringund a(b,c,d)ist eine Kurzdefinition fürb.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)

Testaufruf:

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

Und ungolfed:

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")
Benutzer unbekannt
quelle
1

Python 3, 148 145 142 Bytes

Ja, ich weiß, es ist etwas spät, aber ...

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

Es verwendet die neuen F-Strings, um den resultierenden String zu formatieren.

Ich glaube, TIO unterstützt leider noch keine F-Strings.

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

3 Bytes dank @officialaimm gespeichert

Caird Coinheringaahing
quelle
Sparen Sie drei Bytes, indem Sie das Literal 'AEIOUaeiou' verwenden und lower () in der 3. Zeile vermeiden
offiziell am
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'

Ich wusste nicht sehr gut, bevor ich das tat. Ich weiß es jetzt viel besser. Der erste Sed in der Pipeline dupliziert den Namen dreimal, sodass er zu "Bob \ nBob \ nBob \ nBob" anstatt nur zu "Bob" wird. Der nächste Sed macht das schwere Heben.

Erwartet Eingaben auf stdin wie echo Name |sed ...

Ungolfed:

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

Ein paar Notizen. Die ersten vier Übereinstimmungen, 1s, 2s, 3s, 4s, verwandeln die Ausgabe in etwas, das nicht ganz korrekt ist. Bob ist bo-bbob geworden, Fred ist fo-ffred geworden, und Mike ist mo-mmike geworden. Kay würde mo-mkay werden, mkay?

Dann müssen wir entweder bo-bbob durch bo-ob oder bo-bkay durch bo-bay ersetzen. Um dies zu tun, können wir eine Funktion verwenden, bei der wir eine /// Ersetzung durchführen und dann verzweigen, wenn dies erfolgreich war, und über die zweite springen, die wir jetzt überspringen möchten. Aber wenn es fehlschlägt, wollen wir durch den Zweig fallen und die nächste Auswechslung vornehmen.

Der Befehl t [label] führt dies aus und verzweigt nur, wenn ein vorheriges s /// übereinstimmt. Aber zu Beginn des Skripts habe ich bereits ein s /// für jede Zeile geschrieben (die führenden Zahlen in 1s, 2s usw. sind Adressen; sie bedeuten, dass der Befehl nur ausgeführt wird, wenn die Adresse übereinstimmt). Egal auf welcher Linie wir uns befinden, 1, 2, 3 oder 4, mindestens ein s /// hat übereinstimmend. (Ich habe versucht, es umgekehrt zu machen, die Namen zu massieren und danach die "Banane-etc." Hinzuzufügen, bin aber auf diese Weise festgefahren, und der Versuch, alles auf einmal zu tun, würde einige Wiederholungen verursachen.) Glücklicherweise kann die Flagge durch Löschen eines Zweigs gelöscht werden, also machen wir das mit "tx ;: x". tx verzweigt zum x-Label und: x ist das x-Label.

Wütend! Das macht den Gaumen für die letzten beiden Auswechslungen frei. Wir versuchen es mit einem, und wenn es gelingt, verzweigen wir über das andere, sonst machen wir das zweite. In beiden Fällen landen wir am Label: z, und der Musterpuffer enthält eine Textzeile, die auf stdout gedruckt wird.

Vielen Dank, dass Sie mich dazu gebracht haben, genug Zeit mit der Manpage von sed und dem Texinfo-Handbuch zu verbringen, um endlich zu verstehen, wie man mehr als sed s / foo / bar / macht.

David Conrad
quelle
Oh, ich zähle die gesamte Länge des Skripts mit dem Befehl sed und dem |und allem. Vielleicht sollte ich diese Bash / Sed nennen oder anders zählen? Ich weiß es nicht. Ich bin zufrieden mit dem Ist-Zustand, aber lassen Sie mich wissen, ob es nach den Standards von PPCG anders sein sollte.
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

Ich habe gerade festgestellt, dass mein Code fehlschlägt ...
- Entfernt keine Anfangskonstanten.
- Verwaltet nicht das 'Bo-Ob'-Geschäft.

Es ist das weiteste, was ich habe, vielleicht kann es jemand beenden.

Anti Erde
quelle
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
quelle
0

R, 189 Zeichen

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

Mit nur einem weiteren Zeichen können Sie viele Namen auf einmal eingeben:

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
quelle
0

Pyth , 111 Bytes SBCS

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

Testsuite

Code verwendet nicht druckbare Zeichen und wird daher in Stack Exchange nicht richtig angezeigt. Der bereitgestellte Link enthält diese Zeichen und ist die richtige Version des Programms.

hakr14
quelle
-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)
user1027046
quelle