Música: Qual o nome desse acorde?

9

Este é o inverso da música: o que há nesse acorde? , que é imprimir as notas em um determinado acorde. Desta vez, a entrada é uma lista de notas em um acorde, e sua tarefa é produzir qual é o acorde.

Seu programa deve suportar os seguintes acordes triádicos. Exemplos são dados com a raiz C. Os acordes com outras raízes são os mesmos com todas as notas giradas para que C se torne essa nota raiz, por exemplo, Dmaj consiste em D, F # e 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

Observe que Caug é o mesmo que Eaug e G # aug, e Csus4 é o mesmo que Fsus2. Você pode produzir qualquer um deles, mas há um bônus se produzir todos eles.

E os sétimos acordes para o bônus estão listados na tabela a seguir:

        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

Regras

  • Você pode escrever um programa completo ou uma função.
  • A entrada é uma lista de notas, separadas por um espaço ou outro caractere conveniente. Também pode ser uma matriz de seqüências de caracteres (se receber entrada do argumento da função) ou a representação de sequência dessa matriz.
  • A entrada não precisa estar em ordem específica.
  • Pode haver notas duplicadas na entrada. Eles devem ser tratados da mesma maneira que existe apenas um deles.
  • A saída é o nome do acorde. Caso ele produza vários nomes, a mesma regra para entrada se aplica.
  • Se a entrada não for um acorde suportado, imprima as notas como estão. Seu programa também pode suportar outros acordes não listados nas tabelas acima (o que é válido, mas não possui bônus).
  • Você pode usar outras notações listadas no artigo da Wikipedia . Porém, se você escolher CDó maior, deverá adicionar um prefixo legível em ambos os casos para distinguir um acorde com uma única nota.
  • Você não pode usar funções internas para esta tarefa (se houver alguma).
  • Isso é código-golfe. O menor código em bytes vence.

Exemplos

  • Entrada: C D# GSaída: Cm.
  • Entrada: C Eb GSaída: Cm.
  • Entrada: C Eb F#Saída: Cdim.
  • Entrada: F A C#Saída: Faug, Aaug, C#aug, Dbaugou Faug Aaug C#aug, Faug Aaug Dbaugem qualquer ordem.
  • Entrada: F D F F F F A A FSaída: Dm.
  • Entrada: C DSaída: C D.

Bónus

  • -30 se imprime todas, se houver mais de uma interpretação (para agosto, sus4 / sus2 e dim7).
  • -70 se também suporta sétimos acordes.
  • -200 se aceita entrada MIDI e imprime cada acorde que recebeu. Observe que as notas não precisam começar ou terminar ao mesmo tempo. Você decide o que acontece nos estados intermediários (desde que não trate ou pare de funcionar). Você pode assumir que não há notas nos canais de percussão (ou apenas um canal, se for conveniente). É recomendável também fornecer uma versão em texto (ou matriz) para teste, especialmente se for dependente da plataforma.
jimmy23013
fonte
A entrada pode ter planos ou está usando apenas afiada? Notas como B # devem ser manipuladas?
precisa saber é
@feersum Pode ter apartamentos (a menos que você reivindique o bônus de -200). Adicionado alguns exemplos. Você não precisa lidar B#, Cbetc.
jimmy23013
Você diz Csus4 is the same as Gsus2. Eu acho que você quer dizer Csus2 is the same as Gsus4, não é?
Gareth
@Gareth ... Sim. Fixo.
precisa saber é o seguinte

Respostas:

2

Caractere 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

Não estou realmente feliz com isso. Acordes codificados usados.

Uso:

Experimente aqui: Pyth Compiler / Executor . Desative o modo de depuração e use "C D# G"como entrada.

Explicação:

Primeiro alguma preparação:

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

Em seguida, uma função que converte notas em número inteiro

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)

Em seguida, para cada nota, mude a coord e procure-a em uma tabela

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

Perl 5: 183 - 100 = 83

Edit: Consegui cortar alguns caracteres extras, então também alterei os nomes dos acordes, como na solução Python, para poder fingir por um momento que estou 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

Exemplo:

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

Python 2, 335 bytes - 30 - 70 = 235

Primeira tentativa de um golfe um pouco mais longo, por isso posso estar perdendo alguns truques óbvios.

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

Comentários:

  • Usei nomes de acordes alternativos na página Wiki (veja o final da linha longa) para economizar espaço.
  • Os acordes são representados por 3 deslocamentos hexadecimais cada (0 não é necessário, mas é incluído nas tríades para que elas se alinhem).
  • "#". find (n [1:]) funciona porque "#". find ("b") é -1 e "#". find ("") é 0.

Saída de amostra

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