Учитывая два названия нот, вы должны написать программу, которая определяет, является ли интервал, образованный этими двумя нотами, согласным или диссонантным.
Введение
В западной музыке есть только 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 : я попытался упростить это объяснение, насколько я мог. Есть намного больше теории относительно интервалов. Пожалуйста, не ругайте меня за то, что я оставил это.
АПЛ (Дялог) ,
6239 байтИспользует
⎕IO←0
; 0 согласен, 1 диссонирует. Принимает список символов базовой ноты в качестве левого аргумента и список острых символов в качестве правого аргумента.Попробуйте онлайн!
{
…}
Анонимная функция где⍺
левый аргумент и⍵
правый аргумент⎕A[
...]∊'BCGKL'
это lphabet, индексируется в следующем, член строки?⍕#
отформатировать корневое пространство имен (дает острый символ)⍵=
правильные аргументы (символы) равны этому?(
...)+
добавить следующее:'C D EF G A '⍳⍺
индексы левого аргумента в строке-/
разница между этими|
абсолютная величинаисточник
MATL ,
302726 байтВводит две ноты в разные строки. Выходы
0
для согласных,1
для диссонантных.Попробуйте онлайн! Или проверьте все тестовые случаи .
объяснение
Строка из 11 символов
кодирует ноты и диссонирующие интервалы следующим образом.
Сначала программа находит основанные на 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'
мы получим числовой векторкоторый содержит именно диссонантные интервалы, в дополнение к некоторым отрицательным значениям, которые не будут ни полезными, ни вредными. Заметьте, что выбор дополнительных букв
JPIL
в строке'DJEFPGIALBC'
определяет (через последовательные различия) интервалы диссонанса.Чтобы увидеть, являются ли две входные ноты диссонансными, мы берем абсолютную разницу их значений основного тона. Например,
C
иD#
дадут цифры12
и3
соответственно, а абсолютная разница будет9
. Фактическая разница будет равна-9
фактическому интервалу3
(полученному по-9
модулю 12). Но благодаря симметрии, упомянутой выше, мы можем рассмотреть9
вместо3
. Поскольку9
нет в векторе последовательных различий, ноты согласны.источник
JavaScript (ES6),
6864 байтаПринимает заметки в виде двух строк в синтаксисе карри
(a)(b)
. Возвращает0
за диссонанс или1
согласную.Контрольные примеры
Показать фрагмент кода
Отформатировано и прокомментировано
источник
Желе , 26 байт
Монадическая ссылка, принимающая список из двух заметок (в виде списков символов) и возвращающая
0
согласные и1
для диссонирующих.Попробуйте онлайн! или увидеть все входы в тестовом наборе .
Как?
источник
Желе , 31 байт
Попробуйте онлайн!
Wheeeeee 32 байта слишком долго
объяснение
источник
"G#", "A"
(диссонанс) дает разницу,11
которой нет[1,2,6]
.Mathematica, 55 байт
Сопоставьте внутреннюю встроенную
Sound`PitchToNumber
входную информацию (список из двух строк), возьмите абсолютную разницу, затем сопоставьте шаблон для диссонирующих интервалов.Просто для удовольствия (не соревнуясь)
Вот некоторые более короткие функции, которые нарушают ограничение «вы не можете назначать никакие другие имена примечаниям». У элементарного
Music`
пакета есть предопределенные константы примечания (напримерA4 = 440.
) и функцияHertzToCents
(которая может быть введена в игру). Вместо строк мы будем использовать константы примечания в качестве аргументов, но для каждой функции они предоставляются в разном формате.Импорт пакета
<<Music`;
занимает 9 байтов.Эта функция преобразует строку (например
"F#"
) в константу примечания (напримерFsharp3
):Чтобы принять интервалы, превышающие октаву, замените
Abs[…]
наMod[…,12]
.Почему некоторые интервалы считаются диссонансными? Интервал - это соотношение двух частот. Если отношение имеет «простой» числитель и знаменатель, оно имеет тенденцию быть более согласным. В 5-предельной настройке отношения могут быть преобразованы в целочисленные степени только простых чисел, меньших или равных 5. Никакой интервал с одинаковым темпераментом, кроме октавы, не является просто интервалом ; это просто близкие приближения, использующие степени 12-го корня из 2.
Вместо жесткого кодирования того, какие числа интервалов являются диссонансными, мы можем найти рациональную аппроксимацию интервала и затем определить, являются ли его числитель и знаменатель «простыми» (это означает, что знаменатель меньше 5, а отношение не делит 7).
В этой таблице показаны все этапы этого процесса.
Рациональное приближение лежит в пределах
1/17
интервала, потому что это самый большой порог, который различает все 12 равных темперированных интервалов. Мы сопоставляем рациональные числа с шаблономRational[a_,b_]
(или простоa_~_~b_
Сначала ), а затем сопоставляем целые числа только с_
.Это завершается следующей довольно короткой функцией, которая определяет, является ли произвольное отношение частот (больше 1) согласным или диссонантным.
источник
Mathematica, 118 байт
Форма ввода
Выходы
спасибо @JonathanFrech -16 байт
источник
Consonant
иDissonant
. Вы можете вывести любые два значения вместо них (0/1, ... что угодно). Это может сэкономить несколько байтов.If[...,0,1]
и определитьTrue->Consonant; False->Dissonant
?StringCases["CC#DD#EFF#GG#AA#B",_~~"#"...]
- 42 байта{1,2,6,10,11}
на1|2|6|10|11
Древесный уголь , 30 байт
Попробуйте онлайн! Ссылка на подробную версию кода. Выходы 1 для согласного, 0 для диссонанта. Объяснение:
источник
⌕ζ
используется для «поиска индекса»?ζ
- это переменная, назначенная ранее.J, 68 байт
объяснение
Простая, не супергольфированная реализация в J:
Входные данные даны в виде подробных заметок в штучной упаковке (произведены с использованием вырезки) по порядку
Найдите их индексы в диапазоне заметок:
(<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]
Вычтите первое из второго:
-~/
Возьмите остаток от деления на 12:
12|
Проверьте, не является ли это одной из диссонирующих нот:
e.&1 2 6 10 11
Попробуйте онлайн!
источник
/// ,
9088 байтПопробуйте онлайн! (все тестовые случаи одновременно)
,B#
в каждом тестовом примере.,
для согласной,,#
для диссонанта.##
) илиE#
в некоторых особых случаях. В противном случае выходные данные,
для согласных,#,
для диссонантных (благодаря симметрии по модулю 12)источник
C (gcc) , 91 байт
вызов:
f("A#", "D")
Возвращаемое значение:
Бонус: функция не чувствительна к регистру.
Попробуйте онлайн!
источник
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;}
и хорошее решение!Python 2,
125 117 83 7877 байтГде
""
в конце на самом деле содержит символы"\x02\x04\x0c\x14\x16"
Попробуйте онлайн!
(+3 потому что я забыл 11 или 22 в списке для начала)
-8 байт от Джонатана Фреха и переход на Python 2 .
-34 байта с предложениями Джонатана Фреха и использованием
str
индекса вместо вместоlist
.-4 байта от встраивания
i
и Нил поменял строковое предложение (только -2 действительно, как я забыл()
вокруг генератора)-5 байт от вставки
i
и изменения формата ввода-1 байт от Джонатана Фреха
map()
и непечатные.Принимает ввод в одной строке стандартного ввода в формате:
True
диссонирует,False
согласен.Старое объяснение:
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'
своем аргументе (имя заметки), который равен 2 * (количество полутонов, с которых нота взятаC
)Python 2
input()
(в основном) эквивалентенeval(input())
в Python3, поэтому с допустимым вводом формата'C#','F'
(например),a='C#'
иb='F'
Если расстояние между первой и второй нотой в строке не равно 2, 4, 12 или 20 (поскольку имена ноты представлены в 2 символа), то интервал будет диссонирующим, выведите True, иначе он будет согласным, выведите False.
источник
eval(input())
(13 байт) вместоinput().split()
(15 байт).
) вместо строки emtpy.C (gcc) , 115
117120байтовПопробуйте онлайн!
Верните 1/0 для созвучия и диссоната. Всегда интересно делать строковые манипуляции с чистым C. Примите ввод как
f("A#", "C")
источник
PowerShell , 107 байт
Попробуйте онлайн!
Выходы
True
для диссонанта иFalse
для согласного.Принимает ввод
$a
и$b
, две заметки, в виде строк. Выполняет-split
операцию в масштабе, которая разделяется на пустые пространства, чтобы создать массив примечаний, сохраняющих это в$x
. Находит.indexof
$b
в этом массиве, вычитает индекс$a
, а затем принимает егоabs
абсолютное значение. Проверяет, является ли это число-in
диссонансными диапазонами.источник
Python 2 , 68 байт
Попробуйте онлайн!
Выходы:
1
диссонирует,0
согласен.источник
SQL, 582 байта
SQL Fiddle
У меня все еще есть кое-что для игры в гольф, но я хотел получить это здесь, прежде чем закончить с этим.
Если ввод в буквенном формате, то поместить эти буквы в таблицу со значениями - это нормально, верно?
источник
Perl 5 , 106 байт
Попробуйте онлайн!
Возвращает false для диссонанта, true для согласного.
источник