楽譜ASCIIアートジェネレーター


31

:Anders Kaseorgは、これは別の以前の質問と重複する可能性があると警告しています。そう思われますが、この質問を投稿する前にその質問を見つけられなかったのが残念です。それにもかかわらず、その質問は1つの答えしか受け取っておらず、この質問は皆さんが今回試してみたい場合に備えて、より簡単です。ただし、この質問が重複としてマークされてしまうかどうかは理解できます。

チャレンジ

次のような入力が与えられた場合:

8g 8Df 4cs 2C 1A

次のような出力を生成する最短のプログラム/関数を作成します。

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

ルール

出力は、上記のとおり正確にG音部記号の描画で始まる5行の譜表で構成され、譜表の左側に揃えられ、譜表の開始後に単一の列が残されている必要があります。

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

ノートは、タイプに応じて*またはで始まる必要がありますo

すべて*またはo文字ごとに正確に8列の分離が必要です。

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

譜表は、例に示されているように、ターミネーターを右に揃えて終了する必要があります。ターミネーターの左のバーは、最後の音から8列離れている必要があります。

入力は、空白で区切られたノート(少なくとも1つ、空の入力なし)を含む単一の文字列になります(すべてのノートが適切なものであると見なすことができるため、エラーをチェックする必要はありません)。入力を文字列の配列として受け取ることもでき、配列の要素ごとにメモがあります。各ノートのために、最初の文字は、音符の長さ(の分母になる1ための全音符/ semibreve、との開始o; 2のために半分ノート/ミニム、との開始o; 4のために四分音符/音符で始まり*、と8のために第八note / quaverで始まります*)。2番目の文字は音符(次の表を参照)、および第三の、任意の文字であろうとなりf又はFフラット音符およびsまたはSシャープなメモ。

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

明らかに、入力では音符の大文字と小文字を区別する必要がありますがfs修飾子の。

メモcA追加し-、スタッフを延長する必要があるため、各側に1つずつ、2つ(元帳行)を追加する必要があります。メモdGスタッフはなくなりましたが、元帳行は必要ありません。

平坦化またはシャープ化されたノートは、追加bまたは#は、ノートの左側に1つ 2つの位置をます。

ステム(ある場合)は、4本の垂直バーで描画する必要があります。音符のb上と音符は、音符の左下にステムを描画する必要があります。a上下の音符は、音符の上側で音符の右側にステムを描画する必要があります。四分音符は、常に右方向に表示されているとおりにフラグを追加する必要があります。また、列に複数のフラグがある場合は、ビームする必要はありません。

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

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

通常どおり、プログラム/関数は出力を直接描画したり、文字列、文字列の配列、文字のマトリックス、またはその他の適切な形式を返すことができます。

便利なリンク

これはなので、各言語の最短のプログラム/機能が勝つかもしれません!

おまけ:有名なメロディーを使って例を書いてみて、誰もがそれがどのメロディーであるかを推測できるようにしてください!




...そのため、文字の大文字小文字を使用して、幹をどの方向に描画するかを判断することさえできませんか?
ニール

1
@ニール申し訳ありませんが、私はあなたができないことを恐れています。私はそのルールを構成していなかった、私がいることを確認し、「通常、最大下のそれらのための中央の線以上のノートのためにダウンポイント茎」:。
チャーリー

1
入力として、各文字列が単一の音符である文字列の配列を使用できますか?
シャギー

回答:


13

SOGL V0.12178の 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

2番目の部分:ループ、音符の頭の配置

{                        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

あなたのコードはほぼ完璧です。唯一の要点は2bs、例の音符が下向きのステムを持つ必要があることです。
チャーリー

@CarlosAlejo修正
dzaima

すばらしいです!そして説明をありがとう!
チャーリー

10

JavaScript(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へようこそ。とてもいい最初の答え:)しかし、もう少しゴルフをすることができます。ifを簡単にパスして520バイトに減らしたので、良いスタートが切れるはずです。
シャギー

確かに、いくつかの+ atob / btoaを置き換えると、いくつかのバイトが節約されます
-Downgoat

1
@Shaggyありがとうございます。学ぶべきことがたくさんあります。
アーク

どういたしまして:)空きスペースがあるので、s>6&&(1バイト節約できます。(w=q+12)with wrepeat(q=i.length*9)with repeat(w=i.length*9)およびrepeat(q)withを置き換えることで、別のバイトを保存することもできます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座標です(ある場合)。その位置にジャンプした後、次の音符の位置を表す9が追加されます。

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

臨時記号がある場合は印刷します。

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

必要に応じて元帳行とメモを印刷します。実際、線は偶数のy座標に印刷されますが、ステーブの上に印刷しても当然効果はありません。

¿›ι2

セミブレーブにはこれ以上のことはありません。

¿›λ⁶«

中間点より下のメモについては、

↗↑⁴

茎を上向きに引きます

¿›ι8«↘↘¹↓¹

および四分音符のフラグ。

»»«

中間点より上のノートについては、

↙↓⁴

茎を下に引き、

¿›ι8«↗↗¹↑¹

および四分音符のフラグ。


あなたはSOGLを倒しました!:
チャーリー

@CarlosAlejoそれが起こると思った。しかし、私はそれが20%ほど私を打ち負かすと期待していました。
-dzaima

@dzaimaは、もしそれが純粋なASCIIアートの挑戦だったのかもしれませんが、これには、出力を入力に依存させる論理部分もあります。それにもかかわらず、私はまだ各言語がより良くできることに慣れています。
チャーリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.