운명의 쪽지-직원에게 쪽지 H이나 L, 지정 “높은”또는 “낮음” 피치를 지정하는 A~

좀비 종말이오고 세상은오고 있습니다. 갑자기 누군가는 현재시, 분, 일이 걸리는 공식을 발견하고 피아노에서 연주하는 모든 좀비를 즉시 죽이는 완벽한 음표를 뱉어냅니다. 불행히도, 세계에는 피아노 연주자가 한 명 뿐이며, 음표 읽는 법을 잊어 버렸지 만 여전히 악보를 읽는 법을 알고 있습니다. 물론 이것은 매우 시간에 민감하므로 컴퓨터를 사용하는 것이 당연합니다. 1

다음과 같이 G메모를 작성하여 직원에게 고른 음표를 고음 음자리표로 출력해야합니다.

-----

-----
   |
---|-
   |
--O--

-----

사양:

  • 교대 라인 -----(5 개의 대시)과 공백 라인 의 스태프를 출력해야합니다 . -----총 5가 있습니다 . 이 직원 위에 메모를 겹쳐 야합니다.
  • 입력은 메모가있는 위치를 지정합니다. 입력은 다음과 같습니다
    • 옵션 H이나 L, 지정 “높은”또는 “낮음”
    • 피치를 지정하는 A~ 부터의 글자G
    • 선택적인 #또는 b, 선명하거나 평평하게 지정합니다.
  • “노트”는 다음과 같이 정의됩니다.
    • 하나의 O(자본 O)는 메모 대신에 직원의 중간에 정렬되었습니다. (맨 위 줄은 HF(높은 F)이고 맨 아래 줄은 E(보통 E)입니다.)
    • 3 |초 (세로 막대), 줄기 :
      • 메모가 중간 줄 ( B) 이상인 경우 메모 왼쪽의 한 칸, 아래로 내려가는 음 (아래 쪽 한 칸 시작 ) 또는
      • 음표가 중간 선 아래에있는 경우 음표 오른쪽에 한 칸 띄우고 위쪽으로 이동합니다 (음표 위 한 칸 시작).
    • #또는 b입력에 지정된 경우 노트의 바로 왼쪽에 하나 개의 공간.
  • 노트가 너무 높거나 낮은 경우 원장 선을 추가해야합니다. 이 선들은 ---(5와 반대로 3 개의 대시 폭만) 노트가 원장 위 또는 위 (아래쪽 원장 선의 경우)의 원장 선인 경우에만 나타납니다.
  • 원하는 공간을 원하는 곳에 배치 할 수 있습니다. 예를 들어, 문자를 저장하는 데 도움이되는 경우 빈 줄에 공백이 있거나 원장 줄 뒤에 공백이있을 수 있습니다.

다음은 라인 옆에 모든 노트 이름이있는 스펙을보다 쉽게 ​​이해하기위한 시각화입니다.

      HB
 ---  HA
      HG
----- HF
      HE
----- HD
      HC
----- B
      A
----- G
      F
----- E
      D
 ---  C
      LB
 ---  LA
      LG
 ---  LF
... (bottom cut off for brevity, you get the idea anyway)

다음은 프로그램을 테스트하는 데 사용할 수있는 몇 가지 예입니다.

입력: HG#

 #O
-|---
 |
-|---

-----

-----

-----

입력: LAb

-----

-----

-----

-----

-----
   |
 --|
   |
 bO-

입력: HB

  O
 |--
 |
-|---

-----

-----

-----

-----

입력: C

-----

-----

-----

-----
   |
---|-
   |
 -O-

이것은 이므로 바이트 단위의 가장 짧은 코드가 승리합니다!

1 : 가장 현실적인 박람회 회피! :-피



답변

Golfscript, 211 210 209 197 195 192 자

최신 Python 버전 의 GolfScript 버전 (이 게시물 기준)에 당첨되었습니다 .

"J"\+[0]+.1=71>>3<{}/@7*2/246-@3+7%-:z;:c;21,{..3z<3z
if<\11z>11z
if>|{;}{...2>\12<&\2%.{'-'' 'if}:Q~:9;&Q\.z={c!9{[c]''+}if}{..z>\4z+<&8z>&'|'9if}if\.z='o'9if\..z
4-\<\z<&7z<&'|'9if\;3$n}if}/

여기에서 테스트 하십시오 (처음 두 줄은 사용자 입력이며 일반적으로 stdin에서 나옵니다).

‘판독 가능’버전 :

;"HCb"

"J"\+[0]+       #process input
.1=71>>3<       #first char is HJL, second is letter, third is #b or space
{}/             #spill chars onto stack, now we working with ints
@7*2/246-@3+7%- #convert HC/JD/LE etc to a number from 0 to 20
:z;:c;
21,{            #for r in range(21):
  ..3z<3z if<           #either out-of-bounds or process the line
  \11z>11z if>|
  {;}{
    ...2>\12<&\2%.{'-'' 'if}:Q~:9;&Q\        #1st char
    .z={c!9{[c]''+}if}                       #2nd char accidental
       {..z>\4z+<&8z>&'|'9if}if\            #2nd char stem or row
    .z='o'9if\                              #3rd char
    ..z 4-\<\z<&7z<&'|'9if\                 #4th char stem or row
    ;3$                                      #5th char=1st char
    n
  }if
}/


답변

루비 – 271 267 252 249 234 229 220 214 자

문자 그대로 루비를 배웠습니다. 따라서 골프의 질을 향상시킬 여지가 확실히 있습니다. 아니면 정말 뭐든지 그러나 가변 문자열이있는 언어가 필요했습니다. 🙂

def f(n)s=[0]*20
s.fill{|i|i%2>0?i<3||i>11?" ---":?-*5:" "*5}
s[l=(3-n[(p="H_L".index n[0])?1:0].ord)%7+7*(p||1)][1,2]=("#b"[n[-1]]||s[l][1])+?O
s[l+3-2*o=l>7?3:1,3].map{|t|t[o]=?|}
puts s[[3,l].min..[11,l].max]end

언 골프 :

def f(note)
  staff=[]
  0.step(20) {|i| staff[i] = " "*5}
  1.step(19,2) {|i| staff[i] = " ---"}
  3.step(11,2) {|i| staff[i] = "-"*5}
  level = 7
  if !(pos="HL".index note[i=0]).nil?
    level = 14*pos
    i += 1
  end
  level += (73-note[i].ord)%7
  staff[level][2] = "O"
  mark = note[-1]
  if !"#b".index(mark).nil?
    staff[level][1] = mark
  end
  offset = (level > 7) ? 3 : 1
  staff[level-2*offset+3,3].map {|line| line[offset] = "|"}
  first = [3,level].min
  last = [11,level].max
  puts s[first..last]
end

선행 빈 줄이 허용되는 경우 다른 2자를 212 자로 줄일 수 있습니다. 이 솔루션은 인쇄되지 않은 행을 채우지 않습니다.

def f(n)s=[]
[3,l=(3-n[(p="H_L".index n[0])?1:0].ord)%7+7*(p||1)].min.step(l>11?l:11){|i|s[i]=i%2>0?i<3||i>11?" ---":?-*5:" "*5}
s[l][1,2]=("#b"[n[-1]]||s[l][1])+?O
s[l+3-2*o=l>7?3:1,3].map{|t|t[o]=?|}
puts s
end

람다의 공정한 게임입니까? 그런 다음 첫 번째 접근 방식으로 210자를 얻을 수 있습니다.

f=->n{s=[0]*20
s.fill{|i|i%2>0?i<3||i>11?" ---":?-*5:" "*5}
s[l=(3-n[(p="H_L".index n[0])?1:0].ord)%7+7*(p||1)][1,2]=("#b"[n[-1]]||s[l][1])+?O
s[l+3-2*o=l>7?3:1,3].map{|t|t[o]=?|}
puts s[[3,l].min..[11,l].max]}

또는 빈 줄이 추가 된 207 자 :

f=->n{s=[]
[3,l=(3-n[(p="H_L".index n[0])?1:0].ord)%7+7*(p||1)].min.step(l>11?l:11){|i|s[i]=i%2>0?i<3||i>11?" ---":?-*5:" "*5}
s[l][1,2]=("#b"[n[-1]]||s[l][1])+?O
s[l+3-2*o=l>7?3:1,3].map{|t|t[o]=?|}
puts s}

물론 지금해야합니다 f.call("HGb").


답변

파이썬, 329 309 295 286 280 277 자

조금 더 골프를 쳤다. 여전히 향상 될 수는 있지만이 방법으로 루비 또는 골프 스크립트 솔루션을 이길 수 있는지 확실하지 않습니다.

R=range
N='J'+raw_input()+' '
X=N[1]>'G'
a,b,c=N[X:3+X]
z=266-ord(a)/2*7+(ord(b)-4)%7
Z=[list((' '*5,(' ---','-'*5)[8<r<18])[r%2])for r in R(21)]
Z[z][2]='o'
if' '<c:Z[z][1]=c
Q=(z<13)*2
for i in(1,2,3):Z[z+i*Q-i][Q+1]='|'
for r in R(max(17,z),min(z-1,8),-1):print''.join(Z[r])

처음에는 한 줄씩 인쇄했지만 너무 많이 걸리므로 문자열 그리드를 생성 한 다음 채워야 할 내용을 입력합니다. 입력은 명령 줄에서 입력합니다. 예 :

>echo HG# | python note2_golf.py
 #o
-|---
 |
-|---

-----

-----

-----


답변

GolfScript – 243 232 228 227 자

CoffeeScript 답변을 GolfScript로 변환했는데 문자열 조작에 훨씬 더 적합합니다.

편집 : 증가 연산자를 올바르게 사용하여 6 문자를 저장하고, 스택을 잘 사용하여 3 문자를 사용하고, 사용하지 않는 연산자를 무의식적으로 재정 의하여 6 문자를 추가하고 유예 줄 뒤에 후행 공백을 인쇄하지 않으면 6 문자를 절약했습니다.

완전히 골프 :

..0="HL"?2+3%:o)2%.@="CDEFGAB"?7o*+:`2%45 32if:r;
).2$,<{=}{;;r}if:&;
[" "5*:|" ---":g]4*[|"-"5*]5*+[|g|]+.
[`<~]\[`>([0=:^&79r^]''+\~]
+17`<`)18if<9`>`9if:j>:t 13`>.2*):x;
4,1>{`j-\2${+}{-}if}%\;
{.@<\t>(:v[x<'|'+x)v>+]\++:t}
/-1%n*

의견으로 :

# extract octave
..0="HL"?2+3%:o

# extract note
2%1\-.@="CDEFGAB"?7o*+:k

# line spacer
2%45 32if:r;

# extract accidental
1+.2$,<{=}{;;r}if:a;

# staff
[" "5*:|" --- ":g]4*[|"-"5*]5*+[|g|]+.

# lines below
[k<~]\

# note line and above
[k>([0=:w a 79r w]''+\~]+

# cut off just what we need
17k<1k+18if<
9k>k 9if:j>:t;

# and the note stem
13k>.2*1+:x;4,1>{k j-\2${+}{-}if}%\;

{
  .t<\
  t>(:v[x<'|'+1x+v>+]\++:t;
}/

# now output the note
t-1%n*


답변

파이썬, 250 245 242 235 자

매우 다른 접근 방식으로 인해 다른 방법이 끝났습니다! 입력 처리 코드는 비슷하지만 그에 관한 것입니다.

M=' -'
N=raw_input()+M
a,b,c=('J'+N)[N>'G':][:3]
z=ord(a)*7/2-246-(ord(b)+3)%7
for r in range(21):
 L=M[r%2];F=M[2<r<12and r%2]
 if min(3,z)<=r<=max(11,z):print F+((L,'|')[8>z<r<z+4],(L,c)[M<c])[r==z]+(L,'o')[r==z]+(L,'|')[z-4<r<z>7]+F

행과 열을 기준으로 각 문자의 값을 매핑 한 다음 인쇄를 골프화했습니다.

#given row r, with note on row n, how to print each char?
#rows are:
#       HB : 0
#  ---  HA : 1
#       HG : 2
# ----- HF : 3
#       HE : 4
# ----- HD : 5
#       HC : 6
# ----- B  : 7
#       A  : 8
# ----- G  : 9
#       F  : 10
# ----- E  : 11
#       D  : 12
#  ---  C  : 13
#       LB : 14
#  ---  LA : 15
#       LG : 16
#  ---  LF : 17
#       LE : 18
#  ---  LD : 19
#       LC : 20
#chars are:
# 0 | 1 | 2 | 3 | 4
#
# 0,4:
#    if r%2:
#      if 2<r<12: '-'
#      else ' '
#    else: ' '
# 1: ' -b#|'
#    if r==n:
#      if A: c
#      else: ' -'[r%2]
#    elif n<8 and n<r<n+4: '|'
#    else: ' -'[r%2]
# 2: ' -o'
#    if r==n: 'o'
#    else: ' -'[r%2]
# 3: ' -|'
#    if n>7 and n-4<r<n: '|'
#    else: ' -'[r%2]


답변

자바 – 921 907 863 자

각 문자열을 배열에 저장하여 각 문자열을 별도로 작성합니다. 그런 다음 배열을 반복하고 각 줄을 인쇄하십시오.

public class D{public static void main(String[]a){char[]z=a[0].toCharArray();char[]y=new char[3];y[0]=('H'==z[0]||'L'==z[0])?z[0]:'N';int o=(y[0]=='N')?0:1;y[1]=z[o++];y[2]=z.length>o?z[o]:'!';int n=y[1]<'C'?((int)(y[1]-'A'))+6:((int)(y[1]-'C'))+1;n=(y[0]=='N')?n+7:(y[0]=='H'?n+14:n);String s="     ";String b=" --- ";String[]u=new String[22];for(int i=1;i<=21;i+=2){u[i]=s;}for(int i=10;i<=18;i+=2){u[i]="-----";}u[20]=n>19?b:s;u[2]=n<3?b:s;u[4]=n<5?b:s;u[6]=n<7?b:s;u[8]=n<9?b:s;char c=u[n].charAt(0);char e=u[n].charAt(1);char[]h=new char[]{c,y[2]=='!'?e:y[2],'O',e,c};u[n]=new String(h);for(int i=0;i<22;i++){if(n<14&&i-n<4&&i>n)u[i]=u[i]!=null?u[i].substring(0,3)+"|"+u[i].charAt(4):s;else if(n>13&&n-i<4&&n>i)u[i]=u[i]!=null?u[i].substring(0,3)+"|"+u[i].charAt(4):s;}for(int i=21;i>=0;i--)if(!(i>n&&i>18||i<n&&i<10))System.u.println((u[i]==null)?s:u[i]);}}

오 제발 날 미워 하지마, 처음이야 나는 어떤 faq / introduction도 찾을 수 없어서 제 포스팅 형식이 좋기를 바랍니다. 사람들이 문자 수에 대해 얼마나 심각한 지 잘 모르겠습니다. 정상적인 버전의 코드-추가는 줄 바꿈 / 공백 (1313 자)입니다.

public class DisplayNote
{
  public static void main(String[] args)
  {
    char[] z=args[0].toCharArray();
    char[] y=new char[3];
    y[0]=('H'==z[0]||'L'==z[0])?z[0]:'N';
    int o=(y[0]=='N')?0:1;
    y[1]=z[o++];
    y[2]=z.length>o?z[o]:'!';

    int noteValue=y[1]<'C'?((int) (y[1] - 'A')) + 6:((int) (y[1] - 'C')) + 1;
    noteValue=(y[0]=='N')?noteValue+7:(y[0]=='H'?noteValue+14:noteValue);
    String s="     ";
    String b=" --- ";
    String[] out=new String[22];
    for (int i=1;i<=21;i+=2){out[i]=s;}
    for (int i=10;i<=18;i+=2){out[i]="-----";}
    out[20]=noteValue>19?b:s;
    out[2]=noteValue<3?b:s;
    out[4]=noteValue<5?b:s;
    out[6]=noteValue<7?b:s;
    out[8]=noteValue<9?b:s;

    char c=out[noteValue].charAt(0);
    char e=out[noteValue].charAt(1);
    char[] h=new char[]{c,y[2]=='!'?e:y[2],'O',e,c};
    out[noteValue]=new String(h);
    for (int i=0;i<22;i++)
    {
      if (noteValue<14&&i-noteValue<4&&i>noteValue)
        out[i]=out[i]!=null?out[i].substring(0,3)+"|"+out[i].charAt(4):s;
      else if (noteValue>13&&noteValue-i<4&&noteValue>i)
        out[i]=out[i]!=null?out[i].substring(0,3)+"|"+out[i].charAt(4):s;
    }

    for (int i=21;i>=0;i--)
      if (!(i>noteValue&&i>18||i<noteValue&&i<10))
        System.out.println((out[i]==null)?s:out[i]);
  }
}


답변

하스켈 377C

import Data.Char
(<.)=elem
n(c:r)|elem c"HL"=let(s,a)=n r in(s+case c of 'H'->7;_-> -7,a)|1<2=(mod(ord c-67)7-2,case r of[]->' ';[x]->x)
r(s,a)y x=c where d|s>4= -1|1<2=1;c|x<.[0,4]&&(y<0||y>8)=' '|x==2&&y==s='o'|y==s&&x==1&&' '/=a=a|x==2+d&&y<.[s+k*d|k<-[1..3]]='|'|1<2="- "!!mod y 2
g p@(s,a)=unlines$[map(r p y)[0..4]|y<-reverse[min 0 s..max 8 s]]
main=getLine>>=putStr.g.n

Ungolfed 버전 :

import Data.Char

fromName ('H':s) = let (step, alter) = fromName s in ((step + 7), alter)
fromName ('L':s) = let (step, alter) = fromName s in ((step - 7), alter)
fromName (x:s) = (mod (ord x - 67) 7 - 2, if null s then ' ' else head s)

renderChar :: (Int, Char) -> Int -> Int -> Char
renderChar (step, alter) y x = let
    dir = if step >  4 then -1 else 1
    normal = "- "!!mod y 2
    stemYs = [step + k * dir | k <- [1..3]]
    c | elem x [0,4] && not(elem y [0,2,4,6,8]) = ' '
      | x == 2 && y == step = 'o'
      | y == step && x == 1 && alter /= ' ' = alter
      | elem y stemYs && x == 2 + dir = '|'
      | otherwise = normal
  in c

render :: (Int, Char)-> String
render (step, alter) = unlines [map (renderChar (step, alter) y) [0..4] | y <- ys]
  where
    ys = reverse [min 0 step .. max 8 step]

main = getLine >>= (putStr.render.fromName)