Facciamo musica!


11

A molte persone piace suonare musica per divertimento e intrattenimento. Sfortunatamente, la musica è piuttosto difficile a volte. Ecco perché sei qui!

Compito

Il tuo compito è quello di rendere la lettura della musica molto più semplice per chi è alle prese con essa. È necessario scrivere un programma o una funzione che accetta come input un rigo musicale e genera i nomi delle note scritte su quel rigo.

Bastone, chiave e appunti

Un rigo musicale , o pentagramma, è composto da cinque linee orizzontali, tra cui quattro spazi. Ogni riga o spazio rappresenta una nota (intonazione) diversa, a seconda della chiave.
Ci sono alcune diverse chiavi musicali tra cui scegliere, ma per ora ci occuperemo solo di una: la chiave di violino . Sulla chiave di violino, le note sono rappresentate sul rigo come segue:

Linee
F ----------
D ----------
B ----------
G ----------
E ----------
spazi  
   ----------  
E
   ----------  
C
   ----------  
UN
   ----------  
F
   ----------

Formattazione dell'input

L'input verrà dato come una singola stringa, come segue:

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

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

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

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

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

Le cinque linee e i quattro spazi del rigo sono costituiti da nove file di caratteri. Le linee del rigo sono costruite con caratteri -(trattino) e spazi con (spazio). Ogni riga è separata dalla successiva da un singolo carattere di nuova riga, ad esempio:
-----\n \n-----\n \n-----\n \n-----\n \n-----\n
Le righe hanno una lunghezza arbitraria (a una quantità ragionevole che può essere gestita dal tuo linguaggio di programmazione) e ogni riga ha esattamente la stessa lunghezza in caratteri delle altre. Si noti inoltre che le righe avranno sempre una lunghezza divisibile per tre (per adattarsi al modello di una nota seguito da due colonne senza una nota).

Le note vengono inserite in questo rigo sostituendo l'appropriato -o il carattere con o. Le note possono anche essere alzate (nitide) o abbassate (piatte) in altezza di un semitono (circa la metà della differenza di frequenza tra una nota e le sue note adiacenti). Questo sarà rappresentato dai personaggi #e b, rispettivamente, al posto del o. Ogni nota sarà separata dalla successiva esattamente da due -caratteri, e la prima nota apparirà sempre sulla prima "colonna" di -e (spazio) caratteri.

Quando si emettono nomi di note, il programma deve sempre utilizzare le lettere maiuscole ( A B C D E F G) corrispondenti alla nota fornita sullo staff. Per le note taglienti ( #) e piatte ( b), il programma deve aggiungere #e b, rispettivamente, alla lettera corrispondente alla nota. Per una nota naturale che non sia nitida o piatta, si dovrebbe invece aggiungere uno (spazio).

Esempio

Ingresso:

--------------------- O--
                  o     
--------------- o --------
            o           
--------- b --------------
      o                 
--- o --------------------
o                       
------------------------

* nota tutto lo "spazio vuoto" in questo esempio è in realtà (carattere spazio).
In questo caso (una semplice scala F maggiore), il tuo programma dovrebbe produrre questo:

FGA Bb CDEF

Notare che la spaziatura tra i caratteri dell'output deve essere esattamente come mostrato sopra, per adattarsi correttamente alle note sul rigo. Tra tutti i nomi delle note ci sono due (spazio) caratteri, tranne tra il Bbe C. Il bqui sostituisce uno dei caratteri (spazio).

Un altro esempio
Input:

------------------------
                     o  
------------------ # -----
               #        
------------ o -----------
         o              
------ # -----------------
   #                    
o -----------------------

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

Un altro esempio di buona fortuna
Input:

---------------------
oooo           
---------------------
         o              
---------------------

--------------- o - O--

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

Produzione:
E E E C E G G

Regole

  • Le note verranno sempre e solo date nella gamma di personale a cinque righe da E piatta a F nitida (ad eccezione delle sfide, vedi sotto)
  • Qualsiasi nota potrebbe essere acuta o piatta, non solo quelle che si vedono comunemente nella musica (ad es. Nonostante B # in realtà venga suonato come C in realtà, B # può ancora verificarsi nell'input)
  • Puoi presumere che ci sarà esattamente una nota per 3 colonne (quindi non ci saranno accordi o qualcosa del genere, né pause)
  • Puoi presumere che l'ultima nota sarà seguita da due colonne senza note
  • Puoi presumere che anche l'ultima riga del rigo sarà seguita da un singolo carattere di nuova riga
  • L'input deve essere preso da STDIN (o equivalente della lingua) o come parametro di funzione
  • L'output deve essere su STDOUT (o equivalente in una lingua) o come risultato di ritorno se il programma è una funzione
  • Sono consentite scappatoie standard e incorporate! La musica è sperimentare e suonare. Vai avanti e divertiti con la tua lingua (anche se riconosci che lo sfruttamento di una scappatoia potrebbe non produrre il programma più interessante)
  • Questo è , quindi vince il programma più breve in byte

Sfide bonus

  • -10% se il programma può anche elaborare correttamente lo spazio sopra la linea superiore dello staff (G, G #, Gb).
  • -10% se il programma può anche elaborare correttamente lo spazio sotto la linea di fondo dello staff (D, D #, Db)
  • In questi casi il tuo programma prenderà come input una riga aggiuntiva all'inizio e alla fine; queste righe devono essere trattate esattamente come le altre nove righe

Sì, mi rendo conto che uno è abbastanza simile alla mia domanda. Tuttavia, quello ha avuto solo una risposta. Speravo di rendere qualcosa di più semplice per coinvolgere più lingue. E in realtà, credo che la sfida implichi il contrario, convertendo le note in uno staff.
MC ΔT

Risposte:


3

CJam ( 40 37 * 0.8 = 29.6 punti)

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

Demo online

Grazie davvero per aver sottolineato alcune variabili predefinite che avevo dimenticato.


Molto pulito! Puoi radere qualche byte usando S per i caratteri spaziali. Inoltre, si sostituisce 13 con D.
MC ΔT

1

Rubino, 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}

Non registrato nel programma di test

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]

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

Spiegazione

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
)

Test

Ricorda di aggiungere una linea sopra il rigo che è la lunghezza esatta delle altre linee perché questa soluzione include l'analisi delle linee sopra e sotto il rigo.

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.