Música: ¿Cómo se llama este acorde?

9

Este es el reverso de la música: ¿qué hay en este acorde? , que es imprimir las notas en un acorde dado. Esta vez, la entrada es una lista de notas en un acorde, y su tarea es dar salida a ese acorde.

Su programa debe admitir los siguientes acordes triádicos. Se dan ejemplos con la raíz C. Los acordes con otras raíces son los mismos acordes con todas las notas giradas para que C se convierta en esa nota raíz, por ejemplo, Dmaj consiste en D, F # y 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

Tenga en cuenta que Caug es lo mismo que Eaug y G # aug, y Csus4 es lo mismo que Fsus2. Puede generar cualquiera de los dos, pero hay una bonificación si los genera a todos.

Y los séptimos acordes para la bonificación se enumeran en la siguiente tabla:

        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

Reglas

  • Puede escribir un programa completo o una función.
  • La entrada es una lista de notas, separadas por un espacio u otro carácter conveniente. También puede ser una matriz de cadenas (si toma información del argumento de la función) o la representación de cadena de dicha matriz.
  • La entrada no tiene que estar en un orden específico.
  • Puede haber notas duplicadas en la entrada. Deben ser tratados de la misma manera, ya que solo hay uno de ellos.
  • La salida es el nombre del acorde. En caso de que genere varios nombres, se aplica la misma regla para la entrada.
  • Si la entrada no es un acorde compatible, debe imprimir las notas tal cual. Su programa también puede admitir otros acordes que no figuran en las tablas anteriores (que es válido pero no tiene bonificación).
  • Puede usar otras anotaciones enumeradas en el artículo de Wikipedia . Pero si elige Cpara Do mayor, debe agregar un prefijo legible para humanos en cualquier caso para distinguir un acorde con una sola nota.
  • No puede usar funciones integradas para esta tarea (si hay alguna).
  • Este es el código de golf. El código más corto en bytes gana.

Ejemplos

  • Entrada: C D# GSalida: Cm.
  • Entrada: C Eb GSalida: Cm.
  • Entrada: C Eb F#Salida: Cdim.
  • Entrada: F A C#Salida: Faug, Aaug, C#aug, Dbaugo Faug Aaug C#aug, Faug Aaug Dbaugen cualquier orden.
  • Entrada: F D F F F F A A FSalida: Dm.
  • Entrada: C DSalida: C D.

Bonos

  • -30 si los imprime a todos si hay más de una interpretación (para aug, sus4 / sus2 y dim7).
  • -70 si también admite séptimos acordes.
  • -200 si acepta entrada MIDI e imprime cada acorde que ha recibido. Tenga en cuenta que las notas no tienen que comenzar o finalizar al mismo tiempo. Usted decide qué sucede en los estados intermedios (siempre que no se bloquee o deje de funcionar). Puede suponer que no hay notas en los canales de percusión (o solo hay un canal si es conveniente). Se recomienda también proporcionar una versión de texto (o matriz) para la prueba, especialmente si depende de la plataforma.
jimmy23013
fuente
¿Puede la entrada tener planos o solo está usando Sharp? ¿Se deben manejar notas como B #?
fiesta
@feersum Puede tener pisos (a menos que reclames la bonificación de -200). Se agregaron algunos ejemplos. No es necesario junto con el mango B#, Cbetc.
jimmy23013
Usted dice Csus4 is the same as Gsus2. Creo que quieres decir, Csus2 is the same as Gsus4¿no?
Gareth
@Gareth ... Sí. Fijo.
jimmy23013

Respuestas:

2

Pyth 190 carácter - 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

No muy contento con eso. Utiliza acordes codificados.

Uso:

Pruébelo aquí: Pyth Compiler / Executor . Deshabilite el modo de depuración y úselo "C D# G"como entrada.

Explicación:

Primero algo de preparación:

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

Luego, una función que convierte notas en enteros

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)

Luego, para cada nota, cambie el coord y búsquelo en una tabla

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
fuente
2

Perl 5: 183-100 = 83

Editar: logré cortar algunos caracteres adicionales, así que también modifiqué los nombres de acordes como en la solución Python, por lo que puedo fingir por un momento que estoy liderando.

#!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

Ejemplo:

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

Python 2, 335 bytes - 30 - 70 = 235

Primer intento en un golf un poco más largo, por lo que me pueden faltar algunos trucos obvios.

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

Comentarios:

  • Utilicé nombres de acordes alternativos de la página Wiki (ver el final de la línea larga) para ahorrar espacio.
  • Los acordes están representados por 3 compensaciones hexadecimales cada uno (no se requiere 0, pero se incluye para que las tríadas se alineen).
  • "#". find (n [1:]) funciona ya que "#". find ("b") es -1 y "#". find ("") es 0.

Salida de muestra

>>> 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
fuente