Notalar ASCII-sanat üreteci


31

Not : Anders Kaseorg, bunun bir önceki sorunun başka bir kopyası olabileceği konusunda beni uyardı . Öyle görünüyor ve özür dilerim bu soruyu göndermeden önce bu soruyu bulamadım. Bununla birlikte, bu soru yalnızca bir cevap aldı ve bu sefer daha kolay, sadece bu sefer denemek istemeniz durumunda. Yine de, bu sorunun kopya olarak işaretlenip bitmediğini anlayacağım.

Meydan okuma

Bunun gibi bir girdi verilir:

8g 8Df 4cs 2C 1A

Bunun gibi bir çıktı üreten en kısa programı / işlevi yazın:

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

kurallar

Çıktı, tam olarak yukarıda gösterildiği gibi bir G-nota anahtarı çekilmesi ile başlayan, personelin soluna hizalı ve personelin başlamasından sonra tek bir sütun bırakan beş hatlı bir personelden oluşmalıdır.

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

Notlar , türüne bağlı olarak bir *veya bir okarakterle başlamalıdır .

Her *veya bir okarakterden tam olarak sekiz tane ayırma sütunu olmalıdır :

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

Personel, örnekte gösterildiği gibi sağa hizalanmış sonlandırıcıyla bitmelidir. Sonlandırıcının sol çubuğu, son notadan 8 sütun ayrılmalıdır.

Giriş, her biri bir boşlukla ayrılmış (her notun uygun olacağını düşünebilirsiniz, bu nedenle hataları kontrol etmeniz gerekmez) olan, notları içeren (en az bir, boş giriş yok) tek bir dize olacaktır. Girdiyi, dizideki öğe başına bir not ile birlikte bir dize dizisi olarak da alabilirsiniz. Her bir not için ilk karakter not uzunluğunun (payda olacak 1bir için bütün not / semibreve ile başlar o; 2bir için yarım notu / minim ile başlar o; 4bir için çeyrek notu / crotchet ile başlar *ve 8bir için sekizinci not / quaver , ile başlar*). İkinci karakter not olacaktır (bir sonraki tabloya bakınız) ve üçüncü, isteğe bağlı karakter fveya Fdüz notlar ve / sveya Skeskin notlar için olacaktır.

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

Açıkçası, girdi notlar için duruma saygı göstermelidir, ancak fve sdeğiştiricilerin durumunu seçebilirsiniz .

Notlar cve personeli genişletmeleri gerektiğinden her iki tarafta birer tane olmak üzere Aiki -(satır defteri) eklemek gerekir. Notlar dve Gpersonel dışındadır ancak defter hatlarına ihtiyaç duymazlar.

Yassılaştırılmış veya keskinleştirilmiş notlar notun sol tarafına bveya #iki konum eklemelidir .

Saplar (varsa) 4 dikey çubukla çizilmelidir. bYukarıdan ve yukarıdan gelen notlar , gövdeyi aşağıya ve notun sol tarafına çekmelidir. Alt ave alt notalarda kök yukarı ve notun sağ tarafına çekilmelidir. Quavers bayrağı her zaman sağa ve aynen gösterildiği gibi eklemelidir ve üst üste birkaç tane varsa, ışınlanmasına gerek yoktur.

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

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

Her zaman olduğu gibi, programınız / işleviniz çıktıyı doğrudan çizebilir veya bir dize, dizi dizisi, karakter matrisi veya başka bir makul formatta dönebilir.

Kullanışlı bağlantılar

Bu , yani her dil için en kısa program / işlev kazanabilir!

Bonus: ünlü melodilerle örnekler yazmaya çalışın ve herkesin hangi melodi olduğunu tahmin etmesine izin verin!




... mektubun kasasını hangi yolu çizeceğimizi söylemek için kullanamayız mı?
Neil

1
Ne yazık ki, yapamayacağınıza korkuyorum. Bu kuralı ben yapmadım, şunu kontrol ettim : "Gövde genellikle orta veya daha üstteki notlar için aşağıya, aşağıdakleri için yukarı çeker".
Charlie

1
Girdi olarak her dize tek bir not olacak şekilde bir dizi dizi alabilir miyiz?
Shaggy

Yanıtlar:


13

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

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

Burada dene! (θ kullanım kolaylığı için eklendi; 171 bayt olarak çalıştırmak için girişin yığında olmasını bekler)

Bunu söyleyebildiğim kadarıyla, ancak herhangi bir sorun bulursanız, bana söyleyin.

Açıklama:

ilk bölüm: tuval oluşturma

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

ikinci bölüm: loop, nota yerleştirme

{                        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

üçüncü bölüm: bayraklar ve saplar

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

Kodunuz neredeyse mükemmel. Tek nitpick, 2bsörneğinizdeki notanın sapı aşağıya dönük olması gerektiğidir.
Charlie

@CarlosAlejo sabit
dzaima

Harika! Ve açıklama için teşekkürler!
Charlie,

10

JavaScript (ES6), 616 527 bayt

Teşekkürler Neredeyse 90 byte'ı çıkardığınız için @ shaggy

Notlar hakkında hiçbir fikrim yoktu ... şimdiye kadar, umarım doğru anlamışımdır.

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

açıklama

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``

Ben düşünüyorum Eğer kaydederek bazı bayt kaydedebilir t[0]ve t[2]ve ardından sadece yapmakq=t.length*9
Stephen

2
PPCG'ye Hoşgeldiniz. Çok güzel ilk cevap :) Ancak, yapılabilir daha iyi bir golf var. Hızlı bir şekilde geçtim ve 520 byte'a indirdim , bu da size iyi bir başlangıç ​​yapmalı.
Shaggy

Şüphesiz bazıları yerine + atob / btoa biraz bayt kazandırır
Downgoat

1
@Shaggy çok teşekkür ederim. Öğrenecek çok şeyim var.
yaylar

Bir şey değil :) Sonra s>6&&(bir bayt kazandırabilir başıboş bir boşluk var . Ayrıca değiştirerek başka byte kaydedebilirsiniz (w=q+12)ile w, repeat(q=i.length*9)birlikte repeat(w=i.length*9)ve repeat(q)birlikte repeat(w,w+=12).
Shaggy

9

Kömür , 180 171 168 163 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

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

Çıtayı yazdır.

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

Nota anahtarı yazdırın.

F⪪θ «

Her nota dolaşın.

A⌕AGFEDCbagfedc§ι¹λ

Notun Y koordinatını bulun.

JχλA⁺⁹χχ

Bu gerçekten sinsidir: χ10'a önceden tanımlanmış bir değişkendir, eğer varsa, ilk notun kazara X tam koordinatıdır. Bu pozisyona atladıktan sonra, bir sonraki not pozisyonunu temsil eden 9 buna eklenir.

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

Varsa, kazayla yazdırın.

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

Gerekirse defter çizgileri ve notu yazdırın. Aslında çizgi, herhangi bir y koordinatına basılsa da, çizginin üzerine yazdırılmasının elbette bir etkisi yoktur.

¿›ι2

Yarı römorklar için yapacak daha fazla bir şey yok.

¿›λ⁶«

Orta noktanın altındaki notlar için,

↗↑⁴

kök yukarı doğru çekmek,

¿›ι8«↘↘¹↓¹

ve tutacağı için bayrak.

»»«

Orta noktanın üzerindeki notlar için,

↙↓⁴

kök aşağı doğru çekmek,

¿›ι8«↗↗¹↑¹

ve tutacağı için bayrak.


SOGL'u yendin! :-)
Charlie,

@CarlosAlejo Olmasını bekledim. Ama aynı zamanda beni% 20 oranında yenmesini bekliyordum.
dzaima

@ dzaima belki de saf bir ASCII-art mücadelesiydi, ama bu da çıktının girdiye bağlı olmasını sağlayan bir mantık parçasına sahip. Bununla birlikte, hala her dilin daha iyi yapabileceği şeylere alışmaya başladım.
Charlie,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.