Музика: Як звуть цей акорд?


9

Це зворотний бік музики: що в цьому акорді? , що полягає у друкуванні нот у заданому акорді. Цього разу вхід - це список нот у акорді, а ваше завдання - вивести, який саме акорд він.

Ваша програма повинна підтримувати наступні тріадні акорди. Приклади наведено з коренем C. Акорди з іншими коренями - це ті самі акорди з усіма обернутими нотами, так що C стане цією кореневою нотою, наприклад, Dmaj складається з D, F # і A.

        C C#D D#E F F#G G#A A#B
          Db  Eb    Gb  Ab  Bb
Cmaj    C       E     G
Cm      C     D#      G
Caug    C       E       G#
Cdim    C     D#    F#
Csus4   C         F   G
Csus2   C   D         G

Зауважте, що Caug - це те саме, що Eaug і G # aug, а Csus4 - це те саме, що і Fsus2. Ви можете випустити будь-яку, але є бонус, якщо ви виведете їх усі.

А сьомі акорди за бонус вказані в наступній таблиці:

        C C#D D#E F F#G G#A A#B
          Db  Eb    Gb  Ab  Bb
C7      C       E     G     A#
Cm7     C     D#      G     A#
Cmmaj7  C     D#      G       B
Cmaj7   C       E     G       B
Caug7   C       E       G#  A#
Cdim7   C     D#    F#    A

Правила

  • Можна написати або повну програму, або функцію.
  • Вхід - це список приміток, розділених пробілом або іншим зручним символом. Це також може бути масив рядків (якщо він бере вхід з аргументу функції) або рядкове представлення такого масиву.
  • Введення даних не повинно бути в певному порядку.
  • На вводі можуть бути дублюються нотатки. До них треба ставитися так само, як є лише один з них.
  • Вихід - назва акорду. У випадку, якщо він виведе кілька імен, застосовується те саме правило для введення.
  • Якщо вхід не підтримується акордом, слід надрукувати нотатки як є. Ваша програма також може підтримувати інші акорди, які не вказані у наведених вище таблицях (що є дійсним, але не має бонусу).
  • Ви можете використовувати інші позначення, перелічені в статті Вікіпедії . Але якщо ви виберете CC-мажор, вам слід додати людський читабельний префікс в будь-якому випадку, щоб відрізнити акорд з однією нотою.
  • Ви не можете використовувати вбудовані функції для цього завдання (якщо вони є).
  • Це код-гольф. Виграє найкоротший код у байтах.

Приклади

  • Вхід: C D# GВихід: Cm.
  • Вхід: C Eb GВихід: Cm.
  • Вхід: C Eb F#Вихід: Cdim.
  • Вхід: F A C#Вихід: Faug, Aaug, C#aug, Dbaugабо Faug Aaug C#aug, Faug Aaug Dbaugв будь-якому порядку.
  • Вхід: F D F F F F A A FВихід: Dm.
  • Вхід: C DВихід: C D.

Бонуси

  • -30, якщо він роздруковує їх усіх, якщо є кілька інтерпретацій (для aug, sus4 / sus2 і dim7).
  • -70, якщо він також підтримує сьомі акорди.
  • -200, якщо він приймає вхід MIDI і друкує кожен отриманий акорд. Зауважте, що нотатки не повинні починатись і закінчуватися одночасно. Ви вирішуєте, що відбувається в проміжних станах (до тих пір, поки воно не вийде з ладу або перестане працювати). Ви можете припустити, що в ударних каналах немає приміток (або є лише один канал, якщо це зручно). Рекомендується також надати текстову (або масив) версію для тестування, особливо якщо це залежить від платформи.

Чи може вхід мати квартири або він використовує лише різкий? Чи слід обробляти примітки, такі як B #?
feersum

@feersum У ньому можуть бути квартири (якщо ви не вимагаєте бонусу -200). Додано кілька прикладів. Вам не потрібно обробляти B#, Cbі т.д.
jimmy23013

Ви кажете Csus4 is the same as Gsus2. Я думаю, ти маєш на увазі, Csus2 is the same as Gsus4чи не так?
Гарет

@Gareth ... Так. Виправлено.
jimmy23013

Відповіді:


2

Персонаж Pyth 190 - 30 - 70 = 90

=Q{cQdL+x"C D EF G A B"hb&tlbt%hx" #b"eb3FZQJx[188 212 199 213 200 224 2555 2411 2412 2556 2567 2398)u+*G12hHSm%-dyZ12mykQ0IhJ+Z@c"sus2 maj dim aug m sus4 7 m7 mmaj7 maj7 aug7 dim7"dJ=T0;ITQ

Не дуже задоволений цим. Використовуються жорсткі штрихи.

Використання:

Спробуйте тут: компілятор / виконавець Pyth . Вимкнути режим налагодження та використовувати "C D# G"як вхід.

Пояснення:

Спочатку підготування:

=Q{cQd
   cQd  split chord into notes "C D# G" -> ["C", "D#", "G"]
  {     set (eliminate duplicates)
=Q      Q = ...

Потім функція, яка перетворює нотатки в ціле число

L+x"C D EF G A B"hb&tlbt%hx" #b"eb3
defines a function g(b),
  returns the sum of 
     index of "D" in "C D EF G A B"
     and the index of "#" in " #b" 
       (if b than use -1 instead of 2)

Потім для кожної ноти змістіть координату і роздивіться її в таблиці

FZQJx[188 ...)u+*G12hHSm%-dyZ12mykQ0IhJ+Z@c"sus2 ..."dJ=T0;ITQ
               implicit T=10
FZQ            for note Z in chord Q:
   mykQ         map each note of Q to it's integer value
   m%-dyZ12     shift it by the integer value of Z modulo 12 
   S            sort it
   u+*G12hH 0   convert it to an integer in base 12
   x[188 ...)   look it up in the list (-1 if not in list)
   J            and store the value in J

   IhJ               if J>=0:
   +Z@c"sus2 ..."dJ   print the note Z and the chord in the list
=T0                   and set T=0
;            end loop
ITQ          if T:print chord (chord not in list)

2

Perl 5: 183 - 100 = 83

Редагувати: мені вдалося вирізати кілька зайвих символів, тому я також змінив назви акордів, як у рішенні Python, так що я можу прикинутись на мить, що я веду за собою.

#!perl -pa
for$z(0..11){$x=0;$x|=1<<((/#/-/b/+$z+1.61*ord)%12or$o=$_)for@F;$x-/\d+_?/-$_*4||push@r,$o.$'
for qw(36M 34- 68+ 18o 40sus2 33sus4 292_7 290-7 546-M7 548M7 324+7 146o7)}$_="@r
"if@r

Приклад:

$ perl chord.pl <<<"C D# G"
C-

0

Python 2, 335 байт - 30 - 70 = 235

Перша спроба трохи довшого гольфу, тому я, можливо, не пропускаю явних хитрощів.

def f(s,N="C D EF G A B",r=range,u=1):
 for i in r(12):
  for t in r(12):
   if(set((N.find(n[0])+" #".find(n[1:]))%12for n in s.split())==set(map(lambda n:(int(n,16)+i)%12,"0"+"47037048036057027047A37A37B47B48A369"[3*t:3*t+3]))):print(N[i],N[i+1]+"b")[N[i]==" "]+"M - + o sus4 sus2 7 -7 -M7 M7 +7 o7".split()[t];u=0
 if(u):print s

Коментарі:

  • Для економії місця я використав альтернативні назви акордів зі сторінки Wiki (див. Кінець довгого рядка).
  • Акорди представлені 3-ма шестнадцятковими зміщеннями (0 не потрібно, але включено для тріад для їх вирівнювання).
  • "#". find (n [1:]) працює, оскільки "#". find ("b") дорівнює -1, а "#". find ("") дорівнює 0.

Вибірка зразка

>>> f("C D# G")
C-
>>> f("C Eb G")
C-
>>> f("C Eb F#")
Co
>>> f("F A C#")
Db+
F+
A+
>>> f("F D F F F F A A F")
D-
>>> f("C D")
C D
>>> f("C Eb Gb A")
Co7
Ebo7
Gbo7
Ao7
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.