악보 ASCII 아트 생성기


31

참고 : Anders Kaseorg는 이것이 이전다른 질문 과 중복 될 수 있다고 경고합니다 . 그렇게 보입니다.이 질문을 게시하기 전에 해당 질문을 찾지 못했습니다. 그럼에도 불구하고, 그 질문은 단 하나의 답변을 받았으며, 여러분 모두가 이번에 시도하고 싶을 경우를 대비하여이 질문은 더 간단합니다. 그러나이 질문이 중복으로 표시되면 이해할 것입니다.

도전

다음과 같은 입력이 주어집니다.

8g 8Df 4cs 2C 1A

다음과 같이 출력을 생성하는 가장 짧은 프로그램 / 기능을 작성하십시오.

    /\                                         -o-
   | |
---|-|---------------------------------------------------|-|
   |/                                                    | |
---/|--------|\----b-*-----------------------------------|-|
  / |        | |    |                  o                 | |
-|--|--------|------|-----------------|------------------|-|
 | (| \      |      | |               |                  | |
-|--|--)----*-------|/---------|------|------------------|-|
  \ | /                        |      |                  | |
-----|-------------------------|-------------------------|-|
     |                         |
   *_/                      #-*-

규칙

출력은 위에 표시된대로 정확하게 G- 음자리표 그리기로 시작하여 직원 왼쪽에 정렬되고 직원 시작 후 단일 열을 남겨 두는 5 줄 직원으로 구성되어야합니다.

    /\  
   | |
---|-|--
   |/   
---/|---
  / |   
-|--|---
 | (| \ 
-|--|--)
  \ | / 
-----|--
     |  
   *_/
^
Single column

노트는 유형에 따라 a *또는 o문자로 시작해야합니다 .

문자 *또는 o문자 마다 정확히 8 개의 열이 있어야합니다 .

    /\                                         -o-
   | |
---|-|---------------------------------------------------|-|
   |/                                                    | |
---/|--------|\----b-*-----------------------------------|-|
  / |        | |    |                  o                 | |
-|--|--------|------|-----------------|------------------|-|
 | (| \      |      | |               |                  | |
-|--|--)----*-------|/---------|------|------------------|-|
  \ | /                        |      |                  | |
-----|-------------------------|-------------------------|-|
     |                         |
   *_/                      #-*-
   ↑        ↑        ↑        ↑        ↑        ↑        ↑
   8 columns of separation

직원은 예에 표시된대로 종단자가 오른쪽에 정렬 된 상태로 끝나야합니다. 터미네이터의 왼쪽 막대는 마지막 메모와 8 개의 열로 분리되어야합니다.

입력은 노트를 포함하는 단일 문자열 (적어도 하나의 빈 입력은 없음)이며 공백으로 구분 된 각 문자열입니다 (모든 노트는 올바른 것으로 간주 할 수 있으므로 오류를 확인할 필요가 없습니다). 배열의 요소 당 메모가있는 문자열 배열로 입력을받을 수도 있습니다. 각 참고, 첫 문자 음표 길이 (분모 것 1A의 전체적인 음 / semibreve 로 시작을 o, 2A에 대한 분 음표 / 미님 와, 시작 o; 4A의 분 음표 / 갈고리 와, 시작 *8위한 여덟째 note / quaver 로 시작*). 두 번째 문자는 (다음 표 참조) 노트 될 것이며, 세 번째, 옵션 문자가 될 것입니다 f또는 F평면 메모 및 s또는 S날카로운 메모.

    ---    A (ledger line)
           G
--------   F
           E
--------   D
           C
--------   b
           a
--------   g
           f
--------   e
           d
    ---    c (ledger line)

분명히, 입력은 노트의 대소 문자를 존중해야하지만, f및 대소 문자의 대소 문자를 선택할 수 있습니다 s.

참고 cA두 개의 추가해야합니다 -그들은 직원을 확장해야하기 때문에, (원장 라인), 각면에 하나씩. 참고 사항 dG직원이 없지만 원장 줄은 필요하지 않습니다.

평평하거나 날카롭게 메모를 추가해야합니다 b또는 #노트의 왼쪽에서 두 위치.

줄기 (있는 경우)는 4 개의 수직 막대로 그려야합니다. 에서 노트 b와 줄기 아래쪽으로 그려야 위 노트의 왼쪽에. a아래와 아래의 메모 는 스템을 위와 메모의 오른쪽에 그려야합니다. 쿼 버는 항상 오른쪽과 같이 표시된대로 플래그를 추가해야하며, 여러 개의 행이있을 경우 빔을 낼 필요가 없습니다.

--------------------------

-----|\----b-*------------
     | |    |             
-----|------|-------------
     |      | |           
----*-------|/---------|--
    ↑↑                 |  
----||------↑↑---------|--
    ||      ||         |
    ||      ||      #-*-
    |\      |\        ↑↑
    | Stem  | Note    | Stem
    Note    Stem      Note

평소와 같이 프로그램 / 기능은 출력을 직접 그리거나 문자열, 문자열 배열, 문자 행렬 또는 기타 적절한 형식을 반환 할 수 있습니다.

유용한 링크

이것은 이므로 각 언어마다 가장 짧은 프로그램 / 기능이 이길 수 있습니다!

보너스 : 유명한 멜로디로 예제를 작성하고 모든 멜로디를 추측하도록하십시오!




... 문을 그리는 방법을 알려주기 위해 편지의 대소 문자를 사용할 수 없습니까?
Neil

1
@Neil 죄송합니다, 당신이 할 수 없습니다 두려워요. 나는 그 규칙을 따르지 않았다. 나는 "줄기는 보통 중간 이상의 노트를 가리키고 아래는이를 지적한다"고 확인했다.
Charlie

1
각 문자열을 하나의 음표로 입력하여 문자열 배열을 취할 수 있습니까?
얽히고 설킨

답변:


13

SOGL V0.12 , 178 175 174 173 172 171 바이트

l9*6«+@*@¶¹┐∑:@┌ŗ4Ο"γ;]∑«;‽ΗmzΖH+īN D‼,ΨU‛y‚_○¤└yΨšI‘7n2∆╬5;{" -o-”;l3=?Jζ2%Ƨ#bWGk+;}Jz7m««:U+;W7«κArBb3>?Ζo*ŗ}a2\?┌@ŗ}ē9*LI+a╬5b1>?4┐∙b8=?"■QD³‘┼}e9*5+a4-8a>?5+;2-;G↕№}╬5

여기 사용해보십시오! (θ는 사용 편의성을 위해 추가되었습니다. 171 바이트로 실행하려면 입력이 스택에 있어야합니다)

내가이 작품을 말할 수있는 한, 문제가 발견되면 알려주십시오.

설명:

첫 번째 부분 : 캔버스 생성

l                                get the length of that array
 9*                              multiply by 9
   6«+                           add 12
      @*                         get that many spaces
        @¶                       push a space and a newline
          ¹                      put all the strings on the stack in an array
           ┐∑                    join with vertical bars
             :                   duplicate that string (which is a line with the ending barline but no staff)
              @┌ŗ                replace spaces with dashes (to make it a line with staff)
                 4Ο              encase 4 copies of the space lines in lines with the dashes
                   "...‘         push the G-clef without newlines
                        7n       split into an array of items of length 7
                          2∆╬5   at 1-indexed coordinates [2; -1] place the G-clef in the staff lines, extending the arrays size 
                              ;  get the input split on spaces back on top of the stack

두 번째 부분 : 루프, 메모 헤드 배치

{                        loop over the input split on spaces
" -o-”                    push a template for a note head and leger lines
      ;                   get the input optop
       l3=?            }  if the length of the input is 3, then
           J                pop the last letter off from the input
            ζ               get its unicode point
             2%             modulo 2
               Ƨ#bW         get its index in "#b"
                   G        get the template ontop
                    k       remove its 1st letter
                     +      join the replaced input and the template
                      ;     get the input back ontop to be consisntent with how the if started

sidequest: parse the rest of the inputs
J                  pop the last letter off of the remaining input string (the note), leaving the note length as string on the stack below
 z                 push the lowercase alphabet
  7m               get its first 7 letters
    ««             put the first 2 at the end
      :            duplicate it
       U+          append it uppercased to the original
         ;W        get the notes letter ontop and get its 1-indexed index in that just created string
           7«κ     subtract it from 14
              A    save on variable A
               r   convert the note length to a number
                B  save on variable B

b3>?    }          if b>3 (aka if note length is either 4 or 8)
    Ζo*ŗ             replace "o" with "*"
         a2\?   }  if a divides by 2 (aka there isn't staff nor leger lines required)
             ┌@ŗ     replace "-" with " "

ē          push the value of variable E and after that increase it (default is user input number, which errors and defaults to 0)
 9*        multiply by 9
   LI+     increase by 11
      a    push variable a
       ╬5  at those positions (e*9+11, a) insert the note head template in the canvas

세 번째 부분 : 깃발과 줄기

b1>?                      if b (note length)>1 (aka if the stem is needed at all)
    4┐∙                   get an array of 4 vertical bars
       b8=?       }       if b==8 (aka if the flag is needed)
           "■QD³‘           push "\    |"
                 ┼          add verically-down-then-horizontally-right

e9*                       push e*9 (now e starts with 1 as it's been increased) (the X coordinate for the flag)
   5+                     add 5 to it
     a4-                  push a-4 (the Y coordinate, 4 less than the note head as arrays get inserted from the top-left corner)
        8a>?         }    if 8>a (aka if the flag needs to be rotated)
            5+              add 5 to the Y coordinate
              ;2-;          subtract 2 from the X coordinate
                  G         get the stem&flag or stem ontop
                   ↕№       reverse it vertically and mirror characters
                      ╬5  insert the array of the stem and maybe flag at those coordinates

코드는 거의 완벽합니다. 유일한 nitpick은 2bs귀하의 예제에서 줄기가 아래쪽을 향해야한다는 점 입니다.
Charlie

@CarlosAlejo 고정
dzaima

큰! 그리고 설명 주셔서 감사합니다!
Charlie

10

자바 스크립트 (ES6), 616 527 바이트

거의 90 바이트를 제거해 주셔서 감사합니다 @shaggy

나는 메모에 대해 전혀 몰랐다 ... 지금까지, 나는 그것이 올바르게 되었기를 바란다.

f=i=>i.map((v,p)=>(k[e=(w=q+12)*(l="AGFEDCbagfedc".search(v[1]))+p*9+12]="o*"[(s=v[0])>3|0],l<1|l>11&&(k[e-1]=k[e+1]="-"),(t=v[2])&&(k[e-2]="b#"[t>"f"|0]),--s&&[1,2,3,4].map(i=>(k[(b=l<8)?e+w*i-1:e-w*i+1]="|",s>6&&( b?k[e+w*4]="/":k[e-w*4+2]="\\",k[b?e+w*3+1:e-w*3+3]='|')))),k=[...`    /\\  ${s=" ".repeat(q=i.length*9)}  
   | |  ${s}    
---|-|--${l="-".repeat(q)+"|-|"}
   |/   ${t=s+"| |"}
---/|---${l}
  / |   ${t}
-|--|---${l}
 | (| \\ ${t}
-|--|--)${l}
  \\ | / ${t}
-----|--${l}
     |  ${s}   
   *_/  ${s}`])&&k.join``

console.log(f(["8g","8Df","4cs","2C","1A"]))
.as-console-wrapper { max-height: 100% !important; top: 0 }
.as-console-row:after { display: none !important; }

설명

f=i=>i.map((v,p)=>( // for each note

  k[e=(w=q+12)*(l="AGFEDCbagfedc".search(v[1]))+p*9+12]= // position in 1D array to set the note to
  "o*"[(s=v[0])>3|0], // note value (either o or *)

  l<1|l>11&&(k[e-1]=k[e+1]="-"), // add leger line

  (t=v[2])&&(k[e-2]="b#"[t>"f"|0]), // add sharp or flat

  --s&&[1,2,3,4].map(i=> // add the 4 stem lines
                     (k[(b=l<8)?e+w*i-1:e-w*i+1]="|", // durration over eigth note => add stem

                      s>6&&( // if to add a flag
                        b?k[e+w*4]="/":k[e-w*4+2]="\\", // add flag either on left or the right side

                        k[b?e+w*3+1:e-w*3+3]='|') // add the line after the flag
                     )
                    )
),
// template, extended to the final length with lines
k=[...`    /\\  ${s=" ".repeat(q=i.length*9)}  
   | |  ${s}   
---|-|--${l="-".repeat(q)+"|-|"}
   |/   ${t=s+"| |"}
---/|---${l}
  / |   ${t}
-|--|---${l}
 | (| \\ ${t}
-|--|--)${l}
  \\ | / ${t}
-----|--${l}
     |  ${s}   
   *_/  ${s}`])&&k.join``

내가 생각하는 당신은 저장하여 몇 바이트를 저장할 수 있습니다 t[0]t[2]다음 바로 할q=t.length*9
스티븐

2
PPCG에 오신 것을 환영합니다. 아주 좋은 첫 번째 대답 :) 그래도 할 수있는 더 좋은 골프가 있습니다. 나는 빠른 패스를 가져 와서 520 바이트 로 줄 였으므로 좋은 시작을해야합니다.
얽히고 설킨

분명히 + atob / btoa를 바꾸면 약간의 바이트가 절약 될 것입니다.
Downgoat

1
@Shaggy 매우 감사합니다. 배울 것이 많다.
아크 호

천만에요 공간을 확보 한 후 s>6&&(바이트를 절약 할 수 있습니다. 또한 대체하여있는 다른 바이트를 저장할 수 (w=q+12)w, repeat(q=i.length*9)repeat(w=i.length*9)repeat(q)함께 repeat(w,w+=12).
얽히고 설킨

9

, 180 171 168 163 바이트

F⁵⁺⸿⸿×-⁺²⁷×⁸№θ ↑⁹←↙↓⁹J⁴¦⁹↑⁶↗¹↑²↖¹↓↙¹↓³↙²↓³ \M²↑(| ↘¹↙)↙¹↓²↙¹↑←_*F⪪θ «A⌕AGFEDCbagfedc§ι¹λJχλA⁺⁹χχ¿⁼³Lι§b#⁼§ι²s→P׳¬﹪λ²→P§o*›ι4¿›ι2¿›λ⁶«↗↑⁴¿›ι8«↘↘¹↓¹»»«↙↓⁴¿›ι8«↗↗¹↑¹

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명:

F⁵⁺⸿⸿×-⁺²⁷×⁸№θ ↑⁹←↙↓⁹

구멍을 인쇄합니다.

J⁴¦⁹↑⁶↗¹↑²↖¹↓↙¹↓³↙²↓³ \M²↑(| ↘¹↙)↙¹↓²↙¹↑←_*

음자리표를 인쇄하십시오.

F⪪θ «

각 음을 반복합니다.

A⌕AGFEDCbagfedc§ι¹λ

메모의 Y 좌표를 찾으십시오.

JχλA⁺⁹χχ

이것은 실제로 교활합니다. χ10으로 미리 정의 된 변수입니다. 첫 번째 음표의 우연한 X 좌표 인 경우 10입니다. 해당 위치로 점프 한 후 9가 추가되어 다음 음 위치를 나타냅니다.

¿⁼³Lι§b#⁼§ι²s→

실수로 인쇄하십시오 (있는 경우).

P׳¬﹪λ²→P§o*›ι4

필요한 경우 원장 라인을 인쇄하고 메모하십시오. 실제로 선에 인쇄해도 효과는 없지만 y 좌표에 선이 인쇄됩니다.

¿›ι2

세미 브레이브에는 더 이상 할 일이 없습니다.

¿›λ⁶«

중간 지점 아래의 메모의 경우

↗↑⁴

줄기를 위로 당겨

¿›ι8«↘↘¹↓¹

그리고 떨림을위한 깃발.

»»«

중간 점 이상의 노트의 경우

↙↓⁴

줄기를 아래쪽으로 당기고

¿›ι8«↗↗¹↑¹

그리고 떨림을위한 깃발.


당신은 SOGL을 이겼습니다! :-)
찰리

@CarlosAlejo 나는 그것이 일어날 것으로 예상했다. 그러나 나는 그것이 20 %만큼 나를 이길 것으로 기대했습니다.
dzaima

@dzaima 아마도 순수한 ASCII 기술 도전이라면 어쩌면 이것도 출력에 입력에 의존하는 논리 부분이 있습니다. 그럼에도 불구하고 나는 여전히 각 언어가 더 잘할 수있는 것에 익숙해지고있다.
Charlie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.