Созвучие или диссонанс?

36

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

Введение

В западной музыке есть только 12 «разных» тонов. Их имена, отсортированные от низшего к высшему, являются следующие: C, C#, D, D#, E, F, F#, G, G#, A, A#, B. Последовательность носит циклический характер , т.е. продолжается с другой Cпосле того B, бесконечно.

Расстояние между двумя тонами называется интервалом . Интервал между любыми двумя нотами, которые находятся рядом в ряду выше (например, C — C#или E — F), называется полутоном . Интервал между более удаленными нотами определяется как количество полутоновых шагов, необходимых для перехода от первого к второму (при этом, возможно, обтекание последовательности). Некоторые примеры: D to E= 2 полутона, C to G= 7 полутонов, B to D#= 4 полутона (это оборачивает последовательность). 1

Теперь эти интервалы делятся на две категории: согласные (приятно звучащие, если вы играете две ноты одновременно) и диссонирующие (не так уж много).

Определим согласные интервалы: 0, 3, 4, 5, 7, 8 и 9 полутонов.

Остальные из них диссонируют, а именно: 1, 2, 6, 10 и 11 полутонов.

Соревнование

Напишите «программу» (в обычном широком смысле этого слова: функция вполне подходит), чтобы сделать следующее:

  • Возьмите два имени примечания (строки из последовательности выше) в качестве входных данных. Вы можете взять их как угодно (из stdin, в качестве аргументов, разделенных тем, что вы хотите, даже не стесняйтесь воспринимать их как список символов (например ["C","#"]). Однако вы не можете назначать любые другие имена заметкам (особенно вам может не нумеровать их от 0 до 11 и использовать цифры).

  • Для вас, фанатов музыки, ноты будут указаны без октавы. В этом случае также не имеет значения, в каком порядке идут ноты, а какой ниже, а какой выше. Наконец, вам не нужно обрабатывать имена, которых нет в списке выше. Никаких других энхармоник, таких как E#квартиры, двойные переделки и так далее.

  • Выберите любые два разных значения. Ваша программа должна выводить один из них всякий раз, когда интервал, образованный двумя нотами во входных данных, является согласным, а другой - нет. (Может быть Trueи False, но даже π и e, если хотите :))

  • Это код-гольф. Победит самая короткая программа в байтах на каждом языке. Повеселись!

Примеры и тестовые случаи

Note 1    Note 2    Output    Interval [semitones]
  C          D     Dissonant   2
  A#         A#    Consonant   0
  G          D     Consonant   7 (wraparound)
  D#         A     Dissonant   6
  F          E     Dissonant   11
  A          C     Consonant   3

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

Это мой первый вызов, поэтому любая конструктивная критика горячо приветствуется :—). Если вы находите объяснение теории неряшливым, не стесняйтесь задавать вопросы. Наконец, пожалуйста, не говорите мне, что это обман этого или этого . Я убедился, что это не так. (Последнее очень похоже, но сложнее. Я подумал, что если поставить более простую задачу, людям будет легче присоединиться.)


1 : я попытался упростить это объяснение, насколько я мог. Есть намного больше теории относительно интервалов. Пожалуйста, не ругайте меня за то, что я оставил это.

Ramillies
источник

Ответы:

12

Желе , 21 байт

Принимает ввод как список из двух строк. Возвращает 0за диссонанс или 1согласную.

OḢ6×%21_Lµ€IA“¬ɠṘ’æ»Ḃ

Попробуйте онлайн!

OḢ6×%21_Lµ€IA“¬ɠṘ’æ»Ḃ   - main link
         µ€             - for each note             e.g. ["A#", "C"]
O                       -   convert to ASCII codes  -->  [[65, 35], 67]
 Ḣ                      -   keep the first element  -->  [65, 67]
  6×                    -   multiply by 6           -->  [390, 402]
    %21                 -   modulo 21               -->  [12, 3]
       _L               -   subtract the length     -->  [12, 3] - [2, 1] = [10, 2]
           IA           - absolute difference       -->  8
             “¬ɠṘ’      - the integer 540205
                  æ»    - right-shift               -->  540205 >> 8 = 2110
                    Ḃ   - isolate the LSB           -->  2110 & 1 = 0

Изготовление

Прежде всего следует отметить, что функция F является коммутативной: для любой пары нот (A, B) имеем F (A, B) = F (B, A) .

Поскольку существует не так много возможных входов и только 2 возможных выхода, должно быть возможно найти довольно простую хэш-функцию H , такую, что | H (A) - H (B) | создает ограниченный диапазон значений и не имеет коллизий для всех возможных пар нот (A, B) относительно ожидаемого результата.

Мы собираемся протестировать набор функций H (mul, mod) , которые определены как:

H(mul, mod)(s) = ((ORD(s[0]) * mul) MOD mod) - LEN(s)

Где ORD(s[0])код ASCII первого символа примечания и LEN(s)длина примечания ( 2 если есть, '#'и 1, если нет).

Ниже приведена закомментированная версия кода JS, которая использовалась для поиска пары допустимых пар (mul, mod) и полученных битовых масок. Есть много возможных решений, но * 6 % 21это самый короткий способ с этим методом.

Arnauld
источник
3
Как вы вообще придумываете эти вещи? .. Вы получаете такие «алгоритмы» вручную или грубой силой? И независимо от ответа на второй вопрос: как?! ..: S " буквенное целое число 540205; смещено вправо с помощью (код ASCII; умножить на 6; по модулю 21; оставить первым; вычесть длину ...); поразрядно-AND 1 ». Ваши ответы продолжают
удивлять
@KevinCruijssen Я добавил оригинальный код JS, который использовался для поиска этих значений.
Арно
Спасибо за добавленное объяснение. Я по-прежнему впечатлен первым, но вы дали четкое объяснение того, как вы это сделали. Жаль, что я могу проголосовать только один раз.
Кевин Круйссен
9

АПЛ (Дялог) , 62 39 байт

Использует ⎕IO←0; 0 согласен, 1 диссонирует. Принимает список символов базовой ноты в качестве левого аргумента и список острых символов в качестве правого аргумента.

{⎕A[|-/('C D EF G A '⍳⍺)+⍵=⍕#]∊'BCGKL'}

Попробуйте онлайн!

{} Анонимная функция где левый аргумент и правый аргумент

⎕A[... ]∊'BCGKL' это lphabet, индексируется в следующем, член строки?

  ⍕# отформатировать корневое пространство имен (дает острый символ)

  ⍵= правильные аргументы (символы) равны этому?

  (... )+ добавить следующее:

   'C D EF G A '⍳⍺ индексы левого аргумента в строке

  -/ разница между этими

  | абсолютная величина

Уриэль
источник
Не могли бы вы добавить объяснение тем из нас, кто не знаком с APL?
Драконис
@Draconis Объяснение добавлено.
AdaM
9

MATL , 30 27 26 байт

,j'DJEFPGIALBC'&mQs]ZP7Mdm

Вводит две ноты в разные строки. Выходы 0для согласных, 1для диссонантных.

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

Строка из 11 символов

DJEFPGIALBC

кодирует ноты и диссонирующие интервалы следующим образом.

Сначала программа находит основанные на 1 индексы входных символов в приведенной выше строке. Неострый ввод вроде Dдаст 1, Eдаст 3, ..., Cдаст 11. Эти числа также могут рассматриваться как числовые массивы 1 × 1. Резкий ввод как C#даст массив 1 × 2 [11 0], что означает, что Cбыл найден в позиции 11и# не был найден.

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

Числа в первой записи массива 1 × 1 или 1 × 2 соответствуют шагу ноты в полутонах, не считая острых символов (пока). Обратите внимание, что шкала, определяемая этими числами, не начинается с C; но это не имеет значения, потому что мы хотим только интервалы, то есть различия между заметками. Вычитание полученных чисел дало бы или интервал или 12 минус интервал. Но сначала нам нужно рассмотреть острый символ.

Чтобы учесть острые ноты, игра в гольф (в MATL) заключается в добавлении 1к каждой записи полученного ранее массива 1 × 1 или 1 × 2, а затем суммировании массива (2 байта). Таким образом, неострые ноты увеличиваются на1 а резкие ноты на 2. Это делает острые ноты на 1 полутон выше, чем неострые ноты, как требуется. Мы также добавляем дополнительный полутон ко всем заметкам, но это не меняет интервалы между ними. Так что теперь записка Dдаст номер шага 2, D#даст 3, ..., Cдаст 12, C#даст13 .

Диссонирующие интервалы 1, 2, 6, 10, или 11. Они имеют симметрию по модулю 12 : интервал между двумя нотами является диссонирующим тогда и только тогда, когда интервал с нотами в обратном порядке по модулю 12 диссонирует.

Если мы вычислим последовательные различия строки, 'DJEFPGIALBC'мы получим числовой вектор

6 -5 1 10 -9 2 -8 11 -10 1

который содержит именно диссонантные интервалы, в дополнение к некоторым отрицательным значениям, которые не будут ни полезными, ни вредными. Заметьте, что выбор дополнительных букв JPILв строке 'DJEFPGIALBC'определяет (через последовательные различия) интервалы диссонанса.

Чтобы увидеть, являются ли две входные ноты диссонансными, мы берем абсолютную разницу их значений основного тона. Например, Cи D#дадут цифры 12и 3соответственно, а абсолютная разница будет 9. Фактическая разница будет равна -9фактическому интервалу 3(полученному по -9модулю 12). Но благодаря симметрии, упомянутой выше, мы можем рассмотреть 9вместо 3. Поскольку 9нет в векторе последовательных различий, ноты согласны.

Луис Мендо
источник
2
Мне нравится, как вы кодировали ноты и диссонирующие интервалы в одной строке.
celtschk
8

JavaScript (ES6), 68 64 байта

Принимает заметки в виде двух строк в синтаксисе карри (a)(b). Возвращает 0за диссонанс или 1согласную.

a=>b=>488055>>(g=s=>'C D EF G A'.search(s[0])-!s[1])(a)-g(b)+9&1

Контрольные примеры

Отформатировано и прокомментировано

a => b =>                       // given the two notes 'a' and 'b'
  488055 >>                     // 19-bit lookup bitmask: 1110111001001110111
    (g = s =>                   // we use g() to convert a note 's' into a semitone index
      'C D EF G A'.search(s[0]) // position of the note: -1 for 'B' (not found) to 9 for 'A'
      - !s[1]                   // subtract 1 semitone if the '#' is not there
    )(a)                        // compute the result for 'a'  --> [ -2 ...  9]
    - g(b)                      // subtract the result for 'b' --> [-11 ... 11]
    + 9                         // add 9                       --> [ -2 ... 20]
  & 1                           // test the bitmask at this position (0 if negative or > 18)
Arnauld
источник
7

Желе , 26 байт

i@€ØAo.SḤ’d5ḅ4µ€ạ/“¢£©½¿‘ċ

Монадическая ссылка, принимающая список из двух заметок (в виде списков символов) и возвращающая 0согласные и1 для диссонирующих.

Попробуйте онлайн! или увидеть все входы в тестовом наборе .

Как?

i@€ØAo.SḤ’d5ḅ4µ€ạ/“¢£©½¿‘ċ - Link: list of lists of characters, notes
              µ€           - for €ach note in notes: (call the resulting list x)
   ØA                      -   yield the uppercase alphabet
i@€                        -   first index of c in ^ for €ach character, c
                           -     ...note '#' is not there so yields 0 (A->1, B->2,...)
      .                    -   literal one half
     o                     -   or (vectorised)  - e.g. "C#" -> [3, 0] -> [3, 0.5]
       S                   -   sum
        Ḥ                  -   double - that is ...  C C#  D D#  E  F F#  G G#  A A#  B
                                                 ->  6  7  8  9 10 12 13 14 15  2  3  4
         ’                 -   decrement         ->  5  6  7  8  9 11 12 13 14  1  2  3
           5               -   literal five
          d                -   divmod                (e.g. 9 -> [1,4] or 11 -> [2,1])
             4             -   literal four
            ḅ              -   convert from base     (e.g. [1,4] -> 8 or [2,1] -> 9)
                                                 ->  4  5  6  7  8  9 10 11 12  1  2  3
                 /         - reduce x with:
                ạ          -   absolute difference   (e.g. ["G#", "A"] -> [12, 1] -> 11)
                  “¢£©½¿‘  - code-page indices = [1, 2, 6, 10, 11]
                         ċ - count occurrences (1 if in the list, 0 if not)
Джонатан Аллан
источник
5

Желе , 31 байт

O_65ị“¢[ḋṃ’b⁴¤+L$€Ḣ€ạ/e“cṾ’b12¤

Попробуйте онлайн!

Wheeeeee 32 байта слишком долго

объяснение

O_65ị“¢[ḋṃ’b⁴¤+L$€Ḣ€ạ/e“cṾ’b12¤  Main link
O                                Cast each character to an int using Python `ord`
 _65                             Subtract 65 (A is 0, G is 7)
     “¢[ḋṃ’b⁴¤                   [2, 3, 5, 7, 9, 10, 0]
     “¢[ḋṃ’                      37058720
           b                     Digits in base
            ⁴                    16
    ị                            Index into this list; this creates the gaps for sharps
                 €               For each sublist
              +L$                Add the length to each element (Sharpens sharp notes)
              +                  Add
               L                 Length
                   €             For each sublist
                  Ḣ              Take the first element
                    ạ/           Absolute difference between the two (unoctaved) pitches # It's convenient that every interval's inverse (?) has the same consonance/dissonance
                      e          Is the semitone difference in
                       “cṾ’b12¤  [1, 2, 6, 10, 11]?
                       “cṾ’      25178
                           b     base
                            12   12
HyperNeutrino
источник
Эй, это отличный ответ! Мне было интересно, если кто-то использует симметрию, и вы сделали. И мне нравится ваш метод сопоставления имен заметок с числами! +1.
Ramillies
Разница в полутонах может быть симметричной, но вы все равно получите результаты без прикрас - например "G#", "A"(диссонанс) дает разницу, 11которой нет[1,2,6] .
Джонатан Аллан
@JonathanAllan о, ну это неловко; Я думал, что абсолютная разница фиксирует это ... ._. исправит LOL
HyperNeutrino
1
@JonathanAllan исправлено для пары дополнительных байтов (3 IIRC)
HyperNeutrino
4

Mathematica, 55 байт

function                                                  arguments        bytes

FreeQ[1|2|6|10|11]@Abs[#-#2&@@Sound`PitchToNumber/@#]&    [{"C","F#"}]     55

Сопоставьте внутреннюю встроенную Sound`PitchToNumberвходную информацию (список из двух строк), возьмите абсолютную разницу, затем сопоставьте шаблон для диссонирующих интервалов.


Просто для удовольствия (не соревнуясь)

Вот некоторые более короткие функции, которые нарушают ограничение «вы не можете назначать никакие другие имена примечаниям». У элементарного Music`пакета есть предопределенные константы примечания (например A4 = 440.) и функция HertzToCents(которая может быть введена в игру). Вместо строк мы будем использовать константы примечания в качестве аргументов, но для каждой функции они предоставляются в разном формате.

FreeQ[1|2|6|10|11]@Abs@@Round[.01HertzToCents@#]&         [{C3,Fsharp3}]   50+9=59
FreeQ[1|2|6|10|11]@Abs@Round[17Log[#2/#]]&                [C3,Fsharp3]     43+9=52
FreeQ[1|2|6|10|11]@Abs@Round[17Log@#]&                    [C3/Fsharp3]     39+9=48

Импорт пакета <<Music`; занимает 9 байтов.

Эта функция преобразует строку (например "F#") в константу примечания (например Fsharp3):

Symbol[StringReplace[#,"#"->"sharp"]<>"3"]&                                44

Чтобы принять интервалы, превышающие октаву, замените Abs[…]на Mod[…,12].


Почему некоторые интервалы считаются диссонансными? Интервал - это соотношение двух частот. Если отношение имеет «простой» числитель и знаменатель, оно имеет тенденцию быть более согласным. В 5-предельной настройке отношения могут быть преобразованы в целочисленные степени только простых чисел, меньших или равных 5. Никакой интервал с одинаковым темпераментом, кроме октавы, не является просто интервалом ; это просто близкие приближения, использующие степени 12-го корня из 2.

Вместо жесткого кодирования того, какие числа интервалов являются диссонансными, мы можем найти рациональную аппроксимацию интервала и затем определить, являются ли его числитель и знаменатель «простыми» (это означает, что знаменатель меньше 5, а отношение не делит 7).

В этой таблице показаны все этапы этого процесса.

Table[
  Module[{compoundInterval,simpleInterval,rationalApprox,denomLeq5,div7,consonant},
    compoundInterval = Power[2, i/12];
    simpleInterval   = 2^Mod[Log2[compoundInterval], 1];
    rationalApprox   = Rationalize[N@simpleInterval, 1/17];
    denomLeq5        = Denominator[rationalApprox]<=5;
    div7             = Denominator[rationalApprox]>1 && rationalApprox\[Divides]7;
    consonant        = FreeQ[1|2|6|10|11][Mod[i,12]];

    InputForm/@{
      i, simpleInterval, rationalApprox, 
      denomLeq5, div7, denomLeq5 && !div7,
      consonant
    }
  ], {i, 0, 12}
]

i   sInterval  ratio   denomLeq5  div7       den&&!div  | consonant?

0   1          1       True       False      True       | True
1   2^(1/12)   17/16   False      False      False      | False
2   2^(1/6)    9/8     False      False      False      | False
3   2^(1/4)    6/5     True       False      True       | True
4   2^(1/3)    5/4     True       False      True       | True
5   2^(5/12)   4/3     True       False      True       | True
6   Sqrt[2]    7/5     True       True       False      | False
7   2^(7/12)   3/2     True       False      True       | True
8   2^(2/3)    8/5     True       False      True       | True
9   2^(3/4)    5/3     True       False      True       | True
10  2^(5/6)    7/4     True       True       False      | False
11  2^(11/12)  11/6    False      False      False      | False
12  1          1       True       False      True       | True

Рациональное приближение лежит в пределах 1/17интервала, потому что это самый большой порог, который различает все 12 равных темперированных интервалов. Мы сопоставляем рациональные числа с шаблоном Rational[a_,b_](или простоa_~_~b_Сначала ), а затем сопоставляем целые числа только с_ .

Это завершается следующей довольно короткой функцией, которая определяет, является ли произвольное отношение частот (больше 1) согласным или диссонантным.

Rationalize[#,1/17]/.{a_~_~b_:>b<=5&&!a∣7,_->True}&       [Fsharp3/C3]     51+9=60
hftf
источник
1
Черт возьми, не говори мне , Mathematica имеет встроенную команду даже для этого ...: D
Рамильи
3

Mathematica, 118 байт

FreeQ[{1,2,6,10,11},Min@Mod[Differences[Min@Position["C|C#|D|D#|E|F|F#|G|G#|A|A#|B"~StringSplit~"|",#]&/@{#,#2}],12]]&


Форма ввода

["ОБЪЯВЛЕНИЕ"]

Выходы

True->Consonant  
False->Dissonant   

спасибо @JonathanFrech -16 байт

J42161217
источник
Просто замечание: вам не нужно выводить строки Consonantи Dissonant. Вы можете вывести любые два значения вместо них (0/1, ... что угодно). Это может сэкономить несколько байтов.
Ramillies
1
Не можете ли вы опустить If[...,0,1]и определить True->Consonant; False->Dissonant?
Джонатан Фрех
1
StringCases["CC#DD#EFF#GG#AA#B",_~~"#"...]- 42 байта
celtschk
1
Кроме того, 2 байта могут быть сохранены путем замены {1,2,6,10,11}на1|2|6|10|11
celtschk
1
@Skyler Смотрите ответ ниже.
hftf
3

Древесный уголь , 30 байт

≔B#A#G#FE#D#C槔o∧⌈ς”⁻⌕ζ⮌θ⌕ζ⮌η

Попробуйте онлайн! Ссылка на подробную версию кода. Выходы 1 для согласного, 0 для диссонанта. Объяснение:

≔B#A#G#FE#D#Cζ                  Store reversed note names in z
                        θ       First input
                       ⮌        Reversed
                     ⌕ζ         Find index in z
                            η   Second input
                           ⮌    Reversed
                         ⌕ζ     Find index in z
                     ⁻          Subtract
               ”o∧⌈ς”           Compressed string 100111011100
              §                 Circularly index
                                Implicitly print
Нил
источник
из любопытства, есть ли мнемоническая причина, по которой глиф ⌕ζиспользуется для «поиска индекса»?
Иона
@Jonah ζ- это переменная, назначенная ранее.
Нил
2

J, 68 байт

[:e.&1 2 6 10 11[:(12| -~/)(<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

объяснение

Простая, не супергольфированная реализация в J:

  • Входные данные даны в виде подробных заметок в штучной упаковке (произведены с использованием вырезки) по порядку

  • Найдите их индексы в диапазоне заметок: (<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

  • Вычтите первое из второго: -~/

  • Возьмите остаток от деления на 12: 12|

  • Проверьте, не является ли это одной из диссонирующих нот: e.&1 2 6 10 11

Попробуйте онлайн!

Ион
источник
2

/// , 90 88 байт

/^/"\///^\/\///C^D/##"E/DD"F/E#"G/FD"A/GD"B/AD"#,#/,"B#^B/#"A#/#"A^G#^G^F#/#"F^E^D#^D/#/

Попробуйте онлайн! (все тестовые случаи одновременно)

  • Поставьте ввод после кода.
  • Разделите названия заметок с ,B# в каждом тестовом примере.
  • Выход ,для согласной, ,#для диссонанта.
  • Поддержка двойных изменений ( ##) или E#в некоторых особых случаях. В противном случае выходные данные ,для согласных, #,для диссонантных (благодаря симметрии по модулю 12)
  • Может обрабатывать несколько тестовых случаев одновременно (если разделены разумно)
  • Строчные буквы печатаются точно.
user202729
источник
2

C (gcc) , 91 байт

g(char*s){return (s[1]&1|2**s&15)*4/5;}f(char*x,char*y){return (1952220<<g(x)>>g(y))&2048;}

вызов: f("A#", "D")

Возвращаемое значение:

  • Согласный: 2048
  • Диссонант: 0

Бонус: функция не чувствительна к регистру.

Попробуйте онлайн!

celtschk
источник
Нет ли двух лишних пробелов в обоих return (s?
Джонатан Фрех
Вы можете попробовать g(char*s){s=(s[1]&1|2**s&15)*4/5;}f(char*x,char*y){x=1952220<<g(x)>>g(y)&2048;} и хорошее решение!
Кейу Ган,
1

Python 2, 125 117 83 78 77 байт

a,b=map("C C#D D#E F F#G G#A A#B".index,input())
print chr(abs(a-b))in""

Где ""в конце на самом деле содержит символы"\x02\x04\x0c\x14\x16"

Попробуйте онлайн!

(+3 потому что я забыл 11 или 22 в списке для начала)

-8 байт от Джонатана Фреха и переход на Python 2 .

-34 байта с предложениями Джонатана Фреха и использованием strиндекса вместо вместо list.

-4 байта от встраивания iи Нил поменял строковое предложение (только -2 действительно, как я забыл ()вокруг генератора)

-5 байт от вставки iи изменения формата ввода

-1 байт от Джонатана Фреха map()и непечатные.

Принимает ввод в одной строке стандартного ввода в формате:

'C','C#'

Trueдиссонирует, Falseсогласен.

Старое объяснение:

i='C C#D D#E F F#G G#A A#B'.index
a,b=input()
print abs(i(a)-i(b))in[2,4,12,20]

Python str.indexвозвращает самый низкий (положительный) начальный индекс соответствующей подстроки, поэтому "ABACABA".index("A") == 0и "ABACABA".index("BA") == 1. По этой причине мы можем поместить имена заметок в строку на одинаковом расстоянии друг от друга, и, пока (например) Aраньше A#, общий Aдоступ не будет проблемой.

i='C C#D D#E F F#G G#A A#B'.index

iтеперь это функция, которая возвращает индекс в 'C C#D D#E F F#G G#A A#B'своем аргументе (имя заметки), который равен 2 * (количество полутонов, с которых нота взята C)

a,b=input()

Python 2 input()(в основном) эквивалентен eval(input())в Python3, поэтому с допустимым вводом формата 'C#','F'(например), a='C#'иb='F'

print abs(i(a)-i(b))in[2,4,12,20]

Если расстояние между первой и второй нотой в строке не равно 2, 4, 12 или 20 (поскольку имена ноты представлены в 2 символа), то интервал будет диссонирующим, выведите True, иначе он будет согласным, выведите False.

pizzapants184
источник
Поскольку формат ввода не является строгим, вы можете использовать eval(input())(13 байт) вместо input().split()(15 байт).
Джонатан Фрех
101 байт
Джонатан Фрех
98 байтов
Джонатан Фрех
79 байтов
Джонатан Фрех
1
Вы можете использовать символы Unicode ( ) вместо строки emtpy.
Джонатан Фрех
1

C (gcc) , 115117 120 байтов

g(char*a){a=*a-65+!!a[1]*(7-*a/70-*a/67);}f(x,y)char*x,*y;{x="(pP$HL<lt<X"[g(x)]*32+"=ZukW-^h1F6"[g(x)]>>g(y)&1;}

Попробуйте онлайн!

Верните 1/0 для созвучия и диссоната. Всегда интересно делать строковые манипуляции с чистым C. Примите ввод какf("A#", "C")

Кейу Ган
источник
0

PowerShell , 107 байт

param($a,$b)[math]::abs(($x=-split'C C# D D# E F F# G G# A A# B').indexof($b)-$x.indexof($a))-in1,2,6,10,11

Попробуйте онлайн!

Выходы Trueдля диссонанта и Falseдля согласного.

Принимает ввод $aи $b, две заметки, в виде строк. Выполняет -splitоперацию в масштабе, которая разделяется на пустые пространства, чтобы создать массив примечаний, сохраняющих это в $x. Находит .indexof $bв этом массиве, вычитает индекс $a, а затем принимает его absабсолютное значение. Проверяет, является ли это число -inдиссонансными диапазонами.

AdmBorkBork
источник
0

SQL, 582 байта

SQL Fiddle

У меня все еще есть кое-что для игры в гольф, но я хотел получить это здесь, прежде чем закончить с этим.

Если ввод в буквенном формате, то поместить эти буквы в таблицу со значениями - это нормально, верно?

CREATE TABLE N(N char(2),v int)
Insert Into N values('A',1),('A#',2),('B',3),('C',4),('C#',5),('D',6),('D#',7),('E',8),('F',9),('F#',10),('G',11),('G#',12);
CREATE TABLE D(D char(9),v int) 
Insert Into D values('C',0),('D',1),('D',2),('C',3),('C',4),('C',5),('D',6);
CREATE FUNCTION I(@A char(2),@B char(2))
RETURNS char(9) as
BEGIN
DECLARE @E int=(SELECT v from N where n=@A),@F int=(SELECT v from N where n=@B)
DECLARE @C char(9) = (SELECT case D when 'D' then 'Dissonant' when 'C' then 'Consonant' END from D where v in(abs(@e-@f),12-abs(@e-@f)))
RETURN isnull(@C,'NotANote')
END
phroureo
источник
0

Perl 5 , 106 байт

("C,C#,D,D#,E,F,F#,G,G#,A,A#,B,"x2)=~/$F[0],(.*?)$F[1],/;$r=(1+($1=~y/,//))%12;say(grep/$r/,(0,3..5,7..9))

Попробуйте онлайн!

Возвращает false для диссонанта, true для согласного.

Xcali
источник