Memainkan Game Nama

9

Tulis program untuk memainkan permainan nama .

Memasukkan

Program Anda harus menerima satu nama sebagai input dari pengguna dengan cara tertentu (misalnya membaca dari input standar atau sebagai argumen baris perintah). Anda dapat mengasumsikan bahwa nama tersebut adalah satu kata yang terdiri dari huruf besar diikuti oleh satu atau lebih huruf kecil.

Keluaran

Program Anda harus mencetak sajak untuk nama yang diberikan, seperti yang dijelaskan dalam lagu, dengan mengisi templat berikut:

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

Di sini, (X)adalah nama asli, dan (Y)nama dalam huruf kecil dengan setiap konsonan awal dihapus.

Namun, ada satu pengecualian. Jika nama aslinya dimulai dengan m, fatau b, itu harus ditulis tanpa surat ini pada baris yang sesuai. Misal jika namanya Bob, garis "b" harus diakhiri dengan bo-ob. Perhatikan bahwa dalam kasus ini, konsonan lain disimpan, jadi untuk Freditu fo-red, tidak fo-ed.

Contohnya

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!

Mencetak gol

Kode terpendek menang.

hammar
sumber
1
Saya kira Yditangani sebagai vokal, begitu Yvesjuga seperti Ivesatau Arnold.
pengguna tidak diketahui
1
Tetapi bagaimana dengan Yates, Yestin, Yolanda, atau Yulia?
ephemient
@ephemient: Saya kira Anda bisa memperlakukan Ysebagai vokal hanya jika diikuti oleh konsonan. Setidaknya itu harus mencakup kasus-kasus itu.
hammar
13
Saya merasa kasihan pada Tucker.
Peter Olson

Jawaban:

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

Kode mencakup 5 karakter kontrol, yang saya masukkan ke dalam tanda kurung. Masing-masing hanya dihitung sebagai karakter tunggal terhadap jumlah karakter.

EDIT: Memindahkan join pertama (J) ke kemudian dan mengubah paste-before (P) ke paste-after (p) menyelamatkan saya 1 karakter. Juga, tidak menangkap o- di regex menyelamatkan saya 2 karakter lagi.

migimaru
sumber
3

SNOBOL4, 437 430 byte

 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

Tidak tergabung (ditambah saya menambahkan prompt; yang di atas hanya menunggu nama yang akan diketik):

      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

Ini adalah program SNOBOL pertama yang pernah saya tulis.

SNOBOL adalah bahasa berorientasi garis, seperti FORTRAN, COBOL, atau BASIC. Setiap baris terdiri dari label opsional yang dimulai pada kolom 1, kode untuk baris yang dapat melibatkan penugasan dan pencocokan pola, dan cabang opsional. Ya, garis diakhiri dengan GOTO (opsional). Mereka datang dalam dua bentuk:

        :(TARGET)

Cabang untuk diberi label TARGET, sementara

        :S(SUCCESS) F(FAILURE)

Cabang ke SUCCESSjika pola cocok berhasil, atau FAILUREsebaliknya. Anda juga bisa hanya cabang pada kesuksesan dan jatuh ke baris berikutnya pada kegagalan, atau sebaliknya.

Garis lanjutan dimulai dengan a +atau .. Komentar dimulai dengan a *.

Bagaimana cara kerjanya?

Baca dalam nama, ubah menjadi huruf kecil. Atur B-, F-, dan M-nama dengan asumsi itu dimulai dengan vokal. Kemudian periksa apakah itu dimulai dengan rentang konsonan. Jika tidak, kami siap berangkat! Jika demikian, cabut konsonan utama dan atur nama B-, F-, dan M dengan asumsi itu tidak dimulai dengan huruf-huruf itu. Akhirnya, periksa apakah itu dimulai dengan masing-masing huruf pada gilirannya, memperbaiki nama-nama yang diperlukan. Maka kita siap untuk memainkan permainan nama!

Contoh dijalankan:

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

Saya menjalankan ini pada emulator mainframe Hercules S / 370 menjalankan 6.0a rilis Sistem Terminal Michigan menggunakan SNOBOL4 versi 3.10 dari 1 April 1973 dibangun untuk MTS pada 1 Mei 1975, tetapi mungkin ada cara yang lebih mudah untuk menjalankan SNOBOL4 pada sistem modern. :)

Sunting: Menghapus cabang sukses yang berlebihan yang setara dengan fallthrough (saya tidak menyadari bahwa saya dapat menempatkan hanya cabang kegagalan dengan sendirinya) yang menghilangkan label cabang yang tidak dibutuhkan, dan mengubah goto tanpa syarat menjadi cabang kegagalan pada baris sebelumnya, untuk penghematan 7 byte.

Sekarang TIO memiliki dukungan SNOBOL4 Anda dapat mencobanya secara online! Catatan: Ini menunjukkan ukuran sebagai 429 daripada 430 karena ketika saya menempelkannya di sana, umpan baris terakhir dihapus. Saya mencoba mengubah garis kelanjutan (yang dimulai dengan +) menjadi satu baris, yang tidak sah pada versi mainframe karena garis itu terlalu panjang, dan itu bekerja dan membawanya ke 427. Jelas CSNOBOL4 memungkinkan garis yang lebih panjang. Saya akan meninggalkan skor saya di 430, karena itu berapa banyak byte skrip ada di komputer saya, dan selain itu, SNOBOL sangat tidak kompetitif.

David Conrad
sumber
Anda sekarang dapat menjalankan SNOBOL4 di Coba online
Giuseppe
@ Giuseppe Wow, itu keren! Terima kasih telah memberi tahu saya.
David Conrad
CSNOBOL4 memiliki beberapa perbedaan lain, karena penugasan hanya membutuhkan ruang terdepan, sehingga semua baris Anda N = TRIM(INPUT)bisa N =TRIM(INPUT).
Giuseppe
2

J , 149 karakter

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

Penjelasan:

fungsi ini mengembalikan nama tanpa konsonan awal

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

Maka sisanya adalah fungsi mengembalikan string string lengkap.

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

Sunting: dari 119 hingga 115 byte berkat @Martin Ender

eniallator
sumber
1
Selamat datang di PPCG! Saya percaya Anda dapat mempersingkat regex itu menjadi /[aeiou]\w*/i.
Martin Ender
1
Anda dapat mengganti versi aslinya dengan yang singkat. Yang lama akan dipertahankan dalam riwayat edit pos. Jika Anda mau, Anda bisa memasukkan skor sebelumnya seperti JavaScript, <s>119</s> 115 bytesdi header untuk memberi orang petunjuk bahwa pada awalnya ada versi yang lebih panjang jika mereka tertarik.
Martin Ender
Ah keren Diedit lagi :)
eniallator
1

Clojure , 292 karakter setelah diminimalkan

Ini adalah upaya pertama, hampir positif saya bisa membuatnya lebih jauh:

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

Saya baru belajar clojure dan berpikir akan menyenangkan untuk mencobanya. Inilah alasan saya:

- Untuk menghapus konsonan dari awal string: (drop-while (fn [x] (not (some #(= % x) "aeiou"))) name)

- Untuk menangani aturan tambahan untuk "b", "f" dan "m", saya memecah teks menjadi daftar frasa: [", bo-b" "\nBanana-fana-fo-f" "\nFee-fi-mo-m"]

- Lalu, saya menerapkan fungsi yang menanyakan apakah frasa berakhir dengan huruf yang sama dengan nama dimulai, dan menggunakannya untuk mengubah 3 frase berdasarkan aturan teka-teki

- Langkah terakhir adalah membangun string dengan hasil

Upgradedave
sumber
1

Scala 281

Saya mengganti (X) dan (Y) dalam pola dengan #dan 012. Shanyalah nama baru untuk Stringdan a(b,c,d)merupakan definisi singkat untukb.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)

Doa ujian:

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

Dan 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")
Pengguna tidak diketahui
sumber
1

Python 3, 148 145 142 byte

Ya saya tahu ini agak terlambat tapi ...

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

Ia menggunakan f-string baru untuk memformat string yang dihasilkan.

Saya kira TIO belum mendukung f-string, sayangnya.

Versi lama

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

Disimpan 3 byte berkat @officialaimm

caird coinheringaahing
sumber
simpan tiga byte dengan menggunakan literal 'AEIOUaeiou' dan hindari yang lebih rendah () di baris ke-3
officialaimm
1

Sed, 162 byte

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'

Saya tidak tahu sed dengan baik sebelum saya melakukan ini. Aku, uh, tahu itu jauh lebih baik, sekarang. Sed pertama dalam pipa menggandakan nama tiga kali sehingga menjadi "Bob \ nBob \ nBob \ nBob" bukan hanya "Bob". Sed berikutnya melakukan pengangkatan berat.

Mengharapkan input pada stdin like echo Name |sed ...

Tidak Disatukan:

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

Beberapa catatan. Empat pertandingan pertama, 1s, 2s, 3s, 4s, mengubah output menjadi sesuatu yang tidak benar. Bob telah menjadi bo-bbob, Fred menjadi f-ffred, dan Mike telah menjadi mo-mmike. Kay akan menjadi mo-mkay, mkay?

Kemudian, kita perlu mengganti bo-bbob dengan bo-ob, atau bo-bkay dengan bo-bay. Untuk melakukan itu, kita dapat menggunakan fitur di mana kita melakukan substitusi seseorang ///, dan kemudian cabang jika itu berhasil, melompati yang kedua yang sekarang kita ingin lewati. Tetapi jika gagal, kami ingin jatuh melalui cabang dan melakukan penggantian berikutnya.

Perintah t [label] melakukan itu, hanya bercabang jika s /// sebelumnya cocok. Tetapi pada awal skrip saya sudah melakukan satu s /// untuk setiap baris (angka utama dalam 1s, 2s, dll adalah alamat; artinya perintah hanya dilakukan jika alamatnya cocok). Jadi, apa pun baris yang kita pakai, 1, 2, 3, atau 4, setidaknya satu s /// telah cocok. (Saya mencoba melakukannya sebaliknya, memijat nama-nama dan kemudian menambahkan "Pisang-dll." Setelah itu, tetapi macet seperti itu, dan mencoba melakukannya sekaligus akan menyebabkan beberapa pengulangan.) Untungnya, bendera dapat dibersihkan dengan mengambil cabang, jadi kami melakukannya dengan "tx;: x". tx bercabang ke label x, dan: x adalah label x.

Wah! Itu membersihkan langit-langit untuk dua pergantian final. Kami mencoba satu, dan jika berhasil kami bercabang di atas yang lain, kalau tidak kita lakukan yang kedua. Apa pun caranya, kita berakhir pada label: z dan buffer pola berisi satu baris lirik yang dicetak ke stdout.

Terima kasih telah menipu saya untuk menghabiskan waktu yang cukup dengan halaman manual sed dan manual Texinfo untuk akhirnya mengerti bagaimana melakukan lebih dari sed s / foo / bar /

David Conrad
sumber
Oh, aku menghitung seluruh panjang script dengan perintah sed dan the |dan semua. Mungkin saya harus memanggil ini bash / sed, atau menghitungnya secara berbeda? Saya tidak tahu Saya senang dengan itu apa adanya, tetapi beri tahu saya apakah itu harus berbeda dengan standar 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

Baru sadar kode saya gagal ...
- Tidak menghapus konstanta awal.
- Tidak mengelola bisnis 'bo-ob'.

Ini yang terjauh yang saya dapat, mungkin seseorang bisa menyelesaikannya.

Anti Bumi
sumber
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
sumber
0

R, 189 karakter

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

Tetapi dengan hanya satu karakter lagi, Anda dapat memasukkan banyak nama dalam sekali jalan:

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

Pyth , 111 byte SBCS

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

Suite uji

Kode menggunakan karakter yang tidak diinginkan, dan karena itu tidak ditampilkan dengan benar di Stack Exchange. Tautan yang disediakan berisi karakter-karakter ini dan merupakan versi program yang benar.

hakr14
sumber
-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)
pengguna1027046
sumber