이름 게임하기


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
그러나 예이츠, 예 스틴, land 란다 또는 율리아는 어떻습니까?
ephemient

@ephemient : Y자음이 따르는 모음 만 취급 할 수있을 것 같습니다 . 그것은 적어도 그러한 경우를 다루어야합니다.
hammar

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. 또한 성공하면 분기하고 실패하면 다음 줄로 넘어갈 수 있습니다.

연속 줄은 a +또는로 시작합니다 .. 주석은로 시작합니다 *.

어떻게 작동합니까?

이름을 읽고 소문자로 변환하십시오. 모음으로 시작한다고 가정하여 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

나는 이걸 실행 헤라클레스 의 6.0A 릴리스 실행 S / 370 메인 프레임 에뮬레이터 미시간 터미널 시스템을 4 월 1 일 5 월 1 일 1975 MTS 위해 만들어진 1973에서 SNOBOL4 버전 3.10를 사용하지만, 실행하는 것이 더 쉬울 방법이있다 SNOBOL4를 켜짐이 현대 시스템. :)

편집 : 불필요한 분기 레이블을 제거하고 이전 줄의 무조건 분기를 실패 분기로 바꾸는 폴 스루와 같은 중복 성공 분기를 제거했습니다 (실패 분기 만 넣을 수 있다는 것을 몰랐습니다). 7 바이트를 절약 할 수 있습니다.

이제 TIO는 SNOBOL4를 지원 하므로 온라인으로 사용해 볼 수 있습니다! 참고 : 붙여 넣을 때 최종 줄 바꿈이 제거되었으므로 크기는 430이 아닌 429로 표시됩니다. 연속 줄 (으로 시작 +하는 줄)을 단일 줄로 변경하려고했는데 줄이 너무 길어서 메인 프레임 버전에서 합법적이지 않았으며 작동하여 427으로 줄었습니다. CSNOBOL4는 더 긴 줄을 허용합니다. 그래도 점수는 430으로하겠습니다. 왜냐하면 스크립트가 내 컴퓨터에있는 바이트 수이며 SNOBOL은 경쟁이 거의 없기 때문입니다.



@ 주세페 와우, 멋지다! 알려 줘서 고마워.
David Conrad

CSNOBOL4에는 할당에 선행 공백 만 있으면되므로 몇 가지 다른 차이점 N = TRIM(INPUT)이 있습니다 N =TRIM(INPUT).
Giuseppe

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

자바 스크립트, 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}!`

편집 : @Martin Ender 덕분에 119에서 115 바이트


1
PPCG에 오신 것을 환영합니다! 나는 당신이 그 정규 표현식을 단축 할 수 있다고 생각합니다 /[aeiou]\w*/i.
Martin Ender

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

스칼라 281

패턴에서 (X)와 (Y)를 #and로 바꿨습니다 012. S단지 새로운 이름 Stringa(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

파이썬 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}!'

@officialaimm 덕분에 3 바이트 절약


'AEIOUaeiou'리터럴을 사용하여 3 바이트를 절약하고 세 번째 줄에서 lower ()를 피하십시오
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를 잘 알지 못했습니다. 나는, 어하는 그것을 알고 많은 지금, 더 나은. 파이프 라인의 첫 번째 sed는 이름을 세 번 복제하므로 "Bob"대신 "Bob \ nBob \ nBob \ nBob"이됩니다. 다음 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///'

몇 가지 메모. 처음 4 개의 일치 항목 (1, 2, 3, 4)은 출력을 정확하지 않은 것으로 변환합니다. 밥은 보밥이되고 프레드는 프레 프레드가되었으며, 마이크는 모 미크가되었습니다. 케이는 모 미가 되었 겠지

그런 다음 bo-bbob을 bo-ob으로, bo-bkay를 bo-bay로 교체해야합니다. 그렇게하기 위해, 우리는 하나의 s /// 대체를하는 기능을 사용하고, 성공하면 분기하고, 이제 우리가 건너 뛰고 싶은 두 번째 기능을 뛰어 넘을 수 있습니다. 그러나 그것이 그리워지면 지점을 넘어 다음 대체를 원합니다.

t [label] 명령은 이전 s ///와 일치하는 경우에만 분기합니다. 그러나 스크립트 시작 부분에서 이미 각 줄에 대해 하나의 s ///를 수행했습니다 (1, 2 등의 선행 숫자는 주소입니다. 주소가 일치하는 경우에만 명령이 수행됨을 의미합니다). 따라서 1, 2, 3 또는 4에 관계없이 하나 이상의 s ///가 일치합니다. (나는 다른 방법으로 이름을 마사지 한 다음 "바나나 등"을 추가하려고 시도했지만 그 방법으로 붙어서 한 번에 모두 시도하면 반복이 발생할 수 있습니다.) 다행히도 플래그는 "tx; : x"로 분기를 수행하여 지 웁니다. tx는 x 레이블로 분기하고 : x는 x 레이블입니다.

아휴! 최종 두 교체에 대한 입맛이 사라집니다. 우리는 하나를 시도하고 성공하면 다른 하나를 넘어서며, 그렇지 않으면 두 번째를 수행합니다. 어느 쪽이든 우리는 : z 레이블로 끝나고 패턴 버퍼에는 stdout으로 인쇄되는 한 줄의 가사가 들어 있습니다.

sed 매뉴얼 페이지와 Texinfo 매뉴얼을 사용하여 sed s / foo / bar / 이상을 수행하는 방법을 마침내 이해하기 위해 충분한 시간을 보내도록 속여 주셔서 감사합니다.


오, 나는 sed 명령으로 스크립트의 전체 길이를 세고 |있습니다. 어쩌면 나는이 bash / sed라고 부르거나 다르게 계산해야합니까? 모르겠어요 나는 그 자체로 만족하지만 PPCG의 표준에 따라 다른지 알려주십시오.
David Conrad

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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.