Давайте сделаем музыку!

11

Многие люди любят играть музыку для развлечения и развлечения. К сожалению, музыка иногда бывает довольно сложной. Вот почему ты здесь!

задача

Ваша работа - сделать чтение музыки намного проще для тех, кто с ней борется. Вам необходимо написать программу или функцию, которая принимает в качестве входных данных музыкальный посох и выводит названия заметок, написанных для этого посоха.

Персонал, ключ и заметки

Музыкальный коллектив , или нотный стан, пять горизонтальных линий, между ними , которые являются четыре пробела. Каждая строка или пробел представляет различную ноту (шаг), в зависимости от ключа.
Есть несколько разных музыкальных ключей на выбор, но пока мы будем иметь дело только с одним: скрипичным ключом . На скрипичном ключе примечания представлены на персонале следующим образом:

линии
F ----------
D ----------
B ----------
ГРАММ ----------
E ----------
пространства  
   ----------  
Е
   ----------  
С
   ----------  

   ----------  
F
   ----------

Форматирование ввода

Ввод будет дан как одна строка, как показано ниже:

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

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

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

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

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

Пять строк и четыре места посоха построены из девяти рядов символов. Строки персонала построены с -(дефис) символами, а пробелы с (пробел). Каждая строка отделяется от следующей одним символом новой строки, например:
-----\n \n-----\n \n-----\n \n-----\n \n-----\n
строки имеют произвольную длину (до разумного количества, которое может быть обработано вашим языком программирования), и каждая строка точно такой же длины в символах, что и остальные. Также обратите внимание, что строки всегда будут иметь длину, кратную трем (чтобы соответствовать шаблону одной заметки, за которой следуют два столбца без заметки).

Примечания размещаются на этом персонале, заменяя соответствующий -или символ с o. Ноты также могут быть подняты (резкие) или опущены (плоские) по высоте на полутон (примерно половина разницы частот между нотой и смежными нотами). Это будет представлено символами #и b, соответственно, вместо o. Каждая заметка будет отделена от следующей ровно двумя -символами, и первая заметка всегда будет появляться в первом «столбце» -и (пробел) символов.

При выводе имен заметок ваша программа всегда должна использовать заглавные буквы ( A B C D E F G), соответствующие заметке, данной на персонале. Для резких ( #) и плоских ( b) заметок ваша программа должна добавлять #и b, соответственно, к букве, соответствующей заметке. Для естественного примечания, которое не является резким или плоским, вместо него следует добавить (пробел).

пример

Входные данные:

--------------------- О-
                  о     
--------------- о --------
            о           
--------- -------------- б
      о                 
--- о --------------------
о                       
------------------------

* обратите внимание, что все «пустое место» в этом примере фактически (символ пробела).
В этом случае (простая мажорная мажорная шкала) ваша программа должна вывести следующее:

FGA Bb CDEF

Обратите внимание, что расстояние между символами вывода должно быть точно таким, как показано выше, чтобы правильно соответствовать примечаниям на персонале. Между всеми именами заметок есть два (пробел) символа, кроме между Bbи C. bЗдесь заменяет собой одну из (пробел) символов.

Еще один пример
ввода:

------------------------
                     о  
------------------ # -----
               #        
------------ О -----------
         о              
------ # -----------------
   #                    
о -----------------------

Выход:
E F# G# A B C# D# E

Еще один пример удачи
Вход:

---------------------
оооо           
---------------------
         о              
---------------------

--------------- о - О-

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

Выход:
E E E C E G G

правила

  • Примечания будут когда-либо даться только в диапазоне сотрудников из пяти линий от E flat до F Sharp (кроме проблем, см. Ниже)
  • Любая нота может быть резкой или плоской, а не только те, которые обычно встречаются в музыке (например, несмотря на то, что B # на самом деле просто воспроизводится как C, B # все еще может появляться на входе)
  • Вы можете предположить, что в 3 столбцах будет ровно одна нота (поэтому не будет ни аккордов, ни чего-либо подобного, ни пауз)
  • Можно предположить, что за последней заметкой последуют две колонки без заметок
  • Вы можете предположить, что даже за последней строкой персонала будет следовать один символ новой строки
  • Ввод должен быть взят из STDIN (или языкового эквивалента) или в качестве параметра функции
  • Вывод должен быть в STDOUT (или языковой эквивалент) или в качестве результата возврата, если ваша программа является функцией
  • Стандартные лазейки и встроенные модули разрешены! Музыка - это эксперименты и игры. Продолжайте веселиться со своим языком (хотя признайте, что использование лазейки может не дать самую интересную программу)
  • Это , поэтому выигрывает самая короткая программа в байтах

Бонусные испытания

  • -10%, если ваша программа также может успешно обработать пространство над верхней строкой персонала (G, G #, Gb).
  • -10%, если ваша программа также может успешно обработать пространство ниже нижней строки персонала (D, D #, Db)
  • В этих случаях ваша программа будет принимать в качестве входных данных дополнительную строку в начале и конце; эти строки должны обрабатываться точно так же, как и остальные девять строк
MC ΔT
источник
Да, я понимаю, что один очень похож на мой вопрос. Однако тот получил только один ответ. Я надеялся сделать что-то более простое, чтобы привлечь больше языков. И на самом деле, я считаю, что задача заключается в обратном, превращая заметки в сотрудников.
MC ΔT

Ответы:

3

CJam ( 40 37 * 0,8 = 29,6 балла)

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

Онлайн демо

Благодаря действительно для указывая на некоторые предопределенные переменные , которые я забыл о.

Питер Тейлор
источник
Очень аккуратный! Вы можете сбрить несколько байтов, используя S для пробелов. Кроме того, вы заменяете 13 на D.
MC ΔT
1

Рубин, 106 байтов * 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}

Неуправляемый в тестовой программе

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]
Уровень реки St
источник
1

JavaScript (ES6), 144 байта - 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``)

объяснение

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
)

Тест

Не забудьте добавить строку над персоналом, которая является точной длиной других строк, потому что это решение включает в себя анализ строк выше и ниже персонала.

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
источник