Ayo Bikin Musik!

11

Banyak orang suka bermain musik untuk kesenangan dan hiburan. Sayangnya, musik kadang-kadang sangat sulit. Itu sebabnya kamu di sini!

Tugas

Adalah tugas Anda untuk membuat membaca musik jauh lebih mudah bagi mereka yang berjuang dengannya. Anda perlu menulis program atau fungsi yang digunakan sebagai input staf musik, dan menampilkan nama-nama catatan yang ditulis pada staf itu.

Staf, kunci, dan catatan

Sebuah staf musik , atau paranada, lima garis horizontal, peralihan yang empat ruang. Setiap garis atau spasi mewakili nada (nada) yang berbeda, tergantung pada kunci.
Ada beberapa clef musikal yang berbeda untuk dipilih, tetapi kami hanya akan berurusan dengan satu untuk saat ini: treble clef . Pada kunci treble, not diwakili pada staf sebagai berikut:

Garis
F ----------
D ----------
B ----------
G ----------
E ----------
Spasi  
   ----------  
E
   ----------  
C
   ----------  
SEBUAH
   ----------  
F
   ----------

Memformat input

Input akan diberikan sebagai string tunggal, sebagai berikut:

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

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

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

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

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

Lima baris dan empat ruang staf dibangun dari sembilan baris karakter. Garis staf dibangun dengan -karakter (tanda hubung), dan spasi dengan (spasi). Setiap baris dipisahkan dari yang berikutnya dengan satu karakter baris baru, misalnya:
-----\n \n-----\n \n-----\n \n-----\n \n-----\n
Baris panjangnya sewenang-wenang (ke jumlah yang wajar yang dapat ditangani oleh bahasa pemrograman Anda), dan setiap baris persis sama panjangnya dengan karakter seperti yang lain. Perhatikan juga bahwa baris akan selalu memiliki panjang yang dapat dibagi tiga (agar sesuai dengan pola satu catatan diikuti oleh dua kolom tanpa catatan).

Catatan ditempatkan pada staf ini dengan mengganti karakter -atau sesuai dengan o. Nada juga dapat dinaikkan (tajam) atau diturunkan (datar) dengan nada semitone (sekitar setengah perbedaan frekuensi antara not dan not yang berdekatan). Ini akan diwakili oleh karakter #dan b, masing-masing, menggantikan o. Setiap catatan akan dipisahkan dari yang berikutnya dengan tepat dua -karakter, dan catatan pertama akan selalu terjadi pada "kolom" pertama -dan (spasi) karakter.

Saat mengeluarkan nama catatan, program Anda harus selalu menggunakan huruf besar ( A B C D E F G) yang sesuai dengan catatan yang diberikan pada staf. Untuk catatan tajam ( #) dan datar ( b), program Anda perlu menambahkan #dan b, masing-masing, ke huruf yang sesuai dengan catatan tersebut. Untuk nada alami yang tidak tajam atau datar, a (spasi) harus ditambahkan.

Contoh

Memasukkan:

---------------------Hai--
                  Hai     
---------------Hai--------
            Hai           
--------- b --------------
      Hai                 
---Hai--------------------
Hai                       
------------------------

* perhatikan semua "ruang kosong" dalam contoh ini sebenarnya (karakter spasi).
Dalam hal ini (skala F utama sederhana), program Anda harus menampilkan ini:

FGA Bb CDEF

Catatan jarak antara karakter output harus persis seperti yang ditunjukkan di atas, agar sesuai dengan catatan pada staf. Di antara semua nama catatan ada dua (spasi) karakter, kecuali antara Bbdan C. Di bsini menggantikan salah satu (spasi) karakter.

Contoh
Input Lainnya:

------------------------
                     Hai  
------------------ # -----
               #        
------------Hai-----------
         Hai              
------ # -----------------
   #                    
Hai-----------------------

Keluaran:
E F# G# A B C# D# E

Satu lagi contoh untuk
masukan keberuntungan :

---------------------
oooo           
---------------------
         Hai              
---------------------

--------------- o - o--

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

Keluaran:
E E E C E G G

Aturan

  • Catatan hanya akan diberikan dalam kisaran lima baris staf E flat hingga F tajam (kecuali untuk tantangan, lihat di bawah)
  • Catatan apa pun bisa tajam atau datar, bukan hanya yang terlihat umum dalam musik (mis. Meskipun B # sebenarnya hanya dimainkan sebagai C pada kenyataannya, B # masih dapat terjadi pada input)
  • Anda dapat mengasumsikan akan ada tepat satu not per 3 kolom (sehingga tidak akan ada akord atau apapun seperti itu, dan tidak ada sisanya juga)
  • Anda dapat menganggap catatan terakhir akan diikuti oleh dua kolom tanpa catatan
  • Anda dapat mengasumsikan bahkan baris terakhir dari staf akan diikuti oleh satu karakter baris baru
  • Input harus diambil dari STDIN (atau setara dengan bahasa) atau sebagai parameter fungsi
  • Keluaran harus STDOUT (atau setara bahasa) atau sebagai hasil kembali jika program Anda berfungsi
  • Celah dan standar bawaan diizinkan! Musik adalah tentang bereksperimen dan bermain-main. Silakan dan bersenang-senang dengan bahasa Anda (meskipun menyadari bahwa mengeksploitasi celah mungkin tidak menghasilkan program yang paling menarik)
  • Ini adalah , sehingga program terpendek dalam byte menang

Tantangan bonus

  • -10% jika program Anda juga dapat berhasil memproses ruang di atas baris atas staf (G, G #, Gb).
  • -10% jika program Anda juga dapat berhasil memproses ruang di bawah garis bawah staf (D, D #, Db)
  • Dalam kasus ini, program Anda akan memasukkan baris tambahan pada awal dan akhir; baris-baris ini harus diperlakukan sama persis dengan sembilan baris lainnya
MC ΔT
sumber
Ya, saya menyadari bahwa yang satu ini sangat mirip dengan pertanyaan saya. Namun, yang satu itu hanya mendapat satu jawaban. Saya berharap membuat sesuatu yang lebih sederhana untuk melibatkan lebih banyak bahasa. Dan sebenarnya, saya percaya tantangan itu melibatkan yang sebaliknya, mengubah catatan menjadi staf.
MC ΔT

Jawaban:

3

CJam ( 40 37 * 0,8 = 29,6 poin)

qN/z3%{_{iD%6>}#_~'H,65>=@@=+'oSerS}%

Demo online

Terima kasih memang untuk menunjukkan beberapa variabel yang telah ditentukan yang saya lupa.

Peter Taylor
sumber
Sangat rapi! Anda dapat memotong beberapa byte dengan menggunakan S untuk karakter spasi. Selain itu, Anda mengganti 13 dengan D.
MC 8T
1

Ruby, 106 byte * 0.8 = 84.8

->s{a=' '*l=s.index('
')+1
s.size.times{|i|s[i].ord&34>33&&(a[i%l,2]='GFEDCBA'[i/l%7]+s[i].tr(?o,' '))}
a}

Tidak digabungkan dalam program uji

f=->s{a=' '*l=s.index('
')+1                                 #l = length of first row, initialize string a to l spaces
  s.size.times{|i|                   #for each character in s
  s[i].ord&34>33&&                   #if ASCII code for ob#
   (a[i%l,2]=                        #change 2 bytes in a to the following string
   'GFEDCBA'[i/l%7]+s[i].tr(?o,' '))}#note letter, and copy of symbol ob# (transcribe to space if o)
a}                                   #return a



t='                        
---------------------o--
                  o     
---------------o--------
            o           
---------b--------------
      o                 
---o--------------------
o                       
------------------------

'

u='                        
------------------------
                     o  
------------------#-----
               #        
------------o-----------
         o              
------#-----------------
   #                    
o-----------------------

'

v='                     
---------------------
o  o  o     o        
---------------------
         o           
---------------------

---------------o--o--

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

'

puts f[t]
puts f[u]
puts f[v]
Level River St
sumber
1

JavaScript (ES6), 144 byte - 20% = 115.2

f=s=>(n=[],l=s.indexOf(`
`)+1,[...s].map((v,i)=>(x=i%l,h=v.match(/[ob#]/),n[x]=h?"GFEDCBAGFED"[i/l|0]:n[x]||" ",h&&v!="o"?n[x+1]=v:0)),n.join``)

Penjelasan

f=s=>(
  n=[],                      // n = array of note letters
  l=s.indexOf(`
`)+1,                        // l = line length
  [...s].map((v,i)=>(        // iterate through each character
    x=i%l,                   // x = position within current line
    h=v.match(/[ob#]/),      // h = character is note
    n[x]=                    // set current note letter to:
      h?"GFEDCBAGFED"[i/l|0] //     if it is a note, the letter
      :n[x]||" ",            //     if not, the current value or space if null
    h&&v!="o"?n[x+1]=v:0     // put the sharp/flat symbol at the next position
  )),
  n.join``                   // return the note letters as a string
)

Uji

Ingatlah untuk menambahkan garis di atas staf yang sama persis dengan garis lain karena solusi ini mencakup penguraian garis di atas dan di bawah staf.

f=s=>(n=[],l=s.indexOf(`
`)+1,[...s].map((v,i)=>(x=i%l,h=v.match(/[ob#]/),n[x]=h?"GFEDCBAGFED"[i/l|0]:n[x]||" ",h&&v!="o"?n[x+1]=v:0)),n.join``)
<textarea id="input" style="float:left;width:200px;height:175px">                        
---------------------o--
                  o     
---------------o--------
            o           
---------b--------------
      o                 
---o--------------------
o                       
------------------------
                        </textarea>
<div style="float:left">
  <button onclick="results.innerHTML=f(input.value)">Test</button>
  <pre id="results"></pre>
</div>

pengguna81655
sumber