Máy phát nhạc ASCII-art


31

Lưu ý : Anders Kaseorg cảnh báo tôi rằng đây có thể là một bản sao của một câu hỏi khác trước đó . Có vẻ như vậy, và tôi xin lỗi tôi đã không tìm thấy câu hỏi đó trước khi đăng câu hỏi này. Tuy nhiên, câu hỏi đó chỉ nhận được một câu trả lời và câu hỏi này đơn giản hơn, chỉ trong trường hợp tất cả các bạn muốn thử lần này. Tôi sẽ hiểu nếu câu hỏi này cuối cùng được đánh dấu là trùng lặp.

Các thách thức

Đưa ra một đầu vào như thế này:

8g 8Df 4cs 2C 1A

Viết chương trình / hàm ngắn nhất tạo ra đầu ra như thế này:

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

Quy tắc

Đầu ra phải bao gồm một nhân viên năm dòng bắt đầu bằng bản vẽ G-clef chính xác như được hiển thị ở trên, căn chỉnh bên trái của nhân viên và để lại một cột duy nhất sau khi bắt đầu nhân viên.

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

Các ghi chú phải bắt đầu bằng một *hoặc một oký tự tùy thuộc vào loại của nó.

Phải có chính xác tám cột tách mỗi *hoặc một oký tự:

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

Các nhân viên phải kết thúc với dấu kết thúc được căn bên phải như trong ví dụ. Thanh bên trái của dấu kết thúc phải được tách 8 cột khỏi ghi chú cuối cùng.

Đầu vào sẽ là một chuỗi chứa các ghi chú (ít nhất là một, không có đầu vào trống), mỗi chuỗi được phân tách bằng khoảng trắng (bạn có thể coi mỗi ghi chú sẽ là một ghi chú thích hợp, do đó không cần kiểm tra lỗi). Bạn cũng có thể lấy đầu vào là một chuỗi các chuỗi, với một ghi chú cho mỗi phần tử trong mảng. Đối với từng nốt nhạc, ký tự đầu tiên sẽ là mẫu số của độ dài lưu ý ( 1cho một nốt tròn / semibreve , bắt đầu với o; 2cho một nửa lưu ý / nốt trắng , bắt đầu với o; 4cho một nốt đen / ý ngông , bắt đầu với *, và 8cho một thứ tám ghi chú / quaver , bắt đầu với*). Ký tự thứ hai sẽ là ghi chú (xem bảng tiếp theo) và ký tự thứ ba, tùy chọn sẽ là fhoặc Fcho ghi chú phẳng và shoặc Scho ghi chú sắc nét.

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

Rõ ràng, đầu vào phải tôn trọng trường hợp cho các ghi chú, nhưng bạn có thể chọn trường hợp của fssửa đổi.

Ghi chú cAphải thêm hai -(dòng sổ cái), một ở mỗi bên, vì chúng phải mở rộng nhân viên. Ghi chú dGnằm ngoài đội ngũ nhân viên nhưng không cần dòng sổ cái.

Làm phẳng hoặc làm sắc nét các ghi chú phải thêm bhoặc #hai vị trí ở bên trái của ghi chú.

Các thân cây (nếu có) phải được vẽ bằng 4 thanh dọc. Ghi chú từ bvà trên phải vẽ thân cây xuống và ở bên trái của ghi chú. Ghi chú từ avà bên dưới phải vẽ thân cây lên trên và ở bên phải của ghi chú. Quavers phải thêm cờ, luôn luôn đúng và chính xác như được hiển thị, và không cần phải chiếu nếu có một vài trong số chúng liên tiếp.

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

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

Như thường lệ, chương trình / hàm của bạn có thể trực tiếp vẽ đầu ra hoặc trả về một chuỗi, mảng chuỗi, ma trận ký tự hoặc bất kỳ định dạng hợp lý nào khác.

Liên kết hữu ích

Đây là , vì vậy có thể chương trình / chức năng ngắn nhất cho mỗi ngôn ngữ sẽ giành chiến thắng!

Phần thưởng: hãy thử viết ví dụ với những giai điệu nổi tiếng và để mọi người thử đoán xem đó là giai điệu nào!




... vì vậy chúng ta thậm chí không thể sử dụng trường hợp của bức thư để cho biết cách vẽ thân cây?
Neil

1
@ Xin lỗi, tôi sợ bạn không thể. Tôi đã không tạo ra quy tắc đó, tôi đã kiểm tra rằng : "các thân cây thường chỉ xuống cho các ghi chú ở dòng giữa hoặc cao hơn, và cho các ghi chú bên dưới".
Charlie

1
Chúng ta có thể lấy một mảng các chuỗi, với mỗi chuỗi là một ghi chú, làm đầu vào không?
Xù xì

Câu trả lời:


13

SOGL V0.12 , 178 175 174 173 172 171 byte

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

Hãy thử nó ở đây! (θ được thêm vào để dễ sử dụng; Để chạy ở mức 171 byte, nó hy vọng đầu vào sẽ nằm trên ngăn xếp)

Theo như tôi có thể nói điều này hoạt động, nhưng nếu bạn tìm thấy bất kỳ vấn đề, hãy nói với tôi.

Giải trình:

phần đầu tiên: tạo vải

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

phần thứ hai: vòng lặp, vị trí đầu ghi chú

{                        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

phần thứ ba: cờ và thân

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

Mã của bạn gần như hoàn hảo. Các nitpick duy nhất là lưu ý 2bstrong ví dụ của bạn phải có thân hướng xuống dưới.
Charlie

@CarlosAlejo đã sửa
dzaima

Tuyệt quá! Và cảm ơn đã giải thích!
Charlie

10

JavaScript (ES6), 616 527 byte

Cảm ơn @shaggy đã xóa gần 90 byte

Tôi không có ý tưởng về ghi chú ... cho đến bây giờ, hy vọng tôi đã hiểu đúng.

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; }

giải trình

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ôi nghĩ rằng bạn có thể tiết kiệm một số byte bằng cách tiết kiệm t[0]t[2], và sau đó chỉ cần làmq=t.length*9
Stephen

2
Chào mừng đến với PPCG. Câu trả lời đầu tiên rất hay :) Mặc dù vậy, có một chút tốt hơn có thể được thực hiện. Tôi đã nhanh chóng vượt qua nếu và giảm xuống còn 520 byte , điều này sẽ cho bạn một khởi đầu tốt.
Xù xì

Chắc chắn một số thay thế + atob / btoa sẽ tiết kiệm được một số byte
Downgoat

1
@Shaggy cảm ơn bạn rất nhiều. Tôi có rất nhiều điều để học hỏi.
vòng cung

Bạn được chào đón :) Bạn có một không gian đi lạc sau s>6&&(đó có thể giúp bạn tiết kiệm một byte. Bạn cũng có thể lưu một byte khác bằng cách thay thế (w=q+12)bằng w, repeat(q=i.length*9)bằng repeat(w=i.length*9)repeat(q)bằng repeat(w,w+=12).
Shaggy

9

Than , 180 171 168 163 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

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

In stave.

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

In khóa sổ.

F⪪θ «

Lặp lại qua từng ghi chú.

A⌕AGFEDCbagfedc§ι¹λ

Tìm tọa độ Y của ghi chú.

JχλA⁺⁹χχ

Điều này thực sự lén lút: χlà một biến được xác định trước là 10, chính xác là tọa độ X của ghi chú đầu tiên, nếu nó có một biến. Sau khi nhảy đến vị trí đó, 9 được thêm vào vị trí đó, đại diện cho vị trí ghi chú tiếp theo.

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

In tình cờ, nếu có.

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

In các dòng sổ cái nếu cần thiết và ghi chú. Trong thực tế, dòng được in trên bất kỳ tọa độ thậm chí y mặc dù in nó trên stave không có tác dụng tất nhiên.

¿›ι2

Không có gì hơn để làm cho semibreves.

¿›λ⁶«

Đối với ghi chú dưới điểm giữa,

↗↑⁴

vẽ thân cây lên trên,

¿›ι8«↘↘¹↓¹

và cờ cho người qua đường.

»»«

Đối với ghi chú trên điểm giữa,

↙↓⁴

vẽ thân cây xuống dưới,

¿›ι8«↗↗¹↑¹

và cờ cho người qua đường.


Bạn đánh bại SOGL! :-)
Charlie

@CarlosAlejo Tôi dự đoán nó sẽ xảy ra. Nhưng tôi đã mong nó sẽ đánh bại tôi khoảng 20%.
dzaima

@dzaima có thể nếu đó là một thử thách nghệ thuật ASCII thuần túy, nhưng phần này cũng có một phần logic làm cho đầu ra phụ thuộc vào đầu vào. Tuy nhiên, tôi vẫn đang làm quen với những gì mỗi ngôn ngữ có thể làm tốt hơn.
Charlie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.