Música: o que há nesse acorde?

38

Entrada

O símbolo de qualquer acorde triádico (consulte http://en.wikipedia.org/wiki/Chord_(music)#Triads ).

Saída

As notas que constituem o acorde dado.

Exemplos

Entrada: AM Saída:A C# E

Entrada: C#m Saída:C# E G#

Entrada: Db+ Saída:C# F A

Entrada: C0 Saída:C D# F#

Bônus

-50 se você também pode lidar com sétimos acordes

-150 para realmente tocar o som do acorde

-150 para usar caracteres imprimíveis para mostrar como tocar o acorde em um piano; exemplo para AM:

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

-100 para usar caracteres imprimíveis para mostrar como tocar o acorde em uma guitarra; exemplo para AM:

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

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

Regras

  • O resultado deve ser um programa ou script de linha de comando.

  • A entrada e a saída podem ser de qualquer forma, desde que sigam um padrão de notação musical.

  • Uma representação de violão ou piano é considerada válida se e somente se contiver as três (triádicas) ou as quatro (sétimas) notas necessárias e nada mais. A mesma nota pode estar presente várias vezes no acorde.

  • Bibliotecas externas não são permitidas, exceto para geração de som (nesse caso #include, as importdiretivas ... não são adicionadas à contagem de caracteres).

  • Este é o código de golfe, o código mais curto vence!

Um pouco de teoria musical ...

Na música tonal ocidental moderna, cada oitava é composta por doze notas sucessivas, frequentemente observadas:

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

Ou:

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

Neste sistema, consideramos que duas notas sucessivas (por exemplo , Ae A#, ou Ee F) são separadas por um semitom. Além disso, as notas são uma espécie de "loop": o que se segue imediatamente G#é A.

Constelação de pitch

Um acorde é constituído por algumas (2, 3, 4, às vezes mais) notas que "soam bem juntas". Por exemplo, acordes triádicos contêm três notas diferentes e acordes da sétima contêm quatro notas diferentes.

Vamos definir os quatro acordes triádicos como:

  • Tríade maior : contém a raiz do acorde (nesta pergunta, a nota dada como entrada), o terço maior da raiz (4 semitons acima da raiz) e o quinto perfeito para a raiz (7 semitons acima da raiz) ); isso pode ser simbolizado 0-4-7

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

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

  • Tríade diminuída , simbolizada 0-3-6

Constelações de arremesso: tríades

Assim, por exemplo, se você quiser fazer uma tríade maior C , observou C, CM, Cmaj, você vai precisar de três observou:

  • 0: a raiz , neste caso, umC
  • 4: o terço menor , 4 semitons acima da raiz; isso é umE
  • 7: o quinto perfeito , 7 semitons acima da raiz: aG

Isto é o que a 0-4-7, 0-3-7, 0-4-8e 0-3-6notações usadas acima de média! Para os sétimos acordes, use o seguinte padrão:

Constelações de afinação: sétimos acordes

Por hoje é isso! Agora, surpreenda-me com um código incrível ... Se você tiver alguma dúvida, adicione alguns comentários abaixo.

Mathieu Rodic
fonte
1
Pode valer a pena adicionar uma explicação, incluindo as fórmulas para os acordes em notação inteira para não músicos. Notação inteira refere-se a tudo em semitons. Corda maior (Exemplo AM): 0,4,7. Acorde menor (exemplo C # m): 0,3,7. C diminuiu (Exemplo Co, ou como você chama C0) 0,3,6 (observe que a representação correta é C Eb Gb, mas para esse desafio, acho que podemos assumir que isso e o CD # F # são aceitáveis.) para um acorde aumentado (exemplo Db +) é 0,4,8 e seu exemplo está errado, pois nem sequer contém um Db. Como está escrito, é um B + que é equivalente a um D # + ou G +
Nível River St St
3
Além disso, o código mais curto resultará do uso da mesma forma de acordes para todos os acordes de guitarra do mesmo tipo, com barras. Então, Ab será uma forma A barrada no 11º traste. Tudo bem colocar um número ou precisamos desenhar 11 trastes? Em suma, há muitas coisas em que pensar. Você pode simplificar os bônus.
Level River St
1
Hmm .. seu acorde aumentado ainda está errado. C # é enarmônico para Db, mas Db+é que Db F Anão há D # ou G lá. Talvez seja um pouco mais teoria do que o necessário, as fórmulas eram a parte importante. Se você realmente deseja incluir todos os oito dos sétimos acordes listados na wikipedia, você deve especificar a entrada. Presumo que a produção artística do piano e da guitarra seja flexível.
Level River St
3
Sinto que aprendi mais sobre teoria musical aqui do que nas lições.
Kevin Evans
4
O problema mais legal deste site!
Raio

Respostas:

5

BBC BASIC

Emulador em bbcbasic.co.uk

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

Aqui está a versão mais recente, na qual eu consegui incluir os seguintes aprimoramentos enquanto aumentava apenas mais alguns caracteres.

A entrada pode ser editada confortavelmente na tela antes de pressionar return (eu estava usando GET $ antes para obter pressionamentos de tecla únicos, porque o BBC Basic não permite que você acesse um único caractere de uma string, como se a string fosse uma matriz. volumosa função MID $ para extrair uma sequência de um caractere de dentro da sequência.

Ambos os lados do teclado são exibidos, bem como a linha completa entre E e F.

Para compensar os caracteres adicionados pelo texto acima, reorganizei o programa para eliminar declarações de impressão desnecessárias e excluí alguns espaços em branco que, à primeira vista, pareciam que não podiam ser excluídos. No BBC Basic, todas as funções incorporadas são palavras reservadas, e você pode colocar um nome de variável antes delas, sem espaço entre elas. Os nomes de variáveis ​​não podem começar com uma palavra reservada. Para tornar o programa menos confuso para ler, alterei todas as variáveis ​​para minúsculas.

Embora a apresentação pareça muito melhor, o programa a seguir já está totalmente completo. (Veja a correção abaixo.) Geralmente, novas linhas e dois pontos são intercambiáveis, exceto quando uma instrução IF é usada. Nesse caso, todas as instruções na mesma linha (separadas por dois pontos) são executadas condicionalmente. As instruções após a nova linha não são controladas pelo FI e sempre serão executadas.

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

CORREÇÃO: O BASIC da BBC de RT Russell para Windows permite eliminar algumas novas linhas e dois pontos, reduzindo o total para 327, veja abaixo. Também simboliza as palavras-chave em caracteres únicos antes de salvar, reduzindo-o para 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

Saída rev 1

insira a descrição da imagem aqui

Rev 0, 337 - 150 teclado - 150 jogando = 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

Esse é um conceito semelhante à minha resposta do Arduino, mas eu sempre soube que poderia vencer essa contagem de bytes com o básico da BBC. Apenas reconhece objetos cortantes, mas considera B # inválido, você deve colocar C. Isso poderia ser corrigido se realmente fosse considerado importante.

Abandonei a ideia do violão e me concentrei em melhorar o teclado. Agora ele funciona de C a B, e eu adicionei no lado esquerdo do teclado e a linha entre E e F. Isso custa 28 caracteres. O lado direito não seria muito mais.

Aqui estão alguns exemplos de saída, um acorde diminuído de A # (que tem um som bastante estranho nessa inversão) e um acorde maior de B. Observe que a entrada não é ecoada na tela. Conforme a resposta do Arduino, gire a tela no sentido anti-horário para ver.

insira a descrição da imagem aqui

Versão ungolfed

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
fonte
Como o programa deve ser usado na linha de comando? (Eu instalei BBC BASIC na minha máquina Ubuntu)
Mathieu Rodic
Uau, eu não sabia que havia uma versão básica da BBC para Ubuntu. Não consigo encontrar um no site em que obtive meu emulador e não uso o Ubuntu. O BBC basic original tinha apenas um programa na memória de cada vez, então você digitou RUN. Com o emulador que eu uso, você precisa iniciar o ambiente do emulador e, em seguida, ele roda dentro dele. Ele possui um editor de texto, você clica para executar e, quando o programa termina, você pode digitar RUN para executar o programa novamente ou digitar comandos básicos individuais no ambiente. Você pode produzir um executável de linha de comando com meu emulador, mas somente se você comprar a versão completa.
Level River St
Se você quiser testar o programa, a melhor maneira de ajudá-lo é encontrar uma máquina Windows e baixar a versão exata que estou usando. Como alternativa, se você pudesse me dizer de onde você tirou sua versão do Ubuntu, eu poderia ler um pouco disso.
Level River St
O BBC Basic também roda em Linux, eles fornecem muitas distribuições em sua página inicial, dependendo do sistema operacional host. Eu simplesmente não conseguem obter o programa em execução, nem de passar o código ou colá-lo no prompt de ...
Mathieu Rodic
Acabei de baixar o Napoleon Brandy Basic e é realmente difícil começar! Você precisa salvar o código como um arquivo de texto chamado chords.nap e digite LOAD "chords.nap" no prompt de comando. Ele adiciona números de linha ao código (mais autêntico ao BBC Basic original, adicionaria mais alguns caracteres). Em seguida, você digita RUN e o programa trava na linha com a instrução SOUND, com a mensagem de erro "Recurso V não suportado do Basic encontrado." Você poderia escrever um programa sério com a implementação de RT Russell, se realmente quisesse. Mas com o Brandy básico eu nem pensaria nisso.
Level River St
8

Como você pode ver, eu não tentei jogar golfe. Eu sou um nerd de música, e uma das minhas irritações é quando as pessoas escrevem coisas usando as enarmônicas erradas (por exemplo, dizendo que um acorde diminuído de C é CD # F # em vez de C Eb Gb), então eu escrevi este programa que obtém as enarmônicas direita. Faz isso representando cada nota como o número de quintos perfeitos acima de F.

Pelo que vale a pena, se você quiser distinguir enarmônicos, qualquer intervalo musical pode ser bem representado em um programa de computador como um número de quintos perfeitos e um número de oitavas. Um quarto aumentado, por exemplo, é de 6 quintos e -3 oitavas perfeitas, e um quinto diminuído é de -6 quintos perfeitos e 4 oitavas.

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

Algumas invocações de exemplo:

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
fonte
5

Arduino

A entrada / saída é enviada / recebida do Arduino por uma porta COM. Um usuário pode interagir com isso por meio de um terminal ou do monitor serial no IDE do Arduino. Como você deve ter adivinhado pela minha escolha de plataforma, estou planejando incluir a execução real do acorde (embora ainda não o tenha feito).

Eu lidei com o bônus do teclado com sucesso e tentei lidar com a guitarra, com sucesso limitado.

A caixa de acordes tem 130 bytes, o que é muito longo para valer a pena. Portanto, tentei de outra maneira, apenas imprimindo o estilo Tab dos números de traste. Atualmente, são 81 bytes para um bônus de 81-100 = -19. Se essa abordagem for considerada válida, posso tentar melhorá-la.

Os acordes utilizados são todos do tipo D, com a raiz na 2ª corda, o quinto na 3ª corda e o terceiro na 1ª e na 4ª cordas. As cordas 5 e 6 não são usadas e eu as marquei com Xs à direita da caixa de acordes (a esquerda seria mais usual, mas exemplos marcados à direita podem ser encontrados).

Como o programa considera F como a nota mais baixa (para compatibilidade com o teclado, ao mesmo tempo que evita trastes excessivamente altos com esse formato de acorde), o acorde mais alto é um E (com raiz no 17º traste). Veja exemplo de saída.

O teclado é mais bem sucedido em termos de golfe. É executado a partir de FE em vez de CB pelas razões descritas acima. Ele deve ser visualizado girando a tela 90% no sentido anti-horário, quando você pode ver claramente os contornos das notas pretas e a demarcação entre as notas brancas com ---. A linha entre B e C pode ser estendida com alguns ____por mais alguns bytes.

Vou tentar tocar as notas a seguir. Isso será interessante porque, embora eu acredite que o Arduino Uno tenha 3 temporizadores internos, apenas uma nota de cada vez pode ser tocada usando o comando de tom interno. Existe uma função de biblioteca externa que usa todos os temporizadores de hardware (que atrapalham o serial, mas não será necessário nesse estágio.) Como alternativa, posso tentar produzir os tons no software.

Se eu for bem-sucedido com isso, vou apostar, mas acho que não será o vencedor geral.

Código ungolfed

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));
  }  
}

Saída de amostra Quanto menor o espaçamento entre as linhas do texto, melhor será a aparência. Portanto, parece ótimo quando estou editando a postagem, mas horrível na caixa cinza após a publicação. Em vez disso, publiquei uma captura de tela do monitor serial do Arduino, com espaçamento intermediário entre linhas (e, portanto, com qualidade de exibição).

insira a descrição da imagem aqui

Level River St
fonte
Mal posso esperar pelo som real!
Mathieu Rodic
As notas para EM estão corretas (EG # B), mas não estão alinhadas corretamente no teclado. Parece que você está no caminho certo!
Cameron Tinker
@CameronTinker Por favor, incline a tela 90 graus no sentido anti-horário e olhe novamente. Observe que o teclado funciona de F a E, não de C a B pelos motivos descritos em minha postagem. Escolher F como a "nota zero" interna foi um compromisso para a saída da guitarra e do teclado. Existem 3 notas pretas à esquerda, 2 à direita e as notas de saída estão alinhadas corretamente. Estender a divisão entre B e C tornaria mais claro, mas custaria cerca de 20 bytes extras. É bruto, mas ainda acho que meu teclado é mais legível que o de Pandubear.
Level River St
Não sei como senti falta disso! Me desculpe por isso. Sou pianista e minha primeira inclinação quando vi isso foi que o teclado não parecia certo;).
Cameron Tinker
@MathieuRodic Agora eu tenho sons do Arduino, mas eles são tão ruins que não tenho certeza se os chamaria de acorde reconhecível. Vou tentar outra vez, mas há algumas coisas acontecendo com o Arduino que não entendo. Enfim, acabei de postar uma resposta no BBC Basic com teclado e som com uma aparência muito melhor. Então eu vou atualizar este post mais tarde
Nível River St
4

Python3 - 315 caracteres

Primeira vez em codegolf! Suporta apenas acordes menores, maiores, diminuídos e aumentados no 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
fonte
2
Use em 'C C# D D# E F F# G G# A A# B'.split(' ')vez de sua matriz literal para salvar alguns bytes.
wchargin
2
if('#'in a):j+=1-> if'#'in a:j+=1= 2 caracteres a menos para cada instrução. A alteração ypara uma range()expressão também salva algo. Bem vinda! (e lembre-se de que as novas linhas também contam;))
gcq 25/03
2
@wch Mais bytes podem ser salvos com 'C C# D D# E F F# G G# A A# B'.split();) #
undergroundmonorail
1
Como você contou sua pontuação? Eu acho que você precisa contar novas linhas como um caractere cada. A propósito, como essa resposta funciona apenas em Python3, editarei sua resposta para declarar isso explicitamente. Além disso, em vez de usar ypara armazenar [1,2,4,5,6], por que você não pula ye substitui a linha 4 por for i in[1,2,4,5,6]:? De qualquer forma, bem-vindo ao codegolf e espero que você se divirta aqui.
pastebin.com cortar 0mr8spkT
1
Você também pode salvar mais de 3 caracteres pelo recuo com apenas um espaço em vez de quatro em linha 5.
pastebin.com cortar 0mr8spkT
4

Python 506 (unicode como 1 caractere) -150 (som) -150 (teclado) = 206

Para reprodução de som, ele usa pygame.midi. Observe que o pygame.midi.get_default_output_id()método não funciona muito bem. Assim, você pode tentar mudar a linha o=Output(get_default_output_id())para o=Output(1), o=Output(2), etc. Normalmente, o valor correto é entre 0 e 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│  │  │  │  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
Raio
fonte
3

J - 82 char

Independente, lê da entrada do console. Se você precisar de stdin, altere a final 1para a 3. Reivindicando nenhum bônus, e apenas cobrindo as tríades.

+/&(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 vez de uma nota nítida, por exemplo, C#você deve usar o nome plano equivalente Db. (Corrigir isso aumentaria o código em mais de um pouco.) Os quatro tipos de acordes são 0para diminuir, mpara menor, Mpara maior e +para aumentado.

A lógica é a seguinte: usamos o último caractere para adicionar um deslocamento à base 0-3-6, que seleciona o tipo de terceiro e quinto. Enquanto isso, usamos a nota para descobrir de onde na escala podemos extrair as notas. Os ;:dois tornam a nota compatível com a indexação na escala no início e depois (by &.) transforma as notas puxadas em uma sequência separada por espaço.

Exemplo 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
algoritmshark
fonte
O sufixo 'h' segue um dos "padrões de notação musical"?
Mathieu Rodic
@MathieuRodic Suponho que seja uma área cinzenta, então colidi com todos eles em apartamentos. Nenhuma alteração na funcionalidade. Não sei por que não fiz isso antes.
algorithmshark
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 é o meu primeiro código de golfe. Eu acho que pode ser mais curto, mas não consigo encontrar nenhum bytes para salvar.

Suportes principais, mpara menor, 0para diminuída, +para aumentada, ou mais de 37 bytes para dim, aug.

Lanche
fonte
n[m]==0pode ser simplesmente !n[m]. O mesmo se aplica em outro local. Total você pode cortar 6 caracteres facilmente .
Gaurang Tandon
@GaurangTandon Desde que né string, n[m]==0será convertido 0em "0", então é igual a n[m]=="0". "0" == 0é verdade, mas !"0"é falsa.
31 de
Eu estava apenas apontando porque obtive a mesma saída quando inseri AM. Eu também posso estar errado.
Gaurang Tandon 26/03
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]) 

Meu primeiro desafio de golfe :), não sei se mais alguns bytes podem ser removidos.
A notação usada aqui é * aug / + maj /, min / - dim
Eu mereço um ponto de bônus por ter a constante 42 no código: P

LemonBoy
fonte
Você pode obter alguns 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 30/03
1

Python 3: 257 - 150 = 107

Apenas 25 caracteres a mais para vencer a solução J! Ah bem. Existem algumas idéias legais aqui, eu acho.

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,' #','  '))

A entrada é como os exemplos, embora você deva usar nomes nítidos em vez de nomes simples. (por exemplo, Gb deve ser F #)

A saída é uma oitava de um piano, vista de cima e à esquerda, com nomes de notas sobrepostos. Deve ser apenas um pequeno trecho da imaginação.

$ echo C#m | python3 chords.py
-  _ 
-G#_ 
-  _ 
____ 
-  _E
-C#_ 
____ 
pandubear
fonte
Bom trabalho! Embora eu não veja as notas para tocar na saída? Para CM, devemos ser capazes de ler C E G...
Mathieu Rodic
Oh, interpretei mal a pergunta que suponho. Vamos ver se eu posso trabalhar isso em ...
pandubear
Fixo! Muito longo ...):
pandubear
Você não pode substituir bool(R)com R|0?
Mathieu Rodic
Nah, o ponto é que R é uma lista e bool(R)é 1 (verdadeiro) se não for vazio e 0 (falso) se estiver vazio. O |operador não trabalha com 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
fonte
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"]    
Raio
fonte