Фортепіанні акорди на білих клавішах


9

Попередня історія [що не відповідає дійсності]

Фортепіано встановлено так:

! [http://www.piano-lessons-made-simple.com/images/2-Octave-Labled.gif

Проте на моєму піаніно всі чорні клавіші зламані!

Я все ще хочу вміти грати деякі акорди на моєму зламаному фортепіано.

У музиці акорд - це група нот, які відтворюються разом. Щоб дозволити введення акордів, спершу визначу, що таке півтон.

Що таке півтон?

Півтон - найменша відстань у західній музиці. Якщо ви подивитеся на верхню частину фортепіано, то побачите, що зазвичай можна переходити від чорної клавіші до білої клавіші, або навпаки; однак між Bі Cта Eі Fне існує чорного ключа.

Що таке акорд?

Для цілей цього виклику ми визначаємо акорд як купу нот з певною кількістю півтонів між ними. Наприклад, візьмемо участь у 4-3-3акорді, який починається C(для музичних людей це акорд V 7 фа мажор). Ми починаємо з C. Ми розраховуємо на 4 півтони: C#, D, D#, E. Наступне зауваження E, і ми розраховуємо 3 півтони вгору після цього: F, F#, G. Наступне зауваження G, і ми розраховуємо 3 півтони вгору після цього: G#, A, Bb. Отже, ми отримуємо C-E-G-Bb. Так! Але зачекайте ... Bbце чорний ключ, і вони зламані ... Однак, якщо ми почнемо з того G, ми отримаємо G-B-D-F! Так!

Вхідні дані

Введення подається у вигляді списку цілих чисел у будь-якому розумному форматі. Це являє собою акорд, як описано вище.

Вихідні дані

На виході повинен бути список приміток, на яких мені потрібно почати використовувати лише білі клавіші. Це також може бути просто рядок з усіх до 7 нот, оскільки всі ключові імена будуть одним символом. Ви також маєте змогу обробляти порожній вихід.

Випробування

input -> output // comments
4 3 -> C F G // this is a major triad
3 4 -> D E A // this is a minor triad
4 3 3 -> G // this is the major-minor seventh chord
3 3 3 -> [empty output] // this is the diminished-diminished seventh chord. All of them use black keys
4 4 -> [empty output] // this is an augmented triad
3 3 -> B // this is a diminished triad
1 -> B E // this is just a minor second
11 -> C F // this is just a major seventh

Інші характеристики

  • Стандартні лазівки заборонені
  • Можна припустити, що вхід має принаймні одне ціле число
  • Ви можете припустити, що всі цілі числа невід'ємні і менше 12 (тому що фортепіано повторює кожні 12 нот)
  • Вихід може бути в будь-якому порядку

Критерії виграшу

Найменше дійсне подання станом на 15 квітня буде прийнято.


Ми можемо вважати, що "негативні та менше 12" - чи не повинні бути "позитивними та меншими або рівними 12"?
Джонатан Аллан

@JonathanAllan В принципі різниці немає; мій метод дозволяє створити Ідеальний Унісон, але не Ідеальну октаву; ваш навпаки. Теоретично ваше обмеження може мати більше сенсу, але я думаю, що я, мабуть, не повинен його змінювати, оскільки відповіді вже є, і це не змінює виклик принципово.
HyperNeutrino

Відповіді:


3

Желе , 25 байт

236ḃ2ṙЀ7+\€Ṭ
+\ịþ¢Ạ€TịØA

Спробуйте в Інтернеті! або побачити тестовий набір

Як?

236ḃ2ṙЀ7+\€Ṭ - Link 1, white-note-offsets: no arguments
236ḃ2         - 236 in bijective base 2 [2, 2, 1, 2, 2, 1, 2] - semitones G->A, A->B ...
     ṙЀ7     - rotate left by, mapped over [1,2,3,4,5,6,7] - i.e. as above for each
                    starting white key (1st one A->B,B->C,...; 2nd B->C,C->D,...; etc)
         +\€  - reduce €ach with addition - i.e. absolute number of semitones: [[2,3,5,7,8,10,12],[1,3,5,6,8,10,12],[2,4,5,7,9,11,12],[2,3,5,7,9,10,12],[1,3,5,7,8,10,12],[2,4,6,7,9,11,12],[2,4,5,7,9,10,12]]
            Ṭ - untruth (vectorises) - make lists with 1s at those indexes: [[0,1,1,0,1,0,1,1,0,1,0,1],[1,0,1,0,1,1,0,1,0,1,0,1],[0,1,0,1,1,0,1,0,1,0,1,1],[0,1,1,0,1,0,1,0,1,1,0,1],[1,0,1,0,1,0,1,1,0,1,0,1],[0,1,0,1,0,1,1,0,1,0,1,1],[0,1,0,1,1,0,1,0,1,1,0,1]]

+\ịþ¢Ạ€TịØA - Main link: list of semitone gap integers (even negatives will work)
+\          - reduce by addition - gets the absolute semitone offsets needed
    ¢       - last link (1) as a nilad
   þ        - outer product with:
  ị         -     index into - 7 lists, each with 1s for white and 0s for black keys hit
                      note that indexing is modular and all the lists are length 12
                      so any integer is a valid absolute offset, not just 0-11 inclusive
     Ạ€     - all truthy for €ach - for each get a 1 if all keys are white ones, else 0
       T    - truthy indexes - get the valid starting white keys as numbers from 1 to 7
        ị   - index into:
         ØA -     the uppercase alphabet

6

MATL , 31 байт

Дякую Джонатану Аллану за виправлення.

'BAGFEDC'"GYs12X\110BQX@YSYsm?@

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

Шаблон 2 2 1 2 2 2 1визначає інтервали між послідовними білими клавішами. Програма використовує цикл, який застосовує всі циклічні зрушення до цього основного шаблону, щоб перевірити кожну клавішу як потенційну найменшу ноту вхідного акорда. За кожну зміну виходить сукупна сума шаблону. Наприклад, для, Bяк потенційно найнижчої ноти, шаблон зміщено до 1 2 2 1 2 2 2його сукупної суми 1 3 5 6 8 10 12.

Тепер, щоб побачити, чи може це підтримувати 4 3 3акорд, ми обчислимо сукупну суму інтервалів акордів, яка є 4 7 10; зменшити його за допомогою модуля 12 на основі 1 (інтервал, який 14би дав 2); і перевірте, чи всі ці числа є членами дозволених значень 1 3 5 6 8 10 12. У цьому прикладі це не так. Якби це було так, ми вивели б лист B.

Відповідність між циклічними зсувами та вихідними літерами визначається рядком 'BAGFEDC'. Це вказує, що 'B'(перший символ) відповідає циклічному зсуву на 1; 'A'(другий символ) відповідає циклічному зсуву 2тощо.

'BAGFEDC'  % Push this string
"          % For each character from the string
  G        %   Push input array
  Ys       %   Cumulative sum
  12X\     %   1-based modulo 12, element-wise (1,12,13,14 respectively give 1,12,1,2)
  110BQ    %   Push 110, convert to binary, add 1 element-wise: gives [2 2 1 2 2 2 1]
  X@       %   Push current iteration index, starting at 1
  YS       %   Cyclic shift to the right by that amount
  Ys       %   Cumulative sum
  m        %   Ismember. Gives an array of true of false entries
  ?        %   If all true
    @      %     Push current character
           %   End (implicit)
           % End (implicit)
           % Display (implicit)

5

Mathematica, 110 байт (кодування ISO 8859-1)

±i_:=#&@@@Select["A#BC#D#EF#G#"~StringTake~{Mod[#,12,1]}&/@#&/@(Accumulate[i~Prepend~#]&/@Range@12),FreeQ@"#"]

Визначає функцію одинарної функції, яка ±приймає список цілих чисел як вхідні (фактично немає обмежень щодо розміру чи ознак цілих чисел) та повертає список рядків з одним символом. Наприклад, ±{3,4}повернення {"A","D","E"}.

"A#BC#D#EF#G#"~StringTake~{Mod[#,12,1]}&/@#- це функція, яка перетворює список цілих чисел у відповідні імена нот, за винятком #будь-якої чорної клавіші. Це застосовується до кожного елемента Accumulate[i~Prepend~#]&/@Range@12, який формує список значень примітки зі списку вхідних списків інтервалів примітки, починаючи з кожної можливої ​​ноти від 1 до 12. Ми фільтруємо всі такі списки імен нотаток, які містять "#"використання Select[...,FreeQ@"#"], а потім повернути першу примітку в кожному списку, що залишився, використовуючи #&@@@.


Приємного подання!
HyperNeutrino

Питання: Чи використовує Mathematica власну байтову систему? Це 110 символів, але в UTF-8 це 111 байт через +/-символ.
HyperNeutrino

Ви можете повністю зняти завдання і просто "неявно повернути" функцію.
wizzwizz4

@ wizzwizz4: Я ​​виявив, що мені потрібно назвати змінну, Accumulate[i~Prepend~#]&тому що в іншому випадку відбудеться зіткнення кривої. Не соромтеся знайти вирішення, хоча!
Грег Мартін

@HyperNeutrino: ви праві, що UTF-8 є стандартним кодуванням, але Mathematica може (як правило) функціонувати і в кодуванні ISO 8859-1. Я це зазначив у дописі.
Грег Мартін

3

Python 2, 159 155 байт

(Опублікуйте це, переконавшись, що дійсне подання коротше, ніж це)

import numpy
s='C.D.EF.G.A.B'
def k(y):return lambda x:s[(x+y)%12]
for i in range(12):
    if s[i]!='.'and'.'not in map(k(i),numpy.cumsum(input())):print s[i]

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

-4 байти, видаливши непотрібну змінну


3

JavaScript (ES6), 72 71 68 байт

a=>[..."C1D1EF1G1A1B"].filter((c,i,b)=>!+c>a.some(e=>+b[i+=e,i%12]))

Прокручуйте кожну клавішу, опускаючи чорні клавіші, а потім перевіряєте, чи сукупна сума півтонів ніколи не потрапляє на чорний ключ.

Редагувати: збережено 3 байти завдяки @Arnauld.


4
Читання ?! Ви впевнені, що знаходитесь на правильному сайті? :-)
wizzwizz4
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.