แผ่นเพลงเครื่องกำเนิดไฟฟ้า ASCII-art


31

หมายเหตุ : Anders Kaseorg เตือนฉันว่านี่อาจเป็นปัญหาซ้ำซ้อนของคำถามก่อนหน้านี้อีกคำถามหนึ่ง ดูเหมือนจะเป็นเช่นนั้นและฉันขอโทษที่ฉันไม่พบคำถามนั้นก่อนโพสต์คำถามนี้ อย่างไรก็ตามคำถามนั้นได้รับคำตอบเพียงคำตอบเดียวและคำถามนี้ง่ายกว่าในกรณีที่คุณต้องการลองครั้งนี้ ฉันจะเข้าใจว่าคำถามนี้ท้ายถูกทำเครื่องหมายว่าซ้ำกัน

ความท้าทาย

รับอินพุตเช่นนี้:

8g 8Df 4cs 2C 1A

เขียนโปรแกรม / ฟังก์ชั่นที่สั้นที่สุดที่สร้างเอาต์พุตเช่นนี้:

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

กฎระเบียบ

ผลลัพธ์จะต้องประกอบด้วยพนักงานห้าบรรทัดที่เริ่มต้นด้วยการวาด G-clef ตามที่แสดงด้านบนชิดกับด้านซ้ายของพนักงานและออกจากคอลัมน์เดียวหลังจากเริ่มต้นของพนักงาน

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

บันทึกจะต้องเริ่มต้นด้วย*หรือoตัวอักษรขึ้นอยู่กับประเภทของมัน

ต้องมีตรงแปดคอลัมน์ของการแยกทุก*หรือoตัวอักษร:

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

เจ้าหน้าที่จะต้องจบด้วยเทอร์มินัลที่จัดชิดด้านขวาตามที่แสดงในตัวอย่าง แถบด้านซ้ายของเทอร์มิเนเตอร์ต้องแยก 8 คอลัมน์ออกจากบันทึกย่อล่าสุด

อินพุตจะเป็นสตริงเดี่ยวที่มีบันทึกย่อ (อย่างน้อยหนึ่งไม่มีอินพุตว่าง) แต่ละอันคั่นด้วยช่องว่าง (คุณสามารถพิจารณาว่าโน้ตทุกโน้ตจะเป็นสตริงที่เหมาะสมดังนั้นจึงไม่จำเป็นต้องตรวจสอบข้อผิดพลาด) คุณยังสามารถรับอินพุตเป็นอาร์เรย์ของสตริงโดยมีหมายเหตุต่อองค์ประกอบในอาร์เรย์ สำหรับแต่ละโน้ตตัวอักษรตัวแรกจะเป็นส่วนของความยาวโน้ต (คน1สำหรับโน้ตทั้ง / จังหวะเต็มในดนตร , เริ่มต้นด้วยo; 2สำหรับครึ่งโน้ต / ขีดต่ำที่สุด , เริ่มต้นด้วยo; 4สำหรับโน้ต / ตะขอ , เริ่มต้นด้วย*และ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ปรับเปลี่ยน

หมายเหตุcและAจะต้องเพิ่มสอง-(บรรทัดบัญชีแยกประเภท) หนึ่งในแต่ละด้านตามที่พวกเขาจะต้องขยายพนักงาน หมายเหตุdและGอยู่นอกพนักงาน แต่ไม่จำเป็นต้องมีบัญชีแยกประเภท

ธนบัตรที่แบนราบหรือแหลมขึ้นจะต้องเพิ่มbหรือ#วางสองตำแหน่งที่ด้านซ้ายของธนบัตร

ลำต้น (ถ้ามี) จะต้องวาดด้วยแถบแนวตั้ง 4 แถบ โน้ตจากbและสูงกว่าต้องดึงก้านลงและที่ด้านซ้ายของโน้ต โน้ตจากaและด้านล่างจะต้องดึงก้านขึ้นและที่ด้านขวาของโน้ต เควสจะต้องเพิ่มธงเสมอไปทางขวาและตรงตามที่แสดงและไม่จำเป็นต้องมีการยกไฟหากมีหลายคนในแถว

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

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

ตามปกติโปรแกรม / ฟังก์ชั่นของคุณสามารถดึงเอาท์พุทโดยตรงหรือคืนค่าสตริงอาร์เรย์ของสตริงเมทริกซ์ของตัวอักษรหรือรูปแบบที่เหมาะสมอื่น ๆ

ลิงค์ที่มีประโยชน์

  • รายการของสัญลักษณ์ทางดนตรี
  • โน้ตตัวอักษร

นี่คือดังนั้นโปรแกรม / ฟังก์ชั่นที่สั้นที่สุดสำหรับแต่ละภาษาจะชนะ!

โบนัส: ลองเขียนตัวอย่างที่มีท่วงทำนองที่โด่งดังและให้ทุกคนลองเดาว่ามันคือทำนองใด!


Sandbox
Charlie


... ดังนั้นเราจึงไม่สามารถใช้กรณีของจดหมายเพื่อบอกวิธีการดึงก้าน?
Neil

1
@ Neil ขอโทษฉันเกรงว่าคุณทำไม่ได้ ฉันไม่ได้ทำตามกฎนั้นฉันตรวจสอบแล้วว่า : "ลำต้นมักชี้ไปที่โน้ตบนเส้นกลางหรือสูงกว่าและเพิ่มขึ้นสำหรับสิ่งที่อยู่ด้านล่าง"
Charlie

1
เราสามารถนำอาเรย์ของสตริงแต่ละสตริงมาเป็นโน้ตเดี่ยวได้หรือไม่?
Shaggy

คำตอบ:


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

ลองที่นี่! (เพิ่ม for เพื่อความสะดวกในการใช้งานโดยเรียกใช้เป็น 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

JavaScript (ES6), 616 527 ไบต์

ขอบคุณ@shaggyสำหรับการลบเกือบ 90 ไบต์

ฉันไม่รู้เกี่ยวกับบันทึกย่อ ... จนถึงตอนนี้หวังว่าฉันเข้าใจถูก

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 bytesซึ่งควรให้คุณเริ่มต้นที่ดี
Shaggy

แน่นอนว่าการแทนที่ + 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)
Shaggy

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 ของอุบัติเหตุครั้งแรกของบันทึกย่อหากมี หลังจากกระโดดไปที่ตำแหน่งนั้นแล้ว 9 จะถูกเพิ่มเข้าไปแทนตำแหน่งโน้ตถัดไป

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

พิมพ์โดยไม่ตั้งใจถ้ามี

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

พิมพ์บรรทัดบัญชีแยกประเภทหากจำเป็นและบันทึก ในความเป็นจริงเส้นจะถูกพิมพ์บนพิกัด y ใด ๆ แม้ว่าการพิมพ์บน stave จะไม่มีผลแน่นอน

¿›ι2

ไม่มีอะไรให้ทำเพื่อ semibreves

¿›λ⁶«

สำหรับโน้ตด้านล่างจุดกึ่งกลาง

↗↑⁴

ดึงก้านขึ้น

¿›ι8«↘↘¹↓¹

และธงสำหรับเควกเกอร์

»»«

สำหรับโน้ตด้านบนจุดกึ่งกลาง

↙↓⁴

ดึงก้านลง

¿›ι8«↗↗¹↑¹

และธงสำหรับเควกเกอร์


คุณเอาชนะ SOGL ได้! :-)
Charlie

@CarlosAlejo ฉันคาดว่ามันจะเกิดขึ้น แต่ฉันก็คาดหวังว่ามันจะเอาชนะฉันด้วยเช่นกัน 20%
dzaima

@dzaima บางทีถ้ามันเป็นความท้าทายศิลปะ ASCII บริสุทธิ์ แต่อันนี้ก็มีส่วนตรรกะที่ทำให้การส่งออกขึ้นอยู่กับอินพุต อย่างไรก็ตามฉันยังคงคุ้นเคยกับสิ่งที่แต่ละภาษาสามารถทำได้ดีกว่า
Charlie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.