Основна мінорна дихотомія


15

Подаючи список акордів, позначте їх як "Мажор" або "Малий".

Вхідні дані

Введенням буде список акордів, по одному на рядок, що складається з 3 нот, розділених пробілом. Кожна нота буде складатися з назви ноти у верхньому регістрі ( A- G) та необов'язкового випадкового ( #або b). Акорди можуть бути в будь-якій інверсії (тобто ноти можуть бути в будь-якому порядку).

Вихідні дані

Якщо акорд є основним, виведіть «Мажор». Якщо акорд незначний, виведіть «Незначний». Якщо акорд не є головним і незначним, виведіть порожній рядок.

Приклад

Вхідні дані

C E G
F Ab C
C Eb Gb
E G B
Db F Ab
Bb G D
D A Gb

Вихідні дані

Major
Minor

Minor
Major
Minor
Major

Тестові сценарії

Як і в деяких моїх минулих питаннях, я ще раз підкреслив кілька тестових сценаріїв, створених Джої та Вентеро, щоб створити кілька тестових випадків для цього питання:

Використання: ./test [your program and its arguments]

Нагороди

Кожен запис, на який я можу підтвердити, що відповідає специфікації, пройшов тести і, очевидно, намагався займатися гольфом, отримає відгук від мене (тому, будь ласка, надайте інструкції щодо використання зі своєю відповіддю). Найкоротше рішення до кінця 13.10.2012 буде прийнято як переможець.

Трохи теорії

Для тих із вас, хто не має знань з теорії музичної теорії, тут достатньо інформації, щоб ви могли змагатися.

Основний або мінорний акорд складається з трьох нот, які розділені певним малюнком півтонів. Якщо ми вважаємо корінь (нижня нота) акорда 0, то основним акордом є візерунок 0-4-7, а другорядний акорд - шаблон 0-3-7. Речі роблять більш незручними тим, що деякі ноти є напівтоновими, а деякі - тоном один від одного. Поширення півтонів з Ab- G#таке:

G#/Ab A A#/Bb B/Cb B#/C C#/Db D D#/Eb E/Fb E#/F F#/Gb G G#/Ab
  0   1   2    3     4    5   6   7    8     9    10  11  12

G#/Abозначає, що G#це та сама нота, що і Ab. З цього ми бачимо, що акорд Ab C Ebє основним акордом, і Ab Cb Ebце мінор.

Мудрувати далі, акорд Eb Cb Abвважається таким же , як Ab Cb Eb, Cb Eb Abі Cb Ab Ebтак далі. Кожна з цих варіацій все ще є мінорним акордом.


2
Я думаю, що ваш тест-баш потребує вкладів і очікувані відповіді замінені.
флодель

@flodel Так, ти маєш рацію. Вибачте з цього приводу, я зараз це виправив. Мені потрібно перевірити, що сценарій тесту Powershell теж не має такої проблеми.
Гарет

Відповіді:


3

GolfScript, 83 символи

n%{' '%{1\{'A#BC D EF G'?+}/.}%$(+2/{~- 12%}%.(+.(+]$0=.$]10,7>?'MMaijnoorr

'>2%}%

Це швидке перше рішення; Я впевнений, що це може бути додатково гольф. Проходить набір тестів на баш, після виправлення помилок, зазначених флоделями в коментарях.

Редагувати 1: Збережено 5 символів із скороченням розпізнавання канонізованих мажорних та мінорних акордових візерунків.

Редагувати 2: Збережено ще 2 символи з більш компактним кодуванням виходу, натхненим рішенням grc. (Дякую!) Як побічний ефект, код тепер виводить зайвий порожній рядок після виводу, але тестовий джгут, схоже, приймає це, тому я гадаю, що це нормально. :)

Ось як це працює:

  • Зовнішня петля n%{ }%n*просто розбиває введення на рядки, запускає код всередині дужок для кожного рядка та з'єднує результати з новими рядками.

  • ' '%розбиває кожен рядок на масив приміток. Після цього для кожної з цих нотаток 1\{'A#BC D EF G'?+}/перетворять цю ноту в напівтонове число, шукаючи кожного її символу в рядку 'A#BC D EF G'і додаючи позиції (що буде -1 для будь-якого символу, який не знайдений у рядку, зокрема, включаючи b). (Я впевнений, що я бачив цей трюк, який використовувався раніше.) Нарешті, .дублює кожне число, щоб в кінці циклу, наприклад, вхід F Ab Cбув перетворений [9 9 0 0 4 4].

  • Потім ми сортуємо нотатки за допомогою $, переміщуємо першу ноту до кінця (+і розділяємо масив на пари з 2/, так що тепер це виглядає, наприклад, як [[9 0] [0 4] [4 9]]. Потім {~- 12%}%карта кожної пари приміток у її різницю по модулю 12, перетворюючи наш приклад масиву [9 8 7].

  • Далі .(+робить копію масиву і обертає його елементи, залишені на одне положення. Ми робимо це двічі і збираємо копії в масив ], так що наш приклад тепер виглядає [[9 8 7] [8 7 9] [7 9 8]].

  • Потім сортуємо цей масив з масивів $і беремо перший елемент - у цьому випадку [7 9 8]- з 0=. Потім робимо копію цього масиву ( .), сортуємо його ( $), збираємо і несортований, і несортований масив в інший масив масивів ( ]), і шукаємо перше виникнення масиву [7 8 9](який записано так, 10,7>щоб зберегти два символи ) в цьому.

  • Це дає нам або 0(якщо несортований масив був [7 8 9], і, отже, акорд є основним), 1(якщо несортований масив був перестановкою [7 8 9], яка, враховуючи, що його перший елемент повинен бути найменшим, може бути лише [7 9 8], зробивши акорд незначним) або -1(якщо навіть відсортований масив не дорівнює [7 8 9]).

  • Потім це число використовується як початковий індекс у рядку "MMaijnoorr\n\n"(де \ns задані як фактичні канали рядків у коді), з яких ми беремо цей символ і кожну секунду наступну як вихід. Якщо індекс дорівнює -1, ми починаємо з останнього символу рядка, який є лише каналом рядка.


Приємне пояснення. У мене виникають ті ж труднощі, що я, як завжди, маю з GolfScript - я можу викликати його рядок за один раз для тестування, echo "G# B# Eb" | ruby golfscript.rb ilmari.gsале як запустити тестовий сценарій на ньому? Я спробував, ./test ruby golfscript.rb ilmari.gsале цього не було. (Я вже дав вам +1, бо це, очевидно, працює, але мені просто цікаво)
Гарет

1
@Gareth: Схоже, це помилка в скрипті тесту bash - він не обробляє декілька аргументів правильно. Щоб виправити це, замініть args="$@"на args=("$@")і got=$("$cmd" "$args")на got=$("$cmd" "${args[@]}"). (Або просто зробіть golfscript.rbвиконуваний файл і запустіть його як ./test ./golfscript.rb chords.gs.)
Ільмарі Каронен

4

Пітон, 160

f='A#BC D EF G3453543'.find
try:
 while 1:x,y,z=sorted(map(lambda x:f(x[0])+f(x[1:])+1,raw_input().split()));print'MMianjoorrr'[f(`y-x`+`z-y`)/14:-1:2]
except:0
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.