Faisons de la musique!

11

Beaucoup de gens aiment jouer de la musique pour le plaisir et le divertissement. Malheureusement, la musique est parfois assez difficile. Voilà pourquoi vous êtes ici!

Tâche

C'est votre travail de rendre la lecture de la musique beaucoup plus facile pour ceux qui en souffrent. Vous devez écrire un programme ou une fonction qui prend en entrée une portée musicale et génère le nom des notes écrites sur cette portée.

Bâton, clé et notes

Une portée musicale , ou portée , est composée de cinq lignes horizontales, entre lesquelles se trouvent quatre espaces. Chaque ligne ou espace représente une note (hauteur) différente, selon la clé.
Il existe un bon nombre de clés musicales parmi lesquelles choisir, mais nous n'en traiterons qu'une pour l'instant: la clé de sol . Sur la clé de sol, les notes sont représentées sur la portée comme suit:

Lignes
F ----------
RÉ ----------
B ----------
G ----------
E ----------
Les espaces  
   ----------  
E
   ----------  
C
   ----------  
UNE
   ----------  
F
   ----------

Formatage de l'entrée

L'entrée sera donnée en une seule chaîne, comme suit:

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

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

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

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

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

Les cinq lignes et les quatre espaces de la portée sont construits à partir de neuf rangées de caractères. Les lignes de la portée sont construites avec des caractères -(trait d'union) et des espaces avec (espace). Chaque ligne est séparée de la suivante par un seul caractère de nouvelle ligne, par exemple:
-----\n \n-----\n \n-----\n \n-----\n \n-----\n
Les lignes sont de longueur arbitraire (à une quantité raisonnable qui peut être gérée par votre langage de programmation), et chaque ligne a exactement la même longueur en caractères que les autres. Notez également que les lignes seront toujours d'une longueur divisible par trois (pour s'adapter au modèle d'une note suivie de deux colonnes sans note).

Des notes sont placées sur cette portée en remplaçant le caractère approprié -ou par o. Les notes peuvent également être augmentées (nettes) ou abaissées (plates) en hauteur d'un demi-ton (environ la moitié de la différence de fréquence entre une note et ses notes adjacentes). Celui-ci sera représenté par les caractères #et b, respectivement, à la place du o. Chaque note sera séparée de la suivante par exactement deux -caractères, et la première note se produira toujours sur la première "colonne" des caractères ( -et espace).

Lors de la sortie des noms de notes, votre programme doit toujours utiliser les lettres majuscules ( A B C D E F G) correspondant à la note donnée sur la portée. Pour les notes nettes ( #) et plates ( b), votre programme doit être ajouté #et b, respectivement, à la lettre correspondant à la note. Pour une note naturelle qui n'est pas nette ou plate, un (espace) doit être ajouté à la place.

Exemple

Contribution:

--------------------- o--
                  o     
--------------- o --------
            o           
--------- b --------------
      o                 
--- o --------------------
o                       
------------------------

* notez que tout "espace vide" dans cet exemple est en fait (caractère espace).
Dans ce cas (une échelle simple en fa majeur), votre programme devrait produire ceci:

FGA Bb CDEF

Notez que l'espacement entre les caractères de la sortie doit être exactement comme indiqué ci-dessus, pour s'adapter correctement aux notes sur la portée. Entre tous les noms de note, il y a deux caractères (espace), sauf entre le Bbet C. L' bici remplace l'un des caractères (espace).

Un autre exemple d'
entrée:

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

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

Un autre exemple pour la bonne chance d'
entrée:

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

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

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

Production:
E E E C E G G

Règles

  • Les notes ne seront données que dans la gamme de cinq lignes de mi bémol à fa pointu (sauf pour les défis, voir ci-dessous)
  • Toute note peut être nette ou plate, pas seulement celles que l'on voit couramment dans la musique (par exemple, bien que B # soit en fait joué comme C en réalité, B # peut toujours apparaître dans l'entrée)
  • Vous pouvez supposer qu'il y aura exactement une note par 3 colonnes (donc il n'y aura pas d'accords ou quelque chose comme ça, et pas de reste non plus)
  • Vous pouvez supposer que la dernière note sera suivie de deux colonnes sans notes
  • Vous pouvez supposer que même la dernière ligne de la portée sera suivie d'un seul caractère de nouvelle ligne
  • L'entrée doit être prise à partir de STDIN (ou équivalent de langue) ou comme paramètre de fonction
  • La sortie doit être vers STDOUT (ou équivalent de langue) ou comme résultat de retour si votre programme est une fonction
  • Les failles standard et intégrées sont autorisées! La musique consiste à expérimenter et à jouer. Allez-y et amusez-vous avec votre langue (tout en reconnaissant que l'exploitation d'une faille peut ne pas produire le programme le plus intéressant)
  • C'est le , donc le programme le plus court en octets gagne

Défis bonus

  • -10% si votre programme peut également traiter avec succès l'espace au-dessus de la ligne supérieure de la portée (G, G #, Gb).
  • -10% si votre programme peut également traiter avec succès l'espace en dessous de la ligne du bas du personnel (D, D #, Db)
  • Dans ces cas, votre programme prendrait en entrée une ligne supplémentaire au début et à la fin; ces lignes doivent être traitées exactement de la même manière que les neuf autres lignes
MC ΔT
la source
Oui, je me rends compte que l'une est assez similaire à ma question. Cependant, celui-ci n'a obtenu qu'une seule réponse. J'espérais faire quelque chose de plus simple pour impliquer plus de langues. Et en fait, je crois que le défi implique le contraire, la conversion de notes en portée.
MC ΔT

Réponses:

3

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

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

Démo en ligne

Merci en effet d' avoir signalé certaines variables prédéfinies que j'avais oubliées.

Peter Taylor
la source
Très propre! Vous pouvez raser quelques octets en utilisant S pour les caractères d'espace. De plus, vous remplacez 13 par D.
MC ΔT
1

Ruby, 106 octets * 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 testé dans le programme de 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]
Level River St
la source
1

JavaScript (ES6), 144 octets - 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``)

Explication

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
)

Tester

N'oubliez pas d'ajouter une ligne au-dessus de la portée qui est la longueur exacte des autres lignes, car cette solution inclut l'analyse des lignes au-dessus et en dessous de la portée.

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>

user81655
la source