930 год, и у Григорианской Церкви есть проблема. У них тысячи страниц музыкального пения, но проблема в том, что все ноты были просто брошены в кучу, вместо того, чтобы иметь какую-либо реальную систему организации:
Изображение пользователя gamerprinter в Гильдии картографов .
Церкви нужно организовать все ноты, поэтому они наняли средневекового инженера-программиста, чтобы написать программу, чтобы организовать ее для них. Вы - инженер по программному обеспечению, который был нанят. Тем не менее, процесс компиляции в средневековье вовлекает программу, написанную на бумаге командой медленных библейских писцов. Чтобы уменьшить время, необходимое команде сценаристов для компиляции вашего кода, вы должны сделать программу как можно меньше.
Церковь хочет, чтобы музыка пения была организована исходя из музыкальной гаммы, в которой они написаны. Вся музыка пения Церкви написана в дорических масштабах . Учитывая ноты определенного музыкального произведения, ваша программа выведет шкалу Дориана, в которой она находится. Здесь я объясню, что такое шкала Дориана. Если вы уже знаете, вы можете пропустить этот раздел.
В любой мелодии 12 возможных нот. Вот они в порядке:
C C# D D# E F F# G G# A A# B
Полутона (представлено с использованием S
) является приращение на один шаг вправо, обтекание (так полутон вверх от B будет обратно в C). Тональный сигнал (представлен с использованием T
) два полутона. Например, полутон вверх от F # будет G. Тон вверх от F # будет G #.
Чтобы создать шкалу Дориана, мы начинаем с любой заметки в списке, а затем перемещаемся вверх по следующему шаблону, перечисляя встречающиеся заметки:
T, S, T, T, T, S
Пример. Я начинаю с А. Примечания моей дорианской шкалы становятся:
A
B (up a tone)
C (up a semitone)
D (up a tone)
E (up a tone)
F# (up a tone)
G (up a semitone)
Шкала имеет ноты A, B, C, D, E, F # и G. Так как я начал с А, мы называем это Дориан масштаба в . Таким образом, существует 12 различных шкал Дориана, каждая из которых названа в честь записки, с которой они начали. Каждый из них использует один и тот же шаблон тонов и полутонов, только начиная с другой позиции. Если мое объяснение не является последовательным, вы также можете обратиться к Википедии .
Ввод программы может быть получен из того, что подходит для вашей программы (например, STDIN, аргумент командной строки, raw_input()
). Это может быть предварительно не инициализировано в переменной. На входе будет список нот, разделенных запятыми, представляющих мелодию произведения. Там могут быть повторные заметки. На входе всегда будет достаточно разных заметок, чтобы можно было окончательно определить масштаб произведения. Пример ввода:
B,B,D,E,D,B,A,G#,A,G#,E,D,F#,E,F#,E,F#,G#,A
Выходные данные программы должны быть строкой Dorian scale in X
, где X - начальная нота шкалы. Выходные данные примера ввода:
Dorian scale in B
Сравнивая это с дорианской шкалой в B ( B C# D E F# G# A
), мы видим, что все ноты мелодии находятся в пределах этой шкалы. Примечание C # в этом случае не используется. Однако есть достаточно примечаний, чтобы однозначно идентифицировать Б. Дориана как правильный ключ. Никакая другая шкала Дориана не подходит, потому что независимо от того, какую другую шкалу мы пробуем, всегда есть хотя бы одна нота мелодии, которая не принадлежит этой шкале.
Это код гольф, поэтому выигрывает вход с кратчайшим количеством символов. Задайте в комментариях, если у вас есть вопросы.
Ответы:
CJam - 61
Попробуйте это на http://cjam.aditsu.net/
источник
С
171146Разбирать строки в C не так просто, поэтому я выбрал более математический подход.
Я пользуюсь Кругом Пятых. Если мы упорядочим ноты в следующем порядке, основываясь на подсчете 7 полутонов за раз (известный как «пятый»), мы обнаружим, что все ноты, разрешенные в любом данном масштабе, образуют последовательный блок из 7 нот и все запрещенные ноты образуют последовательный блок из 5 нот.
(это круг, он оборачивается
F
в конце.)Положение натуральной ноты в приведенной выше последовательности можно рассчитать как
(ASCII code) * 2 % 7
. Затем, если следующий символ нечетный (применяется,#
но не запятая, пробел или нулевой байт), мы добавляем 7, чтобы сделать его резким. Мы храним растровое изображение заметок, которые были использованы.Число
243
(двоичное11111000
) соответствует примечаниям, запрещенным по шкале A # Dorian. Я умножил это(1<<12)+1=4097
на магическое число1016056
. Это смещение прав для проверки (путем ANDing), содержит ли мелодия запрещенные ноты для каждой из 12 шкал по очереди. Если мелодия не содержит запрещенных нот, шкала печатается.Для вывода нам нужно напечатать имя масштаба, закодированное в обратном порядке с циклом пятых выше, помните, что мы идем назад, потому что мы меняем права.) Последовательность ASCII
ADGCFBEADGCF
генерируется с помощью65+i*3%7
. Для первых пяти из них острый также должен быть напечатан.Код без правил
Недопустимое поведение при вводе: если недостаточно данных для однозначного определения масштаба, будут выведены все возможные масштабы. Если указана невозможная комбинация заметок, она ничего не выдаст. Примечания должны быть разделены запятой (или другим непробельным символом с четным кодом ASCII <= 64). Пробелы нельзя использовать, поскольку все после первого пробела будет считаться другим аргументом. Коды ASCII> 64 будут интерпретироваться как примечания описанным способом.
источник
Хаскелл - 152
Ungolfed
источник
Python 2 - 177 символов
Это не так уж и мало, но я нахожу для Python радостью написать несколько вложенных циклов в одну строку, даже если не игра в гольф. К сожалению, мне пришлось поместить оператор ввода в отдельной строке, чтобы он не выполнялся более одного раза.
Я не использую Python 3, но я считаю, что это редкий случай, когда для оператора print не нужно больше символов. Поскольку там
print
есть функция, я мог бы компенсировать необходимость использования скобок с помощью*
оператора распаковки списка для замены последнего[0]
.источник
input
наraw_input
и сохранить 4 -х символов в Python 3.Рубин - 132
Ввод из аргументов командной строки.
например
ruby dorianscale.rb B,B,D,E,D,B,A,G#,A,G#,E,D,F#,E,F#,E,F#,G#,A
Попробуйте это на: ideone
источник
Хаскель - 140
Используйте свойство Circle of Fifths, представленное @steveverrill. Если мы позволим
circle0 = words "C G D A E B F# C# G# D# A# F"
иcircle = circle0 ++ circle0
, то мы можем построить все шкалы, сделав последовательные 7 примечаний вcircle
.В каждой построенной таким образом
scale !! 3
шкале 4-й элемент является именем шкалы.Код
Ungolfed
источник
Scala,
130128127Используя метод круга пятых. Ввод из аргументов командной строки т.е.
источник