Відтворення гри з іменами


9

Напишіть програму, щоб грати в ігри з іменами .

Вхідні дані

Ваша програма певним чином повинна сприймати одне ім'я як вхід від користувача (наприклад, читати зі стандартного вводу або як аргумент командного рядка). Можна припустити, що ім'я - це одне слово, що складається з великої літери, а потім однієї або декількох малих літер.

Вихідні дані

Ваша програма повинна надрукувати риму для заданого імені, як це пояснено в пісні, заповнивши наступний шаблон:

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

Ось (X)оригінальна назва, і (Y)це ім'я в нижньому регістрі, з якого вилучені початкові приголосні.

Однак є один виняток. Якщо початкова назва починалася з m, fабо b, її слід писати без цієї літери у відповідному рядку. Наприклад, якщо ім'я було Bob, рядок "b" повинен закінчуватися bo-ob. Зауважте, що в цьому випадку зберігаються будь-які інші приголосні, так що для Fredцього fo-redнемає fo-ed.

Приклади

Ширлі:

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!

Оцінка балів

Найкоротший код виграє.


1
Я здогадуюсь, Yце обробляється як вокал, так Yvesяк Ivesабо Arnold.
користувач невідомий

1
А як щодо Йейтса, Йєстіна, Йоланда чи Юлії?
ефеміент

@ephemient: Я думаю, ти можеш ставитися Yдо голосної, лише якщо за нею йде приголосний. Це має принаймні охоплювати ці випадки.
хаммар

13
Мені шкода Таккера.
Пітер Олсон

Відповіді:


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

Код включає 5 контрольних символів, які я помістив у дужки. Кожен вважається лише одним символом до числа символів.

РЕДАКТУВАННЯ: Переміщення першого з'єднання (J) на пізніше та зміна вставки перед (P) на пасту після (p) врятувало мене 1 символом. Крім того, незахоплення o- у регексе врятувало мене ще 2 символи.


3

SNOBOL4, 437 430 байт

 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 (плюс я додав підказку; той, хто вище, просто чекає введення імені):

      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

Це перша програма SNOBOL, яку я коли-небудь писав.

SNOBOL - лінійно-орієнтована мова, як FORTRAN, COBOL або BASIC. Кожен рядок складається з необов'язкової мітки, починаючи з стовпця 1, коду для рядка, який може містити призначення та відповідність шаблону, та необов'язкової гілки. Так, рядки закінчуються (необов'язково) GOTO. Вони бувають у двох формах:

        :(TARGET)

Гілки для позначення TARGET, поки

        :S(SUCCESS) F(FAILURE)

Гілки, SUCCESSякщо вдалося збігнути шаблон, чи FAILUREіншим чином. Ви також можете просто відгалужуватися на успіх і провалитися до наступного рядка при відмові, або навпаки.

Лінії продовження починаються з +або .. Коментарі починаються з а *.

Як це працює?

Прочитайте в імені, перетворіть його на малі регістри. Встановіть назви B-, F- та M, припускаючи, що це починається з голосної. Потім перевірте, чи починається він з проміжку приголосних. Якщо ні, ми готові йти! Якщо це так, зніміть провідні приголосні і встановіть імена B-, F- і M, припускаючи, що це не починається з жодної з цих літер. Нарешті, перевірте, чи не починається вона з кожної з цих літер по черзі, виправляючи імена за потребою. Тоді ми готові грати в гру з іменами!

Проба зразка:

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

Я запустив це на емуляторі основного кадру Hercules S / 370 із запуском 6.0a випуску системи Мічіганського терміналу за допомогою SNOBOL4 версії 3.10 з 1 квітня 1973 року, побудованої для MTS 1 травня 1975 року, але, мабуть, є простіші способи запустити SNOBOL4 на a сучасна система. :)

Редагувати: Видалено надлишкову гілку успіху, яка була еквівалентною падінню (я не усвідомлював, що міг би поставити просто гілку відмови), яка усуває непотрібну мітку гілки та перетворила безумовне перехід у гілку відмови на попередньому рядку, для економії 7 байт.

Тепер, коли TIO має підтримку SNOBOL4, ви можете спробувати його в Інтернеті! Примітка. Він показує розмір як 429, а не 430, тому що коли я вставив його, остаточне виведення рядка видалено. Я спробував змінити рядок продовження (той, що починається з +) на один рядок, що не було законним для версії для мейнфрейму, тому що лінія була занадто довгою, вона працювала і знизила її до 427. Очевидно, CSNOBOL4 дозволяє довші рядки. Я збираюся залишити свою оцінку в 430, тому що саме стільки байтів було на моїй машині, а крім того, SNOBOL є досить неконкурентним.


Тепер ви можете запустити SNOBOL4 на " Спробуйте онлайн"
Джузеппе,

@Giuseppe Вау, це здорово! Дякую, що повідомив.
Девід Конрад

CSNOBOL4 має ще кілька відмінностей, оскільки для призначення потрібен лише провідний простір, тому всі ваші рядки N = TRIM(INPUT)можуть бути N =TRIM(INPUT).
Джузеппе

2

J , 149 символів

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 байт

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

Пояснення:

ця функція повертає назву без початкових приголосних

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

Тоді решта - це функція, що повертає повний рядок рядка.

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

Редагувати: від 119 до 115 байт завдяки @Martin Ender


1
Ласкаво просимо до PPCG! Я вважаю, що ви можете скоротити цей вираз /[aeiou]\w*/i.
Мартін Ендер

1
Ви можете замінити оригінальну версію на скорочену. Стара збережеться в історії редагування публікації. Якщо ви хочете, ви можете включити попередні оцінки, як JavaScript, <s>119</s> 115 bytesу заголовок, щоб натякнути людям, що спочатку була довша версія, якщо вони зацікавлені.
Мартін Ендер

Ах, круто. Відредаговано знову :)
eniallator

1

Clojure , 292 символи після мінімізації

Ось перша спроба, майже позитивна, я можу знизити це далі:

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

Я просто вивчаю клоджур і думав, що було б весело це зробити. Ось мої міркування:

- Щоб викреслити приголосні з початку рядка: (drop-while (fn [x] (not (some #(= % x) "aeiou"))) name)

- Для обробки додаткових правил для "b", "f" та "m" я переламав текст до списку фраз: [", bo-b" "\nBanana-fana-fo-f" "\nFee-fi-mo-m"]

- Тоді я застосував функцію, яка запитує, чи закінчується фраза з тією самою буквою, з якої починається ім’я, і використовується для перетворення цих 3 фраз на основі правил головоломки

- Останнім кроком є ​​створення рядка з результатами


1

Scala 281

Я замінив (X) і (Y) в шаблоні на #і 012. Sце лише нове ім'я Stringта a(b,c,d)є скороченим визначенням для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)

Тестовий виклик:

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

І неозорені:

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 байт

Так, я знаю, це трохи пізно, але ...

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

Він використовує нові f-рядки для форматування отриманого рядка.

На жаль, TIO поки не підтримує f-рядки.

Стара версія

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 байти завдяки @officialaimm


зберегти три байта, використовуючи «AEIOUaeiou» буквальним і уникнути нижньої () в 3 - му рядку
officialaimm

1

Sed, 162 байти

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'

Я не дуже добре знав сед, перш ніж це зробив. Я, е, це знаю набагато краще, зараз. Перший sed в трубопроводі дублює назву три рази, тому він стає "Bob \ nBob \ nBob \ nBob" замість просто "Bob". Наступний sed робить важкий підйом.

Очікує введення на зразок stdin echo Name |sed ...

Безголівки:

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

Пару приміток. Перші чотири матчі, 1s, 2s, 3s, 4s, перетворюють вихід у щось не зовсім правильне. Боб став bo-bbob, Фред став foffred, а Майк став mo-mmike. Кей став би мо-лай, гаразд?

Тоді нам потрібно замінити або bo-bbob на bo-ob, або bo-bkay на bo-ob. Для цього ми можемо скористатись функцією, коли ми робимо одну заміну s ///, а потім відгалужимо, якщо це вдалося, перестрибуючи другий, який ми зараз хочемо пропустити. Але якщо він пропустив, ми хочемо провалитися через гілку і зробити наступну заміну.

Команда t [label] робить це, розгалужуючи лише якщо збігався попередній s ///. Але на початку сценарію я вже робив по одному s /// для кожного рядка (провідні числа в 1s, 2s тощо є адресами; вони означають, що команда виконується лише у тому випадку, якщо адреса відповідає). Тож незалежно від того, на якій лінії ми знаходимося, 1, 2, 3 або 4, принаймні один s /// збігався. (Я намагався робити це навпаки, масажуючи назви, а потім додаючи "Банан-інше" після, але застряг таким чином і намагаючись зробити це все відразу спричинить певне повторення.) На щастя, прапор може очистити, взявши гілку, так ми робимо це з "tx;: x". tx відгалужує до мітки x, і: x - мітка x.

Вау! Це очищає піднебіння для останніх двох замін. Ми спробуємо одне, і якщо це вдасться, ми розгалужуємо інше, інакше робимо друге. У будь-якому випадку ми опиняємось на ярлику: z, а буфер шаблону містить один рядок пісень, який друкується на stdout.

Дякуємо, що обдурили мене, щоб витратити достатньо часу на сторінці «sed man man» та керівництві Texinfo, щоб нарешті зрозуміти, як зробити більше, ніж sed s / foo / bar /


О, я рахую всю довжину сценарію з командою sed і the |та all. Можливо, я повинен назвати це bash / sed, або порахувати його по-іншому? Не знаю. Я задоволений цим як є, але дайте мені знати, чи повинно воно відрізнятися за стандартами PPCG.
Девід Конрад

0

Пітона, 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

Щойно зрозумів, що мій код не вдається ...
- Не видаляє початкових обмежувачів.
- Не керує бізнесом "bo-ob".

Це найдальше, що я отримав, можливо, хтось може це закінчити.


0

Гроовий, 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 символів

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

Але, маючи ще один символ, ви можете ввести багато імен за один раз:

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 байт SBCS

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

Тестовий набір

Код використовує недруковані символи і як такий не відображається належним чином на Stack Exchange. Надане посилання містить ці символи і є правильною версією програми.


-1

Пітон

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.