Accords de piano sur les touches blanches

9

Backstory [ce qui n'est pas vrai]

Un piano est configuré comme ceci:

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

Cependant, sur mon piano, toutes les touches noires sont cassées!

Je veux quand même pouvoir jouer des accords sur mon piano cassé.

En musique, un accord est un groupe de notes jouées ensemble. Pour permettre la saisie d'accords, je vais d'abord définir ce qu'est un demi-ton.

Qu'est-ce qu'un demi-ton?

Un demi-ton est la plus petite distance dans la musique occidentale. Si vous regardez la partie supérieure du piano, vous voyez que vous pouvez généralement passer d'une touche noire à une touche blanche, ou vice versa; cependant, entre Bet Cet Eet Fil n'y a pas de clé noire.

Qu'est-ce qu'un accord?

Pour les besoins de ce défi, nous définissons un accord comme un ensemble de notes avec un certain nombre de demi-tons entre elles. Par exemple, prenons un 4-3-3accord avec un accord commençant C(pour les musiciens, il s'agit d'un accord V 7 en fa majeur). Nous commençons à C. Nous comptons jusqu'à 4 demi - tons: C#, D, D#, E. La note suivante est E, et nous comptons 3 demi - tons après: F, F#, G. La note suivante est G, et nous comptons 3 demi - tons après: G#, A, Bb. Donc, nous obtenons C-E-G-Bb. Yay! Mais attendez ... Bbest une clé noire et ceux-ci sont cassés ... Cependant, si nous partons de G, nous obtenons G-B-D-F! Yay!

Contribution

L'entrée est donnée sous la forme d'une liste d'entiers dans n'importe quel format raisonnable. Cela représente l'accord tel que décrit ci-dessus.

Production

La sortie devrait être une liste de notes sur lesquelles je ne peux commencer qu'à utiliser des touches blanches. Il peut également s'agir simplement d'une chaîne de 7 notes au maximum, car tous les noms clés seront composés d'un seul caractère. Vous devez également pouvoir gérer une sortie vide.

Cas de test

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

Autres spécifications

  • Échappatoires standard interdites
  • Vous pouvez supposer que l'entrée a au moins un entier
  • Vous pouvez supposer que tous les nombres entiers sont non négatifs et inférieurs à 12 (car le piano répète toutes les 12 notes)
  • La sortie peut être dans n'importe quel ordre

Critères gagnants

La soumission valide la plus courte au 15 avril sera acceptée.

HyperNeutrino
la source
Nous pouvons supposer "non négatif et inférieur à 12" - cela ne devrait-il pas être "positif et inférieur ou égal à 12"?
Jonathan Allan
@JonathanAllan Fondamentalement, il n'y a pas de différence; ma méthode permet une parfaite unisson mais pas une octave parfaite; vice-versa. Théoriquement, votre restriction pourrait avoir plus de sens mais je pense que je ne devrais probablement pas la changer car il y a déjà des réponses et cela ne change pas fondamentalement le défi.
HyperNeutrino

Réponses:

3

Gelée , 25 octets

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

Essayez-le en ligne! ou voir une suite de tests

Comment?

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
Jonathan Allan
la source
6

MATL , 31 octets

Merci à Jonathan Allan pour une correction.

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

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

Le motif 2 2 1 2 2 2 1spécifie les intervalles entre les touches blanches consécutives. Le programme utilise une boucle qui applique tous les décalages cycliques à ce modèle de base, afin de tester chaque touche en tant que note la plus basse potentielle de l'accord d'entrée. Pour chaque quart de travail, la somme cumulée du motif est obtenue. Par exemple, pour la Bnote la plus basse potentielle, le motif a été déplacé vers 1 2 2 1 2 2 2et sa somme cumulée est 1 3 5 6 8 10 12.

Maintenant, pour voir si cela peut supporter un 4 3 3accord, nous calculons la somme cumulée des intervalles d'accord, qui est 4 7 10; le réduire via le modulo 12 basé sur 1 (un intervalle de 14donnerait 2); et vérifiez si ces nombres sont tous membres des valeurs autorisées 1 3 5 6 8 10 12. Ce n'est pas le cas dans cet exemple. Si tel avait été le cas, nous publierions la lettre B.

La correspondance entre les décalages cycliques et les lettres de sortie est définie par la chaîne 'BAGFEDC'. Cela indique que 'B'(premier caractère) correspond à un décalage cyclique de 1; 'A'(deuxième caractère) correspond à un décalage cyclique de 2etc.

'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)
Luis Mendo
la source
5

Mathematica, 110 octets (codage ISO 8859-1)

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

Définit une fonction unaire ±prenant une liste d'entiers en entrée (aucune restriction sur la taille ou les signes des entiers, en fait) et retourne une liste de chaînes à un caractère. Par exemple, ±{3,4}renvoie{"A","D","E"} .

"A#BC#D#EF#G#"~StringTake~{Mod[#,12,1]}&/@#est une fonction qui transforme une liste d'entiers en noms de note correspondants, sauf qu'elle #représente toute touche noire. Ceci est appliqué à chaque élément de Accumulate[i~Prepend~#]&/@Range@12, qui établit une liste de valeurs de note à partir de la liste d'entrée de liste des intervalles de note, en commençant par chaque note possible de 1 à 12. Nous filtrons toutes les listes de noms de notes qui contiennent "#"using Select[...,FreeQ@"#"], puis retourner la première note de chaque liste restante en utilisant #&@@@.

Greg Martin
la source
Belle soumission!
HyperNeutrino
Question: Mathematica utilise-t-il son propre système d'octets? C'est 110 caractères mais en UTF-8 c'est 111 octets à cause du +/-symbole.
HyperNeutrino
Vous pouvez supprimer complètement l'affectation et simplement "renvoyer implicitement" une fonction.
wizzwizz4
@ wizzwizz4: J'ai trouvé que je devais nommer la variable Accumulate[i~Prepend~#]&car sinon il y aurait un affrontement curry. N'hésitez pas à trouver une solution de contournement!
Greg Martin
@HyperNeutrino: vous avez raison de dire que UTF-8 est l'encodage standard, mais Mathematica peut (généralement) fonctionner également avec l'encodage ISO 8859-1. Je l'ai noté dans le post.
Greg Martin
3

Python 2, 159 155 octets

(Publier ceci après vous être assuré qu'il existe une soumission valide plus courte que celle-ci)

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]

À peu près juste la solution triviale. Entrées sous forme de liste d'entiers et de sorties avec chaque caractère sur une ligne individuelle.

-4 octets en supprimant une variable inutile

HyperNeutrino
la source
3

JavaScript (ES6), 72 71 68 octets

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

Boucle à travers chaque touche en omettant les touches noires, puis en vérifiant que la somme cumulée des demi-tons n'atteint jamais une touche noire.

Edit: sauvé 3 octets grâce à @Arnauld.

Neil
la source
4
Lisibilité?! Êtes-vous sûr d'être sur le bon site? :-)
wizzwizz4