İsim Oyununu Oynamak


9

İsim oyununu oynamak için bir program yazın .

Giriş

Programınız, kullanıcı tarafından bir şekilde girdi olarak tek bir ad kabul etmelidir (örneğin standart girdiden veya komut satırı bağımsız değişkeni olarak okuyun). Adın bir büyük harf ve ardından bir veya daha fazla küçük harf içeren tek bir kelime olduğunu varsayabilirsiniz.

Çıktı

Programınız, şarkıda açıklandığı gibi, belirli bir ad için kafiyeyi aşağıdaki şablonu doldurarak yazdırmalıdır:

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

Burada, (X)orijinal ad ve (Y)ilk ünsüzlerin kaldırıldığı küçük harfli addır.

Ancak bir istisna vardır. Orijinal adı ile ortaya çıktıysa m, fya bbu gelen satırda bu mektubu olmadan yazılmalıdır. Örneğin, ad Bob"b" satırı ile bitmelidir bo-ob. Böylece için, bu durumda, herhangi bir başka ünsüzleri tutulur unutmayın Fredöyle fo-reddeğil fo-ed.

Örnekler

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!

puanlama

En kısa kod kazanır.


1
Ben tahmin Ybu yüzden, bir vokal olarak ele Yvesgibidir Ivesya Arnold.
kullanıcı bilinmiyor

1
Peki ya Yates, Yestin, Yolanda veya Yulia?
ephemient

@ephemient: Sanırım Ysesli harf olarak sadece ünsüz tarafından takip edilirse düşünebilirsin . En azından bu davaları kapsamalıdır.
hammar

13
Tucker için üzgünüm.
Peter Olson

Yanıtlar:


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

Kod, parantez içine koyduğum 5 kontrol karakteri içeriyor. Her biri karakter sayısına doğru tek bir karakter olarak sayılır.

DÜZENLEME: İlk birleştirmeyi (J) daha sonraya taşıma ve önce yapıştırma işlemini (P) yapıştırma sonrası (p) olarak değiştirme bana 1 karakter kazandırdı. Ayrıca, normal ifade içinde o- yakalamam bana 2 karakter daha kazandırdı.


3

SNOBOL4, 437 430 bayt

 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 (ayrıca bir bilgi istemi ekledim; yukarıdaki ad sadece bir adın yazılmasını bekler):

      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

Bu şimdiye kadar yazdığım ilk SNOBOL programı.

SNOBOL, FORTRAN, COBOL veya BASIC gibi çizgi odaklı bir dildir. Her satır, 1. sütundan başlayarak isteğe bağlı bir etiket, atamalar ve kalıp eşleşmesi içerebilen satırın kodu ve isteğe bağlı bir daldan oluşur. Evet, çizgiler (isteğe bağlı) GOTO'larla biter. İki şekilde gelirler:

        :(TARGET)

Dallar etiketlemek için TARGETise,

        :S(SUCCESS) F(FAILURE)

Desenin SUCCESSeşleşmesi başarılı olursa veya FAILUREbaşka türlü olursa dallar . Ayrıca başarıya dallayabilir ve başarısızlık durumunda bir sonraki satıra geçebilir veya tersi de olabilir.

Devam çizgileri bir +veya ile başlar .. Yorumlar a ile başlar *.

O nasıl çalışır?

Bir adla okuyun, küçük harfe dönüştürün. Bir sesli harfle başladığını varsayarak B, F ve M adlarını ayarlayın. Sonra bir ünsüz ile başlayıp başlamadığını kontrol edin. Değilse, gitmeye hazırız! Öyleyse, önde gelen ünsüzleri soyun ve bu harflerin hiçbiriyle başlamadığını varsayarak B-, F- ve M-adlarını ayarlayın. Son olarak, bu harflerin her biri ile başlayıp başlamadığını kontrol edin, adları gerektiği gibi düzeltin. O zaman isim oyununu oynamaya hazırız!

Örnek çalışma:

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

Ben bu koştum Hercules ait 6.0a salınımını çalışan S / 370 anabilgisayar emülatörü Michigan Terminali Sistemi 1 Nisan 1 Mayıs 1975 tarihinde MTS için inşa 1973 den SNOBOL4 sürümünü 3.10 kullanarak, ama çalıştırmak için muhtemelen daha kolay yolları vardır SNOBOL4 a üzerinde modern sistem. :)

Düzenleme: Gereksiz bir şube etiketini ortadan kaldırır ve önceki satırda bir başarısızlık dalı haline koşulsuz bir goto döndü (Ben sadece kendi başına bir başarısızlık dalı koyabilirsiniz fark etmemiştim) bir düşüş eşdeğer bir yedek başarı dalı kaldırıldı, 7 bayt tasarruf için.

Artık TIO'da SNOBOL4 desteği var, çevrimiçi deneyebilirsiniz! Not: Boyutu 430 yerine 429 olarak gösterir, çünkü oraya yapıştırdığımda son satır besleme kaldırıldı. Devam hattını (ile başlayan +) tek bir satıra değiştirmeyi denedim , çünkü hat çok uzun olduğu için ana çerçeve sürümünde yasal değildi ve çalıştı ve 427'ye indirdi. Açıkçası CSNOBOL4 daha uzun hatlara izin veriyor. Yine de puanımı 430'da bırakacağım, çünkü betiğin makinemde kaç bayt olduğunu ve ayrıca SNOBOL oldukça rekabetçi değil.


Şimdi SNOBOL4'ü çevrimiçi
Giuseppe

@Giuseppe Wow, bu harika! Bilmeme izin verdiğin için teşekkürler.
David Conrad

CSNOBOL4, atamanın yalnızca önde gelen alanı gerektirdiği için birkaç farklılığa sahiptir, bu nedenle tüm satırlarınız N = TRIM(INPUT)olabilir 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

2

Javascript, 115 Bayt

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

Açıklama:

bu işlev ilk ünsüzler olmadan adı döndürür

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

Sonra geri kalanı dize tam dizesini döndüren bir işlevdir.

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

Düzenleme: @Martin Ender sayesinde 119 ila 115 bayt


1
PPCG'ye Hoşgeldiniz! Bu normal ifadeyi kısaltabileceğine inanıyorum /[aeiou]\w*/i.
Martin Ender

1
Orijinal sürümü kısaltılmış sürümle değiştirebilirsiniz. Eskisi yayının düzenleme geçmişinde korunacaktır. İsterseniz JavaScript, <s>119</s> 115 bytes, başlıkta olduğu gibi önceki puanları ekleyerek insanlara ilgilendikleri takdirde daha uzun bir sürümün olduğu hakkında bir ipucu verebilirsiniz.
Martin Ender

Ah guzel. Tekrar düzenlendi :)
eniallator

1

Clojure , simge durumuna küçültüldükten sonra 292 karakter

İşte ilk girişim, neredeyse olumlu daha fazla uyandırabilirim:

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

Sadece clojure öğreniyorum ve bunu denemenin eğlenceli olacağını düşündüm. İşte benim akıl yürütmem:

- ünsüzleri dizenin başlangıcından çıkarmak için: (drop-while (fn [x] (not (some #(= % x) "aeiou"))) name)

- "b", "f" ve "m" için fazladan kuralları işlemek için, ifadeler listesine metin kırdım: [", bo-b" "\nBanana-fana-fo-f" "\nFee-fi-mo-m"]

- Sonra, cümlenin bitip bitmediğini soran bir işlev uyguladım adıyla başlayan aynı harfle ve bulmacanın kurallarına göre bu 3 ifadeyi dönüştürmek için kullanılır

- Son adım, sonuçlarla bir dize oluşturmaktır


1

Scala 281

I (X) ile desen (Y) ile ikame #ve 012. Siçin yeni bir ad Stringve a(b,c,d)kısayol tanımıb.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)

Test çağrısı:

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

Ve 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")

1

Python 3, 148 145 142 bayt

Evet, biraz geç olduğunu biliyorum ama ...

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

Elde edilen dizeyi biçimlendirmek için yeni f-dizelerini kullanır .

Ne yazık ki TIO'nun f-stringleri henüz desteklemediğini düşünmüyorum.

Eski versiyon

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

@Officialaimm sayesinde 3 bayt kaydedildi


'AEIOUaeiou' değişmez bilgisini kullanarak ve 3. satırda alttan () kaçınarak üç bayt tasarruf edin
officialaimm

1

Sed, 162 bayt

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'

Bunu yapmadan önce sed'i çok iyi bilmiyordum. Ben, uh , şimdi çok daha iyi biliyorum . Boru hattındaki ilk sed, adı üç kez çoğaltır, böylece yalnızca "Bob" yerine "Bob \ nBob \ nBob \ nBob" olur. Bir sonraki sed ağır kaldırma yapıyor.

Gibi stdin girişi bekler 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///'

Birkaç not. İlk dört maç, 1s, 2s, 3s, 4s, çıktıyı tam olarak doğru olmayan bir şeye dönüştürür. Bob bo-bbob oldu, Fred fo-ffred oldu ve Mike mo-mmike oldu. Kay mo-mkay olur muydu?

Daha sonra, bo-bbob'u bo-ob ile veya bo-bkay'ı bo-bay ile değiştirmemiz gerekir. Bunu yapmak için, bir s /// yerine koyma yaptığımız bir özelliği kullanabilir ve başarılı olursa dallamak, şimdi atlamak istediğimiz ikincisinin üzerine atlayabiliriz. Ancak kaçırırsa, şubeden düşüp bir sonraki değişikliği yapmak istiyoruz.

T [label] komutu bunu yapar, ancak önceki s /// eşleşirse dallanır. Ancak betiğin başında her satır için zaten bir s /// yaptım (1s, 2s, vb. Baştaki sayılar adreslerdir; komutun yalnızca adres eşleşmesi durumunda gerçekleştirildiği anlamına gelir). Hangi çizgide olursak olalım, 1, 2, 3 veya 4, en az bir // // eşleşti. (Bunu başka bir şekilde yapmayı denedim, isimlere masaj yaptıktan sonra "Muz-vb." bir dal alarak silinir, bunu "tx;: x" ile yaparız. tx, x etiketine ayrılır ve: x, x etiketidir.

Whew! Bu da son iki oyuncu değişikliği için damak yerini temizler. Birini deneriz ve başarılı olursa diğerinin üzerinde dallanırız, aksi takdirde ikincisini yaparız. Her iki şekilde de: z etiketine ulaşırız ve desen arabelleği stdout'a yazdırılan bir şarkı sözü satırı içerir.

Sed man sayfası ve Texinfo kılavuzu ile nihayet sed s / foo / bar / 'dan daha fazlasını nasıl yapacağımı anlamaya yeteri kadar zaman harcadığım için teşekkürler


Ben, sed komutuyla |ve tüm komut dosyalarının tüm uzunluğunu sayıyorum . Belki bu bash / sed demeliyim, yoksa farklı saymalıyım? Bilmiyorum. Olduğu gibi mutluyum ama PPCG standartlarından farklı olup olmadığını bana bildirin.
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


Kodumun başarısız olduğunu fark ettim ... - İlk ünsüzleri kaldırmaz.
- 'bo-ob' iţini yönetmez.

Olabildiğince uzak, belki biri bitirebilir.


0

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

Ancak sadece bir karakter daha kullanarak, tek seferde birçok isim girebilirsiniz:

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 bayt SBCS

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

Test odası

Kod yazdırılamayan karakterler kullanıyor ve bu nedenle Stack Exchange'de düzgün görüntülenmiyor. Sağlanan bağlantı bu karakterleri içerir ve programın doğru sürümüdür.


-1

piton

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.