Давайте робити музику!


11

Багато людей люблять грати музику для розваги та розваг. На жаль, музика буває досить складною. Ось чому ти тут!

Завдання

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

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

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

Лінії
F ----------
D ----------
Б ----------
G ----------
E ----------
Пробіли  
   ----------  
Е
   ----------  
С
   ----------  
А
   ----------  
Ж
   ----------

Форматування вводу

Введення подається у вигляді одного рядка таким чином:

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

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

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

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

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

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

Примітки розміщуються на цьому персоналі шляхом заміни відповідного -або символу на o. Нотатки також можуть бути підняті (різкими) або опущені (плоскі) по висоті на півтоні (приблизно половина різниці частот між нотою та суміжними нотами). Це буде представлено символами #та b, відповідно, замість o. Кожна примітка буде відокремлена від наступної рівно двома -символами, і перша нота завжди буде відбуватися в першій "колонці" -та (пробілі) символів.

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

Приклад

Вхід:

--------------------- о--
                  о     
--------------- o --------
            о           
--------- b --------------
      о                 
--- o --------------------
о                       
------------------------

* зауважте, що "порожній простір" у цьому прикладі є насправді (пробіл).
У цьому випадку (проста F основна шкала) ваша програма повинна вивести це:

FGA Bb CDEF

Зверніть увагу, що інтервал між символами виводу повинен бути точно таким, як показано вище, щоб правильно відповідати приміткам персоналу. Між усіма назвами нот є два (пробільні) символи, крім між Bbі C. bТут замінює собою одну з (пропуск) символів.

Інший приклад
введення:

------------------------
                     о  
------------------ # -----
               #        
------------ o -----------
         о              
------ # -----------------
   #                    
o -----------------------

Вихід:
E F# G# A B C# D# E

Ще один приклад удачі
:

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

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

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

Вихід:
E E E C E G G

Правила

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

Бонусні виклики

  • -10%, якщо ваша програма також може успішно обробити простір над верхньою лінією персоналу (G, G #, Gb).
  • -10%, якщо ваша програма також може успішно обробити простір під нижньою лінією персоналу (D, D #, Db)
  • У цих випадках ваша програма сприймає додатковий рядок на початку та в кінці; до цих рядків слід ставитися точно так само, як до інших дев’яти рядів

Так, я розумію, що це досить схоже на моє запитання. Однак на це лише одна відповідь. Я сподівався зробити щось простіше, щоб залучити більше мов. І власне, я вважаю, що виклик передбачає навпаки, перетворення нотаток на персонал.
MC ΔT

Відповіді:


3

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

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

Демонстрація в Інтернеті

Завдяки дійсно, що вказав на деякі заздалегідь визначені змінні, про які я забув.


Дуже акуратно! Ви можете голити кілька байтів, використовуючи S для символів пробілу. Крім того, ви замінюєте 13 на D.
MC ΔT

1

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

Ungolfed в тестовій програмі

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 байти - 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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.