Vamos fazer música!

11

Muitas pessoas gostam de tocar música para diversão e entretenimento. Infelizmente, a música é bem difícil às vezes. É por isso que você está aqui!

Tarefa

É seu trabalho facilitar a leitura de músicas para aqueles que lutam com ela. Você precisa escrever um programa ou função que tenha como entrada uma pauta musical e produz os nomes das notas escritas nessa pauta.

Cajado, clave e anotações

Uma pauta musical , ou pauta, tem cinco linhas horizontais, entre as quais quatro espaços. Cada linha ou espaço representa uma nota diferente (tom), dependendo da clave.
Existem algumas claves musicais diferentes para escolher, mas só vamos lidar com uma por enquanto: a clave de sol . Na clave de sol, as notas são representadas na pauta da seguinte maneira:

Linhas
F ----------
D ----------
B ----------
G ----------
E ----------
Espaços  
   ----------  
E
   ----------  
C
   ----------  
UMA
   ----------  
F
   ----------

Formatação da entrada

A entrada será fornecida como uma única sequência, da seguinte maneira:

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

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

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

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

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

As cinco linhas e os quatro espaços da equipe são construídos com nove linhas de caracteres. Linhas da equipe são construídas com -caracteres (hífen) e espaços com (espaço). Cada linha é separada da seguinte por um único caractere de nova linha, por exemplo:
-----\n \n-----\n \n-----\n \n-----\n \n-----\n
As linhas são de tamanho arbitrário (em uma quantidade razoável que pode ser manipulada pela sua linguagem de programação), e cada linha tem exatamente o mesmo tamanho em caracteres que as outras. Observe também que as linhas sempre terão um comprimento divisível por três (para ajustar o padrão de uma nota seguida por duas colunas sem uma nota).

As notas são colocadas nessa pauta substituindo o apropriado -ou o personagem por o. As notas também podem ser aumentadas (nítidas) ou abaixadas (achatadas) em um tom semitom (cerca da metade da diferença de frequência entre uma nota e suas notas adjacentes). Isso será representado pelos caracteres #e b, respectivamente, no lugar do o. Cada nota será separada da seguinte por exatamente dois -caracteres, e a primeira nota sempre ocorrerá na primeira "coluna" dos caracteres -e (espaço).

Ao emitir nomes de notas, seu programa sempre deve usar as letras maiúsculas ( A B C D E F G) correspondentes à nota dada na equipe. Para notas nítidas ( #) e planas ( b), seu programa precisa anexar #e b, respectivamente, à letra correspondente à nota. Para uma nota natural que não seja nítida ou plana, um (espaço) deve ser anexado.

Exemplo

Entrada:

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

* observe que todo "espaço vazio" neste exemplo é realmente (caractere de espaço).
Nesse caso (uma escala simples F maior), seu programa deve gerar o seguinte:

FGA Bb CDEF

Observe que o espaçamento entre os caracteres da saída deve ser exatamente como mostrado acima, para se encaixar corretamente nas notas da pauta. Entre todos os nomes das notas, há dois caracteres (espaço), exceto entre Bbe C. O baqui substitui um dos caracteres (espaço).

Outro exemplo de
entrada:

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

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

Mais um exemplo de boa sorte
de entrada:

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

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

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

Resultado:
E E E C E G G

Regras

  • As notas só serão dadas na faixa de E da equipe de cinco linhas, até F acentuada (exceto para os desafios, veja abaixo)
  • Qualquer nota pode ser nítida ou achatada, não apenas as vistas comumente na música (por exemplo, apesar de o B # realmente ser tocado como C na realidade, o B # ainda pode ocorrer na entrada)
  • Você pode assumir que haverá exatamente uma nota a cada 3 colunas (portanto, não haverá acordes nem nada do tipo, nem descansos)
  • Você pode assumir que a última nota será seguida por duas colunas sem notas
  • Você pode assumir que até a última linha da equipe será seguida por um único caractere de nova linha
  • A entrada deve ser obtida a partir de STDIN (ou idioma equivalente) ou como parâmetro de função
  • A saída deve ser STDOUT (ou idioma equivalente) ou como resultado de retorno se o seu programa for uma função
  • São permitidas brechas e embutidos padrão! Música é experimentar e brincar. Vá em frente e divirta-se com seu idioma (embora reconheça que explorar uma brecha pode não produzir o programa mais interessante)
  • Isso é , então o programa mais curto em bytes vence

Desafios bônus

  • -10% se o seu programa também puder processar com êxito o espaço acima da linha superior da equipe (G, G #, Gb).
  • -10% se o seu programa também puder processar com êxito o espaço abaixo da linha inferior da equipe (D, D #, Db)
  • Nesses casos, seu programa levaria como entrada uma linha adicional no início e no final; essas linhas devem ser tratadas exatamente da mesma forma que as outras nove linhas
MC ΔT
fonte
Sim, eu percebo que um é bastante semelhante à minha pergunta. No entanto, esse só conseguiu uma resposta. Eu esperava tornar algo mais simples para envolver mais idiomas. E, na verdade, acredito que o desafio envolve o oposto, converter anotações em uma equipe.
MC ΔT

Respostas:

3

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

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

Demonstração online

Graças ao fato de apontar algumas variáveis pré-definidas que eu tinha esquecido.

Peter Taylor
fonte
Muito arrumado! Você pode cortar alguns bytes usando S para caracteres de espaço. Além disso, você substitui 13 por D.
MC ΔT
1

Ruby, 106 bytes * 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}

Ungolfed in program program

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
fonte
1

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

Explicação

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
)

Teste

Lembre-se de adicionar uma linha acima da equipe com o comprimento exato das outras linhas, porque esta solução inclui a análise das linhas acima e abaixo da equipe.

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
fonte