Música: ¿qué hay en este acorde?

38

Entrada

El símbolo de cualquier acorde triádico (ver http://en.wikipedia.org/wiki/Chord_(music)#Triads ).

Salida

Las notas que constituyen el acorde dado.

Ejemplos

Entrada: AM Salida:A C# E

Entrada: C#m Salida:C# E G#

Entrada: Db+ Salida:C# F A

Entrada: C0 Salida:C D# F#

Bonos

-50 si también puedes lidiar con séptimos acordes

-150 para tocar realmente el sonido del acorde

-150 por usar caracteres imprimibles para mostrar cómo tocar el acorde en un piano; ejemplo para AM:

┌─┬─┬┬─┬─┬─┬─┬┬─┲┱─┬─┬─┲━┱┬─┲━┱─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ┃┃ │ │ ┃ ┃│ ┃ ┃ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ┃┃ │ │ ┃ ┃│ ┃ ┃ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ┃┃ │ │ ┃ ┃│ ┃ ┃ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┲┛┗┱┘ │ ┗┯┛└┲┛ ┃ └┬┘└┬┘└┬┘ │
│  │  │  │  │  ┃  ┃  │  │  ┃  ┃  │  │  │  │
└──┴──┴──┴──┴──┺━━┹──┴──┴──┺━━┹──┴──┴──┴──┘

-100 por usar caracteres imprimibles para mostrar cómo tocar el acorde en una guitarra; ejemplo para AM:

x   o   o   o   o   o
┌───┬───┬───┬───┬───┐
│   │   │   │   │   │
├───┼───┼───┼───┼───┤
│   │   │   │   │   │
├───┼───┼───┼───┼───┤
│   │   █   █   █   │
├───┼───┼───┼───┼───┤
│   │   │   │   │   │

(ver https://en.wikipedia.org/wiki/Box-drawing_character )

Reglas

  • El resultado debe ser un programa o script de línea de comandos.

  • La entrada y la salida pueden ser de cualquier forma, siempre que sigan un estándar de notación musical.

  • Una representación de guitarra o piano se considera válida si y solo si contiene las tres (triádicas) o cuatro (séptimas) notas requeridas y nada más. La misma nota puede estar presente varias veces en el acorde.

  • Las bibliotecas externas no están permitidas, excepto para la generación de sonido (en cuyo caso #include, las importdirectivas , ... no se agregan al recuento de caracteres).

  • Este es el código de golf, ¡el código más corto gana!

Un poco de teoría musical ...

En la música tonal occidental moderna, cada octava se compone de doce notas sucesivas, a menudo señaladas:

A A# B C C# D D# E F F# G G#

O:

La La# Si Do Do# Re Re# Mi Fa Fa# Sol Sol#

En este sistema, consideramos que dos notas sucesivas (por ejemplo , Ay A#, o Ey F) están separadas por un semitono. Además, las notas son una especie de "bucle": lo que sigue inmediatamente G#es A.

Constelación de tono

Un acorde está constituido por unas pocas notas (2, 3, 4, a veces más) que "suenan bien juntas". Por ejemplo, los acordes triádicos contienen tres notas diferentes, y los acordes séptimos contienen cuatro notas diferentes.

Definamos los cuatro acordes triádicos como:

  • Tríada mayor : contiene la raíz del acorde (en esta pregunta, la nota dada como entrada), el tercio mayor para la raíz (4 semitonos más alto que la raíz) y el quinto perfecto para la raíz (7 semitonos más alto que la raíz ); esto se puede simbolizar 0-4-7

  • Tríada menor , simbolizada 0-3-7

  • Tríada aumentada , simbolizada 0-4-8

  • Tríada disminuida , simbolizada 0-3-6

Constelaciones de tono: tríadas

Así, por ejemplo, si usted quiere hacer una tríada de Do mayor , señalado C, CM, Cmaj, necesitará tres observó:

  • 0: la raíz , en este caso unC
  • 4: el tercio menor , 4 semitonos más alto que la raíz; eso es unE
  • 7: el quinto perfecto , 7 semitonos más altos que la raíz: aG

Esto es lo que el 0-4-7, 0-3-7, 0-4-8y 0-3-6anotaciones utilizadas por encima de media! Para los acordes séptimos, use el siguiente patrón:

Constaciones de tono: séptimos acordes

¡Es todo por hoy! Ahora, sorpréndeme con un código increíble ... Si tienes alguna pregunta, agrega algunos comentarios a continuación.

Mathieu Rodic
fuente
1
Puede valer la pena agregar una explicación que incluya las fórmulas para los acordes en notación entera para los no músicos. La notación entera se refiere a todo en semitonos. Acorde mayor (Ejemplo AM): 0,4,7. Acorde menor (ejemplo C # m): 0,3,7. C disminuido (Ejemplo Co, o como lo llama C0) 0,3,6 (tenga en cuenta que la representación correcta es C Eb Gb, pero para este desafío, supongo que podemos asumir que tanto esto como CD # F # son aceptables). La fórmula para un acorde aumentado (Ejemplo Db +) es 0,4,8 y su ejemplo es incorrecto ya que ni siquiera contiene un Db. Como está escrito, es un B + que es equivalente a un D # + o G +
Level River St
3
Además, el código más corto resultará del uso de la misma forma de acorde para todos los acordes de guitarra del mismo tipo, sin barra. Entonces Ab será una forma de A barrada en el traste 11. ¿Está bien poner un número o tenemos que sacar 11 trastes? Con todo, hay muchas cosas en las que pensar. Es posible que desee simplificar las bonificaciones.
Level River St
1
Hmm ... tu acorde aumentado todavía está mal. C # es enarmónico a Db, pero Db+es que Db F Ano hay D # o G allí. Tal vez sea un poco más de teoría de lo necesario, las fórmulas fueron la parte importante. Si realmente desea incluir los ocho acordes de séptima enumerados en wikipedia, debe especificar la entrada. Supongo que la producción de arte ascii del piano y la guitarra es flexible.
Level River St
3
Siento que he aprendido más sobre teoría musical aquí de lo que aprendí de las lecciones.
Kevin Evans
44
¡El problema más genial en este sitio!
Ray

Respuestas:

5

BBC BASIC

Emulator en bbcbasic.co.uk

Rev 1, 340 - 150 teclado - 150 jugando = 40

Aquí está la última versión, en la que logré incluir las siguientes mejoras al tiempo que alargué solo unos pocos caracteres más.

La entrada se puede editar cómodamente en la pantalla antes de presionar la tecla Intro (antes estaba usando GET $ para presionar una sola tecla, porque BBC Basic no le permite acceder a un solo carácter desde una cadena como si la cadena fuera una matriz. Ahora uso el Función MID $ voluminosa para extraer una cadena de un carácter dentro de la cadena.

Se muestran ambos lados del teclado, así como la línea completa entre E y F.

Para compensar los caracteres añadidos por lo anterior, reorganicé el programa para eliminar declaraciones de impresión innecesarias y eliminé un espacio en blanco que a primera vista parecía que no podía eliminarse. EN BBC Basic todas las funciones integradas son palabras reservadas, y puede poner un nombre de variable justo antes de ellas sin espacio en el medio. Los nombres de variables no pueden comenzar con una palabra reservada. Para que el programa sea menos confuso de leer, cambié todas las variables a minúsculas.

Aunque la presentación se ve mucho mejor, el siguiente programa ya está totalmente desarrollado. (Vea la corrección a continuación.) Generalmente, las líneas nuevas y los dos puntos son intercambiables, excepto cuando se usa una declaración IF. En ese caso, todas las declaraciones en la misma línea (separadas por dos puntos) se ejecutarán condicionalmente. Las declaraciones posteriores a la nueva línea no están controladas por el IF y siempre se ejecutarán.

Programa rev 1 340 caracteres

  a$="C#D#EF#G#A#B0Mm+"
  INPUTx$
  r=INSTR(a$,LEFT$(x$,1))-1
  c=INSTR(a$,MID$(x$,2,1))
  IFc=2c=INSTR(a$,MID$(x$,3)):r=r+1
  t=(r+4-c MOD2)MOD12
  f=(r+c DIV2)MOD12
  v=1
  FORn=-1TO11
  c=1-(n<0ORn=4ORn=11)*5
  b$=MID$(a$,n+1,1)
  IFb$="#"c=11:b$=MID$(a$,n,1)+b$
  c$=MID$("   _______--|__",c,5)
  IFr=n ORt=n ORf=n c$=c$+b$:SOUNDv,-15,100+n*4,99:v=v+1
  PRINTc$
  NEXT

CORRECCIÓN: La BBC BASIC de RT Russell para Windows le permite eliminar algunas líneas nuevas y dos puntos, reduciendo el total a 327, ver más abajo. También tokeniza las palabras clave en caracteres individuales antes de guardar, reduciéndolo a 279.

  a$="C#D#EF#G#A#B0Mm+"INPUTx$
  r=INSTR(a$,LEFT$(x$,1))-1c=INSTR(a$,MID$(x$,2,1))IFc=2c=INSTR(a$,MID$(x$,3))r=r+1
  t=(r+4-c MOD2)MOD12f=(r+c DIV2)MOD12v=1FORn=-1TO11c=1-(n<0ORn=4ORn=11)*5b$=MID$(a$,n+1,1)IFb$="#"c=11b$=MID$(a$,n,1)+b$
  c$=MID$("   _______--|__",c,5)IFr=n ORt=n ORf=n c$=c$+b$SOUNDv,-15,100+n*4,99v=v+1
  PRINTc$
  NEXT

Salida rev 1

ingrese la descripción de la imagen aquí

Rev 0, 337 - 150 teclado - 150 jugando = 37

A$="C#D#EF#G#A#B0Mm+":X$=GET$:R=INSTR(A$,X$)-1:X$=GET$:IF X$="#"R=R+1:X$=GET$
C=INSTR(A$,X$):T=(R+4-C MOD2)MOD12:F=(R+C DIV2)MOD12:V=1:PRINT"______"
FORN=0 TO 11
C=1-(N=4)*12:B$=MID$(A$,N+1,1): IF B$="#" C=7: B$=MID$(A$,N,1)+B$
PRINT MID$("    __---|________",C,6);:IF(R-N)*(T-N)*(F-N)=0 PRINT B$;:SOUND V,-15,100+N*4,99:V=V+1
PRINT
NEXT

Este es un concepto similar a mi respuesta de Arduino, pero siempre supe que podía superar ese conteo de bytes con BBC basic. Solo reconoce objetos punzantes, pero considera que B # no es válido, debe poner C. Esto podría solucionarse si realmente se considera importante.

Abandoné la idea de la guitarra y me concentré en mejorar el teclado. Ahora va de C a B, y he agregado en el lado izquierdo del teclado y la línea entre E y F. Eso cuesta 28 caracteres. El lado derecho no sería mucho más.

Aquí hay una salida de muestra, un acorde disminuido A # (que tiene un sonido bastante extraño en esta inversión) y un acorde mayor B. Tenga en cuenta que la entrada no se repite en la pantalla. Según la respuesta de Arduino, gire la pantalla hacia la izquierda para ver.

ingrese la descripción de la imagen aquí

Versión sin golf

A$="C#D#EF#G#A#B0Mm+"                              :REM Note names and chord type names fit very conveniently in the same string.
X$=GET$                                            :REM Get a character 
R=INSTR(A$,X$)-1                                   :REM Root note = position of that char in A$. INSTR starts counting at 1, but we want 0, so subtract.
X$=GET$                                            :REM If the root note is natural, the next character will be the chord type. But...
IF X$="#"R=R+1:X$=GET$                             :REM If this char is # we need to increment the root, and get another char for chord type. 
C=INSTR(A$,X$)                                     :REM C encodes for chord type
T=(R+4-C MOD2)MOD12                                :REM even C means major third, odd C means minor third
F=(R+C DIV2)MOD12                                  :REM "Mm" gives C=14,15 meaning C DIV2=7 (perfect fifth.) C=13,16 give diminished and augmented: 6,8.
V=1                                                :REM V is the sound channel number ("voice")                             
PRINT"______"                                      :REM left side of keyboard for cosmetic reasons
FORN=0 TO 11                                       :REM at the start of each iteration initialise C to 1, to point to the 4 spaces/2 underscores in the string below for drawing white notes. 
  C=1-(N=4)*12                                     :REM if the note is E, add 12 so it points to the 6 underscores to draw the line between E and F. 
  B$=MID$(A$,N+1,1)                                :REM load B$ with the name of the current note.
  IF B$="#" C=7: B$=MID$(A$,N,1)+B$                :REM if the character encountered is a sharp, update C to point the characters for drawing a sharp. Find the previous character in A$ and join it to the beginning of B$ to complete the note name.
  PRINT MID$("    __---|________",C,6);            :REM print the key (6 characters.)
  IF(R-N)*(T-N)*(F-N)=0 PRINT B$;:SOUND V,-15,100+N*4,99:V=V+1  :REM if N is equal to R,T or F, print the note name beside the key, play the note and increment the channel number for the next note.  
  PRINT                                            :REM print a carriage return. It may be possible to golf this line out.
NEXT
Level River St
fuente
¿Cómo se supone que se utilizará el programa desde la línea de comandos? (Instalé BBC BASIC en mi máquina Ubuntu)
Mathieu Rodic
Wow, no sabía que había una versión de BBC basic para Ubuntu. No puedo encontrar uno en el sitio del que obtuve mi emulador, y no uso Ubuntu. Original de la BBC básica solo tenía un programa en la memoria a la vez, así que escribiste RUN. Con el emulador que uso, debe iniciar el entorno del emulador y luego se ejecuta dentro de él. Tiene un editor de texto, luego hace clic para ejecutar, luego, cuando finaliza el programa, puede escribir RUN para ejecutar el programa nuevamente o escribir comandos básicos individuales dentro del entorno. Puede producir un ejecutable de línea de comandos con mi emulador, pero solo si compra la versión completa.
Level River St el
Si desea probar el programa, la mejor manera en que podría ayudarlo es si puede encontrar una máquina con Windows y descargar la versión exacta que estoy usando. Alternativamente, si pudiera decirme de dónde obtuvo su versión de Ubuntu, podría leer un poco sobre eso.
Level River St
BBC Basic también se ejecuta en Linux, proporcionan muchas distribuciones en su página de inicio dependiendo del sistema operativo host. Simplemente no logré ejecutar el programa, ni al pasar el código o pegarlo en el indicador ...
Mathieu Rodic
Acabo de descargar Napoleon Brandy Basic, y de hecho, ¡es difícil comenzar! Necesita guardar el código como un archivo de texto llamado chords.nap, luego escriba LOAD "chords.nap" en el símbolo del sistema. Agrega números de línea al código (más auténtico al BBC Basic original, agregaría algunos caracteres más) Luego escribe RUN y el programa se bloquea en la línea con la instrucción SOUND en él, con el mensaje de error "Función V básica no admitida encontró." En realidad, podría escribir un programa serio con la implementación de RT Russell si realmente quisiera. Pero con Brandy basic ni siquiera lo pensaría.
Level River St
8

Como pueden ver, no intenté jugar golf en absoluto. Soy un geek de la música, y una de las cosas que más me molestan es cuando la gente escribe cosas usando la armónica incorrecta (por ejemplo, diciendo que un acorde C disminuido es CD # F # en lugar de C Eb Gb), así que escribí este programa que obtiene la armónica. Derecha. Lo hace representando cada nota como el número de quintas perfectas por encima de F.

Para lo que vale, si desea distinguir la enarmonía, cualquier intervalo musical puede representarse muy bien en un programa de computadora como una cantidad de quintos perfectos y una cantidad de octavas. Un cuarto aumentado, por ejemplo, es 6 quintos perfectos y -3 octavas, y un quinto disminuido es -6 quintos perfectos y 4 octavas.

Haskell, 441 caracteres

import Data.List

notes = "FCGDAEB"

fromNum x = [notes !! (mod x 7)] ++ if x < 0 then replicate (-(div x 7)) 'b' else replicate (div x 7) '#'

toNum (x:xs) = y + 7 * if isPrefixOf "b" xs then -length xs else length xs
    where Just y = elemIndex x notes

chord xs = unwords . map (fromNum . \x -> toNum (init xs) + x) $ case last xs of 'A' -> [0,4,8]; 'M' -> [0,4,1]; 'm' -> [0,-3,1]; 'd' -> [0,-3,-6]

main = getLine >>= putStrLn . chord

Algunas invocaciones de ejemplo:

jaspers:junk tswett$ ./chord
AM
A C# E
jaspers:junk tswett$ ./chord
C#m
C# E G#
jaspers:junk tswett$ ./chord
DbA
Db F A
jaspers:junk tswett$ ./chord
Cd
C Eb Gb
jaspers:junk tswett$ ./chord
A#M
A# C## E#
jaspers:junk tswett$ ./chord
Dbm
Db Fb Ab
Tanner Swett
fuente
5

Arduino

La entrada / salida se envía / recibe del Arduino a través de un puerto COM. Un usuario puede interactuar con esto a través de un terminal o el monitor serie en el IDE de Arduino. Como habrás adivinado por mi elección de plataforma, estoy planeando incluir la ejecución real del acorde (aunque todavía no lo he hecho).

He abordado la bonificación del teclado con éxito, y he tratado de abordar la guitarra, con un éxito limitado.

El cuadro de acordes viene en 130 bytes, que es demasiado largo para que valga la pena. Por lo tanto, he intentado otra forma, simplemente imprimiendo el estilo de Tabulación de números de trastes. Actualmente esto es 81 bytes para un bono de 81-100 = -19. Si este enfoque se considera válido, puedo intentar mejorarlo.

Los acordes utilizados son todas las formas de tipo D con la raíz en la 2da cuerda, la quinta en la 3ra cuerda y la tercera en la 1ra y 4ta cuerda. Las cuerdas 5 y 6 no se usan y marco esto con X a la derecha del cuadro de acordes (la izquierda sería más habitual, pero se pueden encontrar ejemplos marcados a la derecha).

Debido a que el programa considera que F es la nota más baja (para compatibilidad con el teclado mientras evita trastes excesivamente altos con esta forma de acorde), el acorde más alto es una E (con raíz en el traste 17). Ver ejemplo de salida.

El teclado tiene más éxito en términos de golf. Se ejecuta desde FE en lugar de CB por los motivos descritos anteriormente. Debe verse girando la pantalla un 90% en sentido antihorario, cuando puede ver claramente los contornos de las notas negras y la demarcación entre las notas blancas con ---. La línea entre B y C podría extenderse con algunos ____por unos pocos bytes más.

Intentaré tocar las notas a continuación. Esto será interesante porque, aunque creo que el Arduino Uno tiene 3 temporizadores internos, solo se puede reproducir una nota a la vez utilizando el comando de tono incorporado. Hay una función de biblioteca externa que usa todos los temporizadores de hardware (que estropearán el serial, pero de todos modos no será necesario en esa etapa). Alternativamente, puedo intentar producir los tonos en softare.

Si tengo éxito con eso, jugaré golf, pero no creo que sea el ganador general.

Código sin golf

String p="F#G#A#BC#D#E -Mm+",y,d[]=
{"    ","---|"},n="\n";

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(99999);
}

void loop(){
  char x[9]; int r,t,f,i,c=1;
  Serial.readBytesUntil(13,x,9);
  Serial.println(x);  
  r=p.indexOf(x[0]);
  if (x[1]==35|x[1]==98){c=2;r+=x[1]==35?1:-1;}
  f=p.indexOf(x[c])/2;
  t=4-p.indexOf(x[c])%2;

  //chord box
  y=n;for(i=24;i--;)y+=d[1]+(i%4?"":" \n");
  y[89]=y[107]='X'; y[t*4-10]=y[t*4+52]=y[f*4+14]=y[28]='O';
  Serial.print("\t "+String(r+6)+y);

  f+=r;t+=r;

  //tab style
  Serial.println(String(t+1)+n+String(r+6)+n
  +String(f-2)+n+String(t+3)+"\nX\nX\n");

  f%=12;t%=12;

  //piano
  for(i=0;i<12;i++){
    c=0;
    y=String(p[i]);
    if(y=="#") {c=1;y=p[i-1]+y;}      
    Serial.println(d[c]+"__"+((r-i&&t-i&&f-i)?"":y));
  }  
}

Salida de muestra Cuanto menor sea el espacio entre las líneas de texto, mejor se verá. Por lo tanto, se ve muy bien cuando estoy editando la publicación, pero horrible en el cuadro gris después de la publicación. En cambio, publiqué una captura de pantalla del monitor serie Arduino que tiene un espacio intermedio entre líneas (y, por lo tanto, calidad de visualización)

ingrese la descripción de la imagen aquí

Level River St
fuente
¡No puedo esperar al sonido real!
Mathieu Rodic
Las notas para EM son correctas (EG # B), pero no están alineadas correctamente en su teclado. ¡Parece que estás en el camino correcto!
Cameron Tinker
@CameronTinker Incline la pantalla 90 grados en sentido antihorario y vuelva a mirar. Tenga en cuenta que el teclado se ejecuta de F a E, no de C a B por las razones descritas en mi publicación. Elegir F como la "nota cero" interna fue un compromiso tanto para la salida de guitarra como de teclado. Hay 3 notas negras a la izquierda, 2 a la derecha y las notas de salida están correctamente alineadas. Ampliar la división entre B y C lo haría más claro, pero costaría unos 20 bytes adicionales. Es crudo, pero todavía creo que mi teclado es más legible que el de Pandubear.
Level River St
¡No sé cómo me perdí eso! Lo siento por eso. Soy pianista y mi primera inclinación cuando vi esto fue que el teclado no se veía bien;).
Cameron Tinker
@MathieuRodic Tengo sonidos del Arduino ahora, pero son tan pobres que no estoy seguro de llamarlos un acorde reconocible. Voy a intentarlo de nuevo, pero hay algunas cosas que suceden con el Arduino que no entiendo. De todos modos, acabo de publicar una respuesta en BBC Basic con teclado y sonido que se ve mucho mejor. Así que actualizaré esta publicación más tarde
Level River St,
4

Python3 - 315 char

Primera vez en codegolf! Solo admite acordes menores, mayores, disminuidos y aumentados en este momento.

z=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];y=[1,2,4,5,6]
def q(a):print(z[a%12])
a=input();k=(ord(a[0])+3)%7;j=k;m=4;s=0;f=7;
for i in y:
    if(k>=i):j+=1
if('#'in a):j+=1
if('b'in a):j-=1
if('m'in a or'0'in a):m=3
if('+'in a or"aug"in a):f=8
if('0'in a or"dim"in a):f=6;m=3
if('ma'in a):m=4
q(j);q(j+m);q(j+f);
John
fuente
2
Use en 'C C# D D# E F F# G G# A A# B'.split(' ')lugar de su matriz literal para guardar algunos bytes.
wchargin
2
if('#'in a):j+=1-> if'#'in a:j+=1= 2 caracteres menos para cada declaración. También cambiar ya una range()expresión también guarda algo. ¡Bienvenido! (y recuerde que las nuevas líneas también cuentan;))
gcq
2
@wch Se pueden guardar más bytes con 'C C# D D# E F F# G G# A A# B'.split();)
undergroundmonorail
1
¿Cómo contó su puntaje? Creo que también debes contar nuevas líneas como un carácter cada una. Por cierto, dado que esta respuesta solo funciona en Python3, editaré su respuesta para indicarlo explícitamente. Además, en lugar de usar ypara almacenar [1,2,4,5,6], ¿por qué no omite yy reemplaza la línea 4 con for i in[1,2,4,5,6]:? De todos modos, bienvenido a codegolf y espero que te diviertas aquí.
pastebin.com slash 0mr8spkT
1
También puede guardar 3 caracteres más mediante sangría con solo un espacio en lugar de cuatro en la línea 5.
pastebin.com slash 0mr8spkT
4

Python 506 (unicode como 1 char) -150 (sonido) -150 (teclado) = 206

Para la reproducción de sonido, utiliza pygame.midi. Tenga en cuenta que el pygame.midi.get_default_output_id()método no funciona muy bien. Por lo tanto, puede intentar cambiar la línea o=Output(get_default_output_id())a o=Output(1), o=Output(2)etc. Por lo general, el valor correcto está entre 0 y 5.

c=input()
s='C D EF G A B'.index(c[0])+{'#':1,'b':-1,'':0}[c[1:-1]]
m='0mM+'.index(c[-1])
t=s+3+m//2
R=[list(x)for x in['┌─'+'─┬─'*13+'─┐']+['│'+'  │'*14]*5+['└─'+'─┴─'*13+'─┘']]
i=3
for d in[3,6,3,3,6]*2:q=slice(i-1,i+2);R[0][q]='┬─┬';R[1][q]=R[2][q]=R[3][q]='│ │';R[4][q]='└┬┘';i+=d
X=[2]+[1,2,1,2,3,1,2,1,2,1,2,3]*2
from pygame.midi import*
init()
o=Output(get_default_output_id())
for s in[s,t,t+3+m%2]:R[[5,3][s%12 in[1,3,6,8,10]]][sum(X[:s+1])]='o';o.note_on(s+60,127,1)
for r in R:print(''.join(r))

Resultados

goooolf> python chords2.py
CM
┌─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┬─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │
│ o│  │ o│  │ o│  │  │  │  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
goooolf> python chords2.py
Cm
┌─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┬─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││o│ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │
│ o│  │  │  │ o│  │  │  │  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
goooolf> python chords2.py
Dm
┌─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┬─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │
│  │ o│  │ o│  │ o│  │  │  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
goooolf> python chords2.py
D+
┌─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┬─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │o││ ││o│ │ │ ││ │ │ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │
│  │ o│  │  │  │  │  │  │  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
G+
┌─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┬─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││o│ │ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │
│  │  │  │  │ o│  │ o│  │  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
goooolf> python chords2.py
Am
┌─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┬─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │
│  │  │  │  │  │ o│  │ o│  │ o│  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
goooolf> python chords2.py
C#0
┌─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┬─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │o││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │
│  │  │ o│  │ o│  │  │  │  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
goooolf> python chords2.py
EbM
┌─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┬─┬─┬┬─┬─┬─┬─┬┬─┬┬─┬─┐
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││ │ │ │ ││ ││ │ │ │ ││ │ │ │ ││ ││ │ │
│ │ ││o│ │ │ ││ ││o│ │ │ ││ │ │ │ ││ ││ │ │
│ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │ └┬┘└┬┘ │ └┬┘└┬┘└┬┘ │
│  │  │  │  │ o│  │  │  │  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
Rayo
fuente
3

J - 82 char

Autocontenido, lee desde la entrada de la consola. Si necesita stdin, cambie el final 1a a 3. No reclama bonificaciones y solo cubre las tríadas.

+/&(0 3 6++/\_3{.#:'0mM+'i.{:e)&.((,~C`Db`D`Eb`E`F`Gb`G`Ab`A`Bb`B)i.;:)}:e=.1!:1]1

En lugar de una nota aguda, por ejemplo C#, debe usar el nombre plano equivalente Db. (Corregir esto aumentaría el código en más de un bit). Los cuatro tipos de acordes son 0para disminuir, mpara menor, Mpara mayor y +para mayor.

La lógica es la siguiente: utilizamos el último carácter para agregar un desplazamiento a la base 0-3-6, que selecciona el tipo de tercero y quinto. Mientras tanto, usamos la nota para encontrar de qué parte de la escala extraer las notas. El ;:tanto hace que la nota compatible con la indexación en la escala desde el principio, y más tarde (por &.) convierte las notas recogido en un espacio separado de cuerdas.

Ejemplo de uso:

   +/&(0 3 6++/\_3{.#:'0mM+'i.{:e)&.((,~C`Db`D`Eb`E`F`Gb`G`Ab`A`Bb`B)i.;:)}:e=.1!:1]1
AM
A Ch E
   +/&(0 3 6++/\_3{.#:'0mM+'i.{:e)&.((,~C`Db`D`Eb`E`F`Gb`G`Ab`A`Bb`B)i.;:)}:e=.1!:1]1
Ab0
Ab B D
   +/&(0 3 6++/\_3{.#:'0mM+'i.{:e)&.((,~C`Db`D`Eb`E`F`Gb`G`Ab`A`Bb`B)i.;:)}:e=.1!:1]1
B+
B Eb G
   +/&(0 3 6++/\_3{.#:'0mM+'i.{:e)&.((,~C`Db`D`Eb`E`F`Gb`G`Ab`A`Bb`B)i.;:)}:e=.1!:1]1
Em
E G B
Algoritmo de tiburón
fuente
¿El sufijo 'h' sigue uno de los "estándares de notación musical"?
Mathieu Rodic
@MathieuRodic Supongo que es un área gris, así que los metí a todos en pisos. Sin cambios en la funcionalidad. No sé por qué no hice esto antes.
algormshark
2

Javascript, 224 caracteres

n=prompt();a="A0A#0B0C0C#0D0D#0E0F0F#0G0G#".split(0);x=1;r=a.indexOf(n[0]);n[1]=="#"&&(r++,x++);n[1]=="b"&&(r--,x++);s=r+4;l=r+7;(n[x]=="m"||n[x]==0)&&s++;s%=12;n[x]=="+"&&l++;n[x]==0&&l--;l%=12;alert(a[r]+" "+a[s]+" "+a[l])

Este es mi primer código de golf. Creo que puede ser más corto, pero no puedo encontrar bytes para guardar.

Soportes principales, mde menor importancia, 0para disminuida, +para aumentarse o más 37 bytes para dim, aug.

Bocadillo
fuente
n[m]==0puede ser simplemente !n[m]. Lo mismo se aplica en otro lugar. Total, puedes cortar 6 caracteres fácilmente .
Gaurang Tandon
@GaurangTandon Dado que nes una cadena, n[m]==0se convertirá 0en "0", por lo que es igual a n[m]=="0". "0" == 0Es cierto, pero !"0"es falso.
Merienda
Solo estaba señalando porque obtuve el mismo resultado cuando ingresé AM. Podría estar equivocado también.
Gaurang Tandon
2

Python ( 143 134 caracteres)

n,a='A A# B C C# D D# E F F# G G#'.split(),input();m,i=ord(a[-1])-42,n.index(a[:-1])
print(n[i],n[(i+4-m//2)%12],n[(i-4+(-m//2))%12]) 

Mi primer desafío de golf :), no sé si se pueden eliminar algunos bytes más.
La notación utilizada aquí es * aug / + maj /, min / - dim
Merezco un punto extra por tener la constante 42 en el código: P

LemonBoy
fuente
Puede obtener algunos bytes como este:n,q,a='A A# B C C# D D# E F F# G G#'.split(),[4,4,3,3],input();m,i=ord(a[-1])-42,n.index(a[:-1])
Mathieu Rodic
1

Pitón 3: 257-150 = 107

¡Solo 25 caracteres demasiado para superar la solución J! Oh bien. Hay algunas buenas ideas aquí, creo.

I='AaBCcDdEFfGg'*2
Q='0123456789.,'*2
K="""-1#_2
-,#_0
-9#_.
____8
-6#_7
-4#_5
____3"""
r,*R,q=input()
r=I.find(r)+bool(R)
p=str.replace
for x in[0]+[8,4,7,3,6]['+Mm0'.find(q):][:2]:K=p(K,Q[x+r],I[x+r].upper())
for x in Q:K=p(K,x,' ')
print(p(K,' #','  '))

La entrada es como los ejemplos, aunque debe usar nombres definidos en lugar de nombres planos. (por ejemplo, Gb debe ser F #)

La salida es una octava única de un piano, vista desde arriba y hacia la izquierda, con nombres de notas superpuestos. Debería ser solo un pequeño tramo de la imaginación.

$ echo C#m | python3 chords.py
-  _ 
-G#_ 
-  _ 
____ 
-  _E
-C#_ 
____ 
pandubear
fuente
¡Buen trabajo! Aunque, ¿no veo las notas para tocar en la salida? Para CM, deberíamos poder leer C E G...
Mathieu Rodic
Oh, interpreté mal la pregunta, supongo. A ver si puedo trabajar eso en ...
pandubear
¡Fijo! Demasiado tiempo ...):
pandubear
¿No puedes reemplazar bool(R)con R|0?
Mathieu Rodic
No, el punto es que R es una lista y bool(R)es 1 (verdadero) si no está vacío, y 0 (falso) si está vacío. El |operador no trabaja con listas ...
pandubear
1

Scala 537 caracteres - 50

import java.util.Scanner
object C extends App{
val c=Map("M"->145,"m"->137,"+"->273,"0"->73,"7"->1169,"M7"->2193,"m7"->1161,"Mm7"->2185,"+7"->1297,"+M7"->2321,"07"->585,"7b5"->1097)
val n=List("A","A#","B","C","C#","D","D#","E","F","F#","G","G#")
val o=List("","Bb","Cb","B#","Db","","Eb","Fb","E#","Gb","","Ab")
val s=new Scanner(System.in).nextLine
val v=s indexWhere{c=>c!='#'&&c!='b'&&(c<'A'||c>'G')}
val (u,m)=s splitAt v
val x=n.indexOf(u)max o.indexOf(u)
val k=c(m)
for(i<-0 to 11)if((k&(1<<i))!=0)print(n((i+x)%12)+" ")
println}
bb94
fuente
0

Haskell, 273 caracteres

n(s,a)="CCDDEFFGGAABB"!!(s+1-a):["b#"!!a|" b b  b b b "!!s/=' ']
t p=[(s,a)|s<-[11,10..0],a<-[0,1],n(s,a)==p]!!0
m(s,d)=n(mod s 12,d-3)
c q=[n(a,x),m(a+d,d),m(a+d+e,e)]where
 (a,x)=t$init q;f=lookup(last q).zip"0mM+";Just d=f[3,3,4,4];Just e=f[3,4,3,4]
main=print.c=<<getLine

Resultados

C0 ->["C","Eb","Gb"]   Cm ->["C","Eb","G"]    CM ->["C","E","G"]     C+ ->["C","E","G#"]    
C#0->["C#","F","G"]    C#m->["C#","F","G#"]   C#M->["C#","F","Ab"]   C#+->["C#","F","A"]    
D0 ->["D","F","Ab"]    Dm ->["D","F","A"]     DM ->["D","F#","A"]    D+ ->["D","F#","A#"]   
D#0->["D#","Gb","A"]   D#m->["D#","Gb","A#"]  D#M->["D#","G","Bb"]   D#+->["D#","G","B"]    
E0 ->["E","G","Bb"]    Em ->["E","G","B"]     EM ->["E","G#","B"]    E+ ->["E","G#","C"]    
F0 ->["F","Ab","B"]    Fm ->["F","Ab","C"]    FM ->["F","A","C"]     F+ ->["F","A","C#"]    
F#0->["F#","A","C"]    F#m->["F#","A","C#"]   F#M->["F#","A#","Db"]  F#+->["F#","A#","D"]   
G0 ->["G","Bb","Db"]   Gm ->["G","Bb","D"]    GM ->["G","B","D"]     G+ ->["G","B","D#"]    
G#0->["G#","B","D"]    G#m->["G#","B","D#"]   G#M->["G#","C","Eb"]   G#+->["G#","C","E"]    
A0 ->["A","C","Eb"]    Am ->["A","C","E"]     AM ->["A","C#","F"]    A+ ->["A","C#","F"]    
A#0->["A#","Db","F"]   A#m->["A#","Db","F"]   A#M->["A#","D","F"]    A#+->["A#","D","F#"]   
B0 ->["B","D","F"]     Bm ->["B","D","F#"]    BM ->["B","D#","Gb"]   B+ ->["B","D#","G"]    
Rayo
fuente