Музыка: как называется этот аккорд?

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

правила

  • Вы можете написать либо полную программу, либо функцию.
  • Ввод представляет собой список заметок, разделенных пробелом или другим удобным символом. Это также может быть массив строк (если он принимает входные данные из аргумента функции) или строковое представление такого массива.
  • Ввод не должен быть в определенном порядке.
  • На входе могут быть дублированные заметки. С ними нужно обращаться так же, как с одним из них.
  • Выход - это название аккорда. В случае, если он выведет несколько имен, применяется то же правило для ввода.
  • Если ввод не поддерживается аккордом, вы должны напечатать заметки как есть. Ваша программа также может поддерживать другие аккорды, не указанные в приведенных выше таблицах (которые действительны, но не имеют бонусов).
  • Вы можете использовать другие обозначения, перечисленные в статье Википедии . Но если вы выбираете Cмажор, вы должны добавить префикс для чтения в любом случае, чтобы выделить аккорд одной нотой.
  • Вы не можете использовать встроенные функции для этой задачи (если есть).
  • Это код-гольф. Самый короткий код в байтах побеждает.

Примеры

  • Вход: 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 и печатает каждый полученный аккорд. Обратите внимание, что заметки не должны начинаться или заканчиваться одновременно. Вы сами решаете, что происходит в промежуточных состояниях (до тех пор, пока они не сбоят или не перестанут работать). Вы можете предположить, что в перкуссионных каналах нет заметок (или есть только один канал, если это удобно). Рекомендуется также предоставить текстовую (или массивную) версию для тестирования, особенно если она зависит от платформы.
jimmy23013
источник
Может ли вход иметь плоские или только резкие? Должны ли обрабатываться такие заметки, как B #?
feersum
@feersum У него могут быть квартиры (если вы не претендуете на бонус -200). Добавил несколько примеров. Вам не нужно обрабатывать B#, Cbи т.д.
jimmy23013
Вы говорите Csus4 is the same as Gsus2. Я думаю, что вы имеете в виду Csus2 is the same as Gsus4, не так ли?
Гарет
@ Гарет ... Да. Исправлена.
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 Compiler / Executor . Отключить режим отладки и использовать в "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)
Jakube
источник
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-
nutki
источник
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
Ури Гранта
источник