Musique: Quel est le nom de cet accord?

9

C'est l'inverse de la musique: qu'y a-t-il dans cet accord? , qui consiste à imprimer les notes dans un accord donné. Cette fois, l'entrée est une liste de notes dans un accord, et votre tâche consiste à sortir de quel accord il s'agit.

Votre programme doit prendre en charge les accords triadiques suivants. Des exemples sont donnés avec la racine C. Les accords avec d'autres racines sont les mêmes accords avec toutes les notes tournées, donc C deviendra cette note fondamentale, par exemple Dmaj se compose de D, F # et A.

        C C#D D#E F F#G G#A A#B
          Db  Eb    Gb  Ab  Bb
Cmaj    C       E     G
Cm      C     D#      G
Caug    C       E       G#
Cdim    C     D#    F#
Csus4   C         F   G
Csus2   C   D         G

Notez que Caug est identique à Eaug et G # aug, et Csus4 est identique à Fsus2. Vous pouvez sortir l'un ou l'autre mais il y a un bonus si vous les sortez tous.

Et les septièmes accords pour le bonus sont répertoriés dans le tableau suivant:

        C C#D D#E F F#G G#A A#B
          Db  Eb    Gb  Ab  Bb
C7      C       E     G     A#
Cm7     C     D#      G     A#
Cmmaj7  C     D#      G       B
Cmaj7   C       E     G       B
Caug7   C       E       G#  A#
Cdim7   C     D#    F#    A

Règles

  • Vous pouvez écrire soit un programme complet soit une fonction.
  • L'entrée est une liste de notes, séparées par un espace ou un autre caractère pratique. Il peut également s'agir d'un tableau de chaînes (s'il prend l'entrée d'un argument de fonction) ou de la représentation sous forme de chaîne d'un tel tableau.
  • L'entrée n'a pas besoin d'être dans un ordre spécifique.
  • Il peut y avoir des notes en double dans l'entrée. Ils doivent être traités de la même manière qu'il n'y en a qu'un seul.
  • La sortie est le nom de l'accord. Dans le cas où il affichera plusieurs noms, la même règle de saisie s'applique.
  • Si l'entrée n'est pas un accord pris en charge, vous devez imprimer les notes telles quelles. Votre programme peut également prendre en charge d'autres accords non répertoriés dans les tableaux ci-dessus (ce qui est valide mais sans bonus).
  • Vous pouvez utiliser d' autres notations répertoriées dans l'article Wikipedia . Mais si vous choisissez le Cdo majeur, vous devez ajouter un préfixe lisible par l'homme dans les deux cas pour distinguer un accord avec une seule note.
  • Vous ne pouvez pas utiliser de fonctions intégrées pour cette tâche (le cas échéant).
  • C'est du code-golf. Le code le plus court en octets gagne.

Exemples

  • Entrée: C D# Gsortie: Cm.
  • Entrée: C Eb Gsortie: Cm.
  • Entrée: C Eb F#sortie: Cdim.
  • Entrée: F A C#sortie: Faug, Aaug, C#aug, Dbaugou Faug Aaug C#aug, Faug Aaug Dbaugdans un ordre quelconque.
  • Entrée: F D F F F F A A Fsortie: Dm.
  • Entrée: C Dsortie: C D.

Bonus

  • -30 s'il les imprime tous s'il y a plus d'une interprétation (pour aug, sus4 / sus2 et dim7).
  • -70 s'il prend également en charge les accords de septième.
  • -200 s'il accepte l'entrée MIDI et imprime chaque accord qu'il a reçu. Notez que les notes ne doivent pas commencer ou se terminer en même temps. Vous décidez de ce qui se passe dans les états intermédiaires (tant qu'il ne plante pas ou ne cesse pas de fonctionner). Vous pouvez supposer qu'il n'y a pas de notes dans les canaux de percussion (ou qu'il n'y a qu'un seul canal si cela vous convient). Il est recommandé de fournir également une version texte (ou tableau) pour les tests, surtout si elle dépend de la plate-forme.
jimmy23013
la source
L'entrée peut-elle avoir des plats ou utilise-t-elle uniquement Sharp? Les notes telles que B # doivent-elles être traitées?
feersum
@feersum Il peut avoir des appartements (sauf si vous réclamez le bonus de -200). Ajout de quelques exemples. Vous n'avez pas besoin de gérer B#, Cbetc.
jimmy23013
Vous dites Csus4 is the same as Gsus2. Je pense que tu veux dire Csus2 is the same as Gsus4, n'est-ce pas?
Gareth
@Gareth ... Oui. Fixé.
jimmy23013

Réponses:

2

Caractère Pyth 190 - 30 - 70 = 90

=Q{cQdL+x"C D EF G A B"hb&tlbt%hx" #b"eb3FZQJx[188 212 199 213 200 224 2555 2411 2412 2556 2567 2398)u+*G12hHSm%-dyZ12mykQ0IhJ+Z@c"sus2 maj dim aug m sus4 7 m7 mmaj7 maj7 aug7 dim7"dJ=T0;ITQ

Pas vraiment content avec ça. Accords codés en dur utilisés.

Usage:

Essayez-le ici: Pyth Compiler / Executor . Désactivez le mode de débogage et utilisez-le "C D# G"comme entrée.

Explication:

Première préparation:

=Q{cQd
   cQd  split chord into notes "C D# G" -> ["C", "D#", "G"]
  {     set (eliminate duplicates)
=Q      Q = ...

Puis une fonction qui convertit les notes en entier

L+x"C D EF G A B"hb&tlbt%hx" #b"eb3
defines a function g(b),
  returns the sum of 
     index of "D" in "C D EF G A B"
     and the index of "#" in " #b" 
       (if b than use -1 instead of 2)

Ensuite, pour chaque note, déplacez la coordonnée et recherchez-la dans un tableau

FZQJx[188 ...)u+*G12hHSm%-dyZ12mykQ0IhJ+Z@c"sus2 ..."dJ=T0;ITQ
               implicit T=10
FZQ            for note Z in chord Q:
   mykQ         map each note of Q to it's integer value
   m%-dyZ12     shift it by the integer value of Z modulo 12 
   S            sort it
   u+*G12hH 0   convert it to an integer in base 12
   x[188 ...)   look it up in the list (-1 if not in list)
   J            and store the value in J

   IhJ               if J>=0:
   +Z@c"sus2 ..."dJ   print the note Z and the chord in the list
=T0                   and set T=0
;            end loop
ITQ          if T:print chord (chord not in list)
Jakube
la source
2

Perl 5: 183 - 100 = 83

Edit: J'ai réussi à couper quelques caractères supplémentaires, j'ai donc également modifié les noms d'accords comme dans la solution Python, afin que je puisse faire semblant un instant que je dirige.

#!perl -pa
for$z(0..11){$x=0;$x|=1<<((/#/-/b/+$z+1.61*ord)%12or$o=$_)for@F;$x-/\d+_?/-$_*4||push@r,$o.$'
for qw(36M 34- 68+ 18o 40sus2 33sus4 292_7 290-7 546-M7 548M7 324+7 146o7)}$_="@r
"if@r

Exemple:

$ perl chord.pl <<<"C D# G"
C-
nutki
la source
0

Python 2, 335 octets - 30 - 70 = 235

Première tentative sur un golf légèrement plus long, donc je risque de manquer quelques tours évidents.

def f(s,N="C D EF G A B",r=range,u=1):
 for i in r(12):
  for t in r(12):
   if(set((N.find(n[0])+" #".find(n[1:]))%12for n in s.split())==set(map(lambda n:(int(n,16)+i)%12,"0"+"47037048036057027047A37A37B47B48A369"[3*t:3*t+3]))):print(N[i],N[i+1]+"b")[N[i]==" "]+"M - + o sus4 sus2 7 -7 -M7 M7 +7 o7".split()[t];u=0
 if(u):print s

Commentaires:

  • J'ai utilisé des noms d'accords alternatifs de la page Wiki (voir la fin de la longue ligne) pour économiser de l'espace.
  • Les accords sont représentés par 3 décalages hexagonaux chacun (0 n'est pas requis mais inclus pour les triades pour les aligner).
  • "#". find (n [1:]) fonctionne car "#". find ("b") est -1 et "#". find ("") est 0.

Exemple de sortie

>>> f("C D# G")
C-
>>> f("C Eb G")
C-
>>> f("C Eb F#")
Co
>>> f("F A C#")
Db+
F+
A+
>>> f("F D F F F F A A F")
D-
>>> f("C D")
C D
>>> f("C Eb Gb A")
Co7
Ebo7
Gbo7
Ao7
Uri Granta
la source