¿Qué acabo de jugar? Traducir digitaciones de guitarra a acordes

22

Relacionado: Música: ¿qué hay en este acorde? , Notas a la tablatura , ¿ Generando tablaturas para guitarra? , Traducir pares de números a notas de guitarra

Dada una digitación de guitarra, emite el acorde que representa. Puede usar la entrada y salida estándar, o escribir una función que devuelva una cadena.

Las digitaciones de entrada se clasificarán como uno de los siguientes acordes, que se expresarán de la siguiente manera (si la nota raíz fuera C):

  • tríada mayor: C
  • tríada menor: Cm
  • (dominante) séptimo: C7
  • séptimo menor: Cm7

El acorde puede estar invertido, por lo que no puede confiar en que la nota más baja sea la raíz. Tampoco puedes confiar en que esto sea una digitación fácil o común en el mundo real. En términos más generales, la salida de su programa debe ignorar las octavas de los tonos y tratar todos los tonos que corresponden a la misma nota musical (es decir, A) como iguales.

Este es el , por lo que gana el código más corto en bytes.

Formato de entrada

La entrada es una serie de 6 valores que indican, para cada cuerda de una guitarra de 6 cuerdas en afinación estándar (EADGBE), en qué traste se tocará esa cuerda. También podría indicar que la cadena no se reproduce en absoluto. El traste "zeroth" también se conoce como la posición abierta, y los números de traste cuentan desde allí. Suponga que la guitarra tiene 21 posiciones de traste, de modo que la posición más alta de traste es el número 20.

Por ejemplo, la entrada X 3 2 0 1 0significa colocar los dedos en las siguientes posiciones en la parte superior del cuello de la guitarra:

(6th) |---|---|---|---|---
      |-X-|---|---|---|---
      |---|---|---|---|---
      |---|-X-|---|---|---
      |---|---|-X-|---|---
(1st) |---|---|---|---|---

y rasgueando las cuerdas segunda a sexta. Corresponde a esta pestaña ASCII :

e |-0-|
B |-1-|
G |-0-|
D |-2-|
A |-3-|
E |---|

Tiene cierta flexibilidad para elegir el tipo de entrada que desea: cada posición de traste se puede expresar como una cadena o un número. Las cuerdas de guitarra que no se tocan se indican comúnmente con un X, pero puede elegir un valor centinela diferente si eso lo hace más fácil para usted (como -1si usa números). La serie de 6 posiciones de traste se puede ingresar como cualquier lista, matriz o tipo de secuencia, una sola cadena separada por espacios o como entrada estándar, una vez más, usted elige.

Puede confiar en la entrada correspondiente a uno de los 4 tipos de acordes mencionados anteriormente.

Explica en tu publicación qué forma de entrada toma tu solución.

Formato de salida

Debe devolver o imprimir en la salida estándar una cadena que describa el acorde para el que es digitación. Esta cadena se compone de dos partes concatenadas juntas. La capitalización importa. Se permite el espacio en blanco al final.

La primera parte indica el nota fundamental , uno de A, A#/ Bb, B, C, C#/ Db, D, D#/ Eb, E, F, F#/ Gb, Go G#/ Ab. (Estoy usando en #lugar de , y en blugar de , para evitar requerir Unicode.) Las notas de raíz que se pueden expresar sin un agudo o plano deben expresarse sin ellas (nunca emitir B#,Fb o Dbb); los que no pueden expresarse con un solo símbolo agudo o plano (es decir, uno C#o Db, pero nunca B##). En otras palabras, debe minimizar el número de accidentes (objetos punzantes o planos) en el nombre de la nota.

La segunda parte indica el tipo de acorde, ya sea vacío para una tríada mayor, mpara una tríada menor, 7para la séptima dominante o m7para la séptima menor. Entonces, un G mayor se emite simplemente como G, mientras que un séptimo menor D♯ se puede generar como D#m7o Ebm7. Se pueden encontrar más ejemplos en los casos de prueba al final.

Teoría y sugerencias

Notas musicales

La escala cromática tiene 12 tonos por octava. Cuando se ajusta a un temperamento igual, cada uno de estos tonos está igualmente distante de sus vecinos 1 . Los tonos que están separados por 12 semitonos (una octava) se consideran la misma nota musical. Esto significa que podemos tratar notas como números enteros módulo 12, de 0 a 11. Siete de ellos reciben nombres de letras 2 de A a G. Esto no es suficiente para nombrar los 12 tonos, pero al agregar correcciones accidentales que: agregar un ♯ ( sostenido) a una nota lo hace un semitono más alto, y agregar un ♭ (plano) lo hace un semitono más bajo.

Acordes

Un acorde son 2 o más notas tocadas juntas. El tipo de acorde depende de las relaciones entre las notas, que pueden determinarse por las distancias entre ellas. Un acorde tiene una nota raíz, como se mencionó anteriormente. Trataremos la nota raíz como 0 en estos ejemplos, pero esto es arbitrario, y todo lo que importa en este desafío es la distancia entre notas en módulo aritmético. Siempre habrá un tipo de acorde único para la respuesta, ya sea una tríada o un séptimo acorde . La nota raíz no siempre será el tono de frecuencia más baja; elija la nota raíz de modo que pueda describir el acorde como uno de los cuatro tipos de acordes siguientes:

  • Una tríada importante es un acorde con las notas.0 4 7 .
  • Una tríada menor es un acorde con las notas.0 3 7 .
  • Un séptimo acorde dominante (o mayor / menor) tiene las notas 0 4 7 10.
  • Un séptimo acorde menor (o menor / menor) tiene las notas 0 3 7 10. 3

Afinación de guitarra

La afinación estándar en una guitarra de 6 cuerdas comienza con E en la cuerda más baja, y luego toca notas a intervalos de 5, 5, 5, 4, luego 5 semitonos subiendo las cuerdas. Tomando la E más baja como 0, esto significa que rasguear todas las cuerdas de la guitarra le da tonos numerados 0 5 10 15 19 24, que es equivalente al módulo 12 0 5 10 3 7 0, o las notas E A D G B E.

Ejemplos trabajados

Si su entrada es 0 2 2 0 0 0, esto corresponde a las notas E B E G B E, por lo que solo E, B y G. Estas forman el acorde Em, que se puede ver al numerarlas con la raíz como E, dándonos 0 3 7. (El resultado sería el mismo para X 2 X 0 X 0, o12 14 14 12 12 12 .)

Si su entrada es 4 4 6 4 6 4, numerarlos con una raíz de C♯ da7 0 7 10 4 7 , o 0 4 7 10, entonces la respuesta es C#7(o Db7). Si fuera así 4 4 6 4 5 4, la numeración daría 7 0 7 10 3 7, o 0 3 7 10, que es C#m7(o Dbm7).

Casos de prueba

X 3 2 0 1 0  --->  C
0 2 2 0 0 0  --->  Em
X 2 X 0 X 0  --->  Em
4 4 6 4 6 4  --->  C#7  (or Db7)
4 4 6 4 5 4  --->  C#m7 (or Dbm7)
0 2 2 1 0 0  --->  E
0 0 2 2 2 0  --->  A
X X 4 3 2 2  --->  F#   (or Gb)
3 2 0 0 0 1  --->  G7
X X 0 2 1 1  --->  Dm7
3 3 5 5 5 3  --->  C
4 6 6 5 4 4  --->  G#   (or Ab)
2 2 4 4 4 5  --->  B7
0 7 5 5 5 5  --->  Am7
7 6 4 4 X X  --->  B
8 6 1 X 1 3  --->  Cm
8 8 10 10 9 8 -->  Fm
0 19 5 16 8 7 -->  Em
6 20 0 3 11 6 -->  A#   (or Bb)
X 14 9 1 16 X -->  G#m  (or Abm)
12 14 14 12 12 12 --> Em
15 14 12 12 12 15 --> G
20 X 20 20 20 20  --> Cm7
X 13 18 10 11 10  --> A#7 (or Bb7)

1 por los logaritmos de sus frecuencias

2 o, en solfeo , nombres como do, re, mi . En este desafío, usa los nombres de las letras.

3 Esto también podría llamarse un acorde de sexto mayor, con una elección diferente de nota raíz. En este desafío, llámalo por su séptimo nombre menor.

Dan Getz
fuente
3
¡Gran reto!
Luis Mendo
1
Tentado a cerrar como un embaucado de mi futuro desafío: D (tenía un desafío muy similar en mente, pero fue obvio más rápido)
Fallo el
¿Se permite el espacio en blanco al final de la cadena de salida?
Luis Mendo
@LuisMendo seguro; esta bien.
Dan Getz
1
@officialaimm no, no necesita manejar ninguna otra situación. Puede suponer que siempre será uno de esos 4 tipos de acordes. En otras palabras, su código puede hacer lo que quiera (incluyendo error o dar una respuesta incorrecta) si obtiene un acorde diferente.
Dan Getz el

Respuestas:

9

MAT , 115 114 bytes

[OAXICO]+tZN~)Y@!"@t1)XH- 12\XzXJK7hm?O.]JI7hm?'m'.]J[KCX]m?'7'.]J[ICX]m?'m7'.]]'FF#GG#AA#BCC#DD#E'l2741B~QY{HX)wh

El formato de entrada es [N 3 2 0 1 0], donde Nindica una cadena no utilizada.

La cadena de salida siempre usa #, no b.

Pruébalo en línea! O verifique todos los casos de prueba, en dos partes para evitar que el compilador en línea agote el tiempo de espera:

Explicación

[OAXICO]            % Push [0 5 10 3 7 0]. This represents the pitch of each open
                    % string relative to the lowest string, modulo 12
+                   % Add to implicit input. May contain NaN's, for unused strings
tZN~)               % Remove NaN's
Y@!                 % Matrix of all permutations, each in a column
"                   % For each column
  @                 %   Push current column
  t1)               %   Duplicate and get first entry
  XH                %   Copy into clipboard H
  - 12\             %   Subtract. This amounts to considering that the first note
                    %   of the current permutation is the root, and computing
                    %   all intervals with respect to that
  12\               %   Modulo 12
  Xz                %   Remove zeros
  XJ                %   Copy into clipboard J
  K7hm?             %   Are all intervals 4 or 7? If so: it's a major chord
    O               %     Push 0 (will become space when converted to char)
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  I7hm?             %   Are all intervals 3 or 7? If so: it's a minor chord
    'm'             %     Push this string
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  [KCX]m?           %   Are all intervals 4, 7 or 10? If so: it's a dominant-7th
                    %   chord
    '7'             %     Push this string
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  [ICX]m?           %   Are all intervals 3, 7 or 10? If so: it's a minor 7th chord
    'm7'            %     Push this string
    .               %     Break for loop
  ]                 %   End if
]                   % End for. The loop is always exited via one of the 'break'
                    % statements. When that happens, the stack contains 0, 'm',
                    % '7' or 'm7', indicating the type of chord; and clipboard H
                    % contains a number that tells the root note using the lowest 
                    % string as base (1 is F, 2 is F# etc)
'FF#GG#AA#BCC#DD#E' % Push this string. Will be split into strings of length 1 or 2
l                   % Push 1
2741B~Q             % Push [1 2 1 2 1 2 1 1 2 1 2 1] (obtained as 2741 in binary,
                    % negated, plus 1)
Y{                  % Split string using those lengths. Gives a cell array of
                    % strings: {'F', 'F#', ..., 'E'}
H                   % Push the identified root note
X)                  % Index into cell array of strings
wh                  % Swap and concatenate. Implicitly display
Luis Mendo
fuente
4

Archivo .COM de MS-DOS (179 bytes)

El archivo (aquí mostrado como HEX):

fc be 81 00 bf 72 01 31 db b9 06 00 51 e8 73 00
59 e2 f9 b9 0c 00 be 48 01 ad 39 c3 74 0d 40 75
f8 d1 fb 73 03 80 c7 08 e2 ec c3 31 db 88 cb 8a
87 59 01 e8 42 00 8a 87 65 01 e8 3b 00 81 c6 08
00 ac e8 33 00 ac eb 30 91 00 89 00 91 04 89 04
ff ff 00 00 6d 00 37 00 6d 37 42 41 41 47 47 46
46 45 44 44 43 43 00 23 00 23 00 23 00 00 23 00
23 00 04 09 02 07 0b 04 84 c0 74 06 b4 02 88 c2
cd 21 c3 8a 0d 47 ac 3c 20 76 fb 30 ed 3c 41 73
22 2c 30 72 0b 86 c5 b4 0a f6 e4 00 c5 ac eb ed
88 e8 00 c8 30 e4 b1 0c f6 f1 88 e1 b8 01 00 d3
e0 09 c3

La entrada se da a través de la línea de comando. ¡La entrada no válida conducirá a un comportamiento no válido del programa!

El código del ensamblador se ve así:

.text
.code16
ComFileStart:
    cld
    mov $0x81, %si
    mov $(TuneTable-ComFileStart+0x100), %di
    xor %bx, %bx
    # 6 strings: Build the mask of played tones
    mov $6, %cx
NextStringRead:
    push %cx
    call InsertIntoMask
    pop %cx
    loop NextStringRead

    # Check all base tones...
    mov $12, %cx
TestNextTone:
    mov $0x100+ChordTable-ComFileStart, %si
TestNextChord:
    lodsw
    # Is it the chord we are searching for?
    cmp %ax, %bx
    je FoundChord 
    # Is it the end of the table?
    inc %ax
    jnz TestNextChord
    # Transpose the chord we really play
    # and go to the next tone
    # This code rotates the low 12 bits of
    # BX one bit right
    sar $1, %bx
    jnc NoToneRotated
    add $8, %bh
NoToneRotated:
    loop TestNextTone
EndOfProgram:
    ret

FoundChord:
    # Get and print the tone name
    xor %bx, %bx
    mov %cl, %bl
    mov (ToneNamesTable+0x100-1-ComFileStart)(%bx),%al
    call printChar
    mov (ToneNamesTable+0x100+12-1-ComFileStart)(%bx),%al
    call printChar
    # Get the chord name suffix and print it
    add $(ChordNamesTable-ChordTable-2),%si
    lodsb
    call printChar
    lodsb
    # Note: Under MS-DOS 0x0000 is the first word on
    # the stack so the "RET" of printChar will jump
    # to address 0x0000 which contains an "INT $0x21"
    # (end of program) instruction
    jmp printChar

ChordTable:
    # Major, Minor, Major-7, Minor-7
    .word 0x91, 0x89, 0x491, 0x489, 0xFFFF
ChordNamesTable:
    .byte 0,0,'m',0,'7',0,'m','7'
ToneNamesTable:
    .ascii "BAAGGFFEDDCC"
    .byte 0,'#',0,'#',0,'#',0,0,'#',0,'#',0
TuneTable:
    .byte 4,9,2,7,11,4

#
# Subfunction: Print character AL;
#              Do nothing if AL=0
#
printChar:
    test %al, %al
    jz noPrint
    mov $2, %ah
    mov %al, %dl
    int $0x21
noPrint:
    ret

#
# Subfunction: Get one finger position
#              and insert it into a bit mask
#              of tones being played
#
# Input:
#
#   [DS:DI] = 
#        Tuning of current string (0=C, 1=C#, ..., 11=B)
#        Actually only 2=D, 4=E, 7=G, 9=A and 11=B are used
#
#   DS:SI = Next character to read
#
#   DF = Clear
#
# Input and Output:
#
#    BX = Bit mask
#    DI = Will be incremented
#
# Destroys nearly all registers but SI and BX
#
InsertIntoMask:
    mov (%di), %cl
    inc %di
SkipSpaces:
    lodsb
    cmp $' ', %al
    jbe SkipSpaces
# Now evaluate each digit
    xor %ch, %ch
GetNextDigit:
    # Number = 10*Number+Digit
    cmp $'A', %al
    jae DigitIsX
    sub $'0', %al
    jb DigitsDone
    xchg %al, %ch
    mov $10, %ah
    mul %ah
    add %al, %ch
    lodsb
    jmp GetNextDigit
DigitsDone:
    # Add the tune of the string
    # and perform modulus 12
    mov %ch, %al
    add %cl, %al
    xor %ah, %ah
    mov $12, %cl
    div %cl
    mov %ah, %cl
    mov $1, %ax
    shl %cl, %ax
    or %ax, %bx
DigitIsX:
    ret

Casos de prueba:

6 20 0 3 11 6 -->  A#   (or Bb)

Ya vi a dos pianistas tocando juntos "cuatro manos" en un piano.

¡Este caso de prueba es la primera vez que leo sobre guitarristas haciendo esto!

¡Incluso con golpes con la mano derecha no puedes tocar un cable como este!

Martin Rosenau
fuente
Hmm, ¿tal vez un calamar podría tocar ese acorde? Creo que es uno de los que encontré mediante una búsqueda aleatoria para que pudiera haber algunos casos de prueba "difíciles".
Dan Getz
3

Rubí, 129 bytes

Como la versión anterior, pero utiliza un solo bucle, con operador ternario para secuenciar entre el paso de análisis y el paso de salida. Se requirieron algunas otras modificaciones menores para que esto funcione.

->a{r=0
18.times{|j|j<6?a[j]&&r|=8194<<(6--~j%5+a[j]*7)%12:(r/=2)&11==3&&puts("CGDAEBF"[j%7]+?#*(j/13)+['',?m,?7,'m7'][r>>9&3])}}

Rubí, 136 bytes

La función Llamda acepta una matriz de 6 números como argumento y se envía a stdout. La cadena no utilizada se representa con un valor falso (los únicos valores falsos en ruby ​​son nily false.)

->a{r=0
6.times{|j|a[j]&&r|=4097<<(6--~j%5+a[j]*7)%12}
12.times{|j|r&11==3&&puts("FCGDAEB"[j%7]+?#*(j/7)+['',?m,?7,'m7'][r>>9&3]);r/=2}}

Explicación

Utilizo una representación de los 12 tonos basados ​​en el círculo de quintas . Esto significa que cada tono es seguido por el tono 7 semitonos más alto (o 5 semitonos más abajo) dando la secuenciaF C G D A E B F# C# G# D# A# . Hay 2 ventajas para esto. Una es que todos los objetos punzantes aparecen juntos. La otra es que las notas de cuerda abierta del bajo de 5 cuerdas aparecen juntas: GDAEB (la guitarra está relacionada pero es un poco más compleja, ver más abajo).

El primer ciclo se ejecuta 6 veces. La expresion6--~j%5 (equivalentemente 6-(j+1)%5) da los valores de las notas de las cuerdas al aire: E=5 A=4 D=3 G=2 B=6 E=5. A esto agregamos el número de traste multiplicado por 7 (como se puede ver arriba, agregando un semitono nos mueve 7 lugares hacia adelante en la secuencia). Luego tomamos todo el módulo 12 y hacemos un mapa de bits de las notas que están presentes (nosotros use 4097<<note valuepara dar 2 octavas consecutivas.)

Una vez compuesto el mapa de bits, estamos listos para buscar el acorde y generarlo.

Nos interesan las siguientes notas:

Note       position in      position in             Note      position in 
           semitone domain  circle of fifths                  circle of fifths 
Root       0                0                       Root      0
Minor 3rd  3                9                       Fifth     1
Major 3rd  4                4                       Sixth     3
Fifth      7                1                       Major 3rd 4
Sixth      9                3                       Minor 3rd 9
Minor 7th  10               10                      Minor 7th 10

Comenzando por verificar el acorde F, probamos para ver si la raíz y la quinta están presentes: bits 0 y 1 (contando desde el menos significativo: los bits 1 y 2). Para rechazar los acordes sextos, también debemos verificar que el sexto está ausente: bit 3 (bit de 8), así que lo comprobamos r&&11==3y, si es así, imprimimos el acorde.

Ignoramos el tercio mayor y confiamos completamente en el bit 9 (tercio menor) y el bit 10 (séptimo menor) para resolver el tipo de acorde. La expresionr>>9&3 se utiliza para elegir el tipo de acorde correcto de una matriz.

Al final del ciclo, desplazamos el mapa de bits un bit r/=2hacia la derecha para probar las posibles raíces de acordes en secuencia:F C G D A E B F# C# G# D# A# .

Sin golf en el programa de prueba

f=->a{                            #Accept array of 6 numbers as argument.
  r=0                             #Setup an empty bitmap.

  6.times{|j|                     #For each string
    a[j]&&                        #if the fret value is truthy (not nil or false)
    r|=4097<<(6--~j%5+a[j]*7)%12  #calculate the note value in the circle of fifths and add to the bitmap.
  }

  12.times{|j|                    #For each possible root note
    r&11==3&&                     #if root and fifth are present (bits 0 and 1) and sixth is absent (bit 3) 
    puts("FCGDAEB"[j%7]+?#*(j/7)+ #output the note name and a sharp symbol if necessary, followed by
    ['',?m,?7,'m7'][r>>9&3])      #m and/or 7 as indicate by bits 9 and 10.
    r/=2
  }
}

print 1;f[[nil,3,2,0,1,0]]       #  C
print 2;f[[0,2,2,0,0,0]]         #  Em
print 3;f[[nil,2,nil,0,nil,0]]   #  Em
print 4;f[[4,4,6,4,6,4]]         #  C#7 
print 5;f[[4,4,6,4,5,4]]         #  C#m7 
print 6;f[[0,2,2,1,0,0]]         #  E
print 7;f[[0,0,2,2,2,0]]         #  A
print 8;f[[nil,nil,4,3,2,2]]     #  F#  
print 9;f[[3,2,0,0,0,1]]         #  G7
print 10;f[[nil,nil,0,2,1,1]]    #  Dm7
print 11;f[[3,3,5,5,5,3]]        #  C
print 12;f[[4,6,6,5,4,4]]        #  G#  
print 13;f[[2,2,4,4,4,5]]        #  B7
print 14;f[[0,7,5,5,5,5]]        #  Am7
print 15;f[[7,6,4,4,nil,nil]]    #  B
print 16;f[[8,6,1,nil,1,3]]      #  Cm
print 17;f[[8,8,10,10,9,8]]      #  Fm
print 18;f[[0,19,5,16,8,7]]      #  Em
print 19;f[[6,20,0,3,11,6]]      #  A#  
print 20;f[[nil,14,9,1,16,nil]]  #  G#m 
print 21;f[[12,14,14,12,12,12]]  #  Em
print 22;f[[15,14,12,12,12,15]]  #  G
print 23;f[[20,nil,20,20,20,20]] #  Cm7
print 24;f[[nil,13,18,10,11,10]] #  A#7
Level River St
fuente
2

Javascript (ES6), 335 333 bytes

Me encanta este desafío y PPCG SE! Este es mi primer campo de golf. Las sugerencias son bienvenidas, ya que estoy seguro de que podrían mejorar mucho. (eliminó 2 bytes ya que había incluido f = en el recuento)

La función ftoma una serie de cadenas, que representan números y 'X', me gusta f(['X','3','2','0','1','0'])y devuelve un acorde (natural o nítido) como E#m7. Nuevas líneas agregadas para mayor claridad (no incluidas en el recuento de bytes)

f=c=>[s=new Map([[435,''],[345,'m'],[4332,7],[3432,'m7']]),
n=[...new Set(c.map((e,i)=>e?(+e+[0,5,10,3,7,0][i])%12:-1)
.filter(e=>++e).sort((a,b)=>a>b))],d=[...n,n[0]+12].reduce(
(a,c,i)=>i?[...a,(c-n[i-1]+12)%12]:[],0).join``.repeat(2),
m=+d.match(/(34|43)(5|32)/g)[0],'E0F0F#0G0G#0A0A#0B0C0C#0D0D#'
.split(0)[n[d.indexOf(m)]]+s.get(m)][4]

Ejemplo de uso:

console.log(f(['0','2','2','0','0','0'])); // Em

Para ejecutar casos de prueba:

tests=`X 3 2 0 1 0 ---> C
0 2 2 0 0 0 ---> Em
X 2 X 0 X 0 ---> Em
4 4 6 4 6 4 ---> C#7 (or Db7)
4 4 6 4 5 4 ---> C#m7 (or Dbm7)`; // and so on...

tests.split`\n`.forEach(e=>{
    console.log(`Test: ${e}
      Result: ${f(e.split(' ').slice(0,6))}`)
})

Versión sin golf con explicación:

f = (c) => {
    s = new Map([
        [435,''], [345,'m'], [4332,7], [3432,'m7'] 
    ]) /* Each key in s describes the intervals (semitones)
          between consecutive notes in a chord, when it is
          reduced to a single octave, including the interval
          from highest back to lowest. The values describe
          the corresponding chord suffix. E.g. C-E-G has
          intervals C-4-E-3-G-5-C. 435=major=no suffix. */

    n = [ ...new Set(
        c.map( 
         (e,i) => e ? ( +e + [0,5,10,3,7,0][i] )%12 : -1 
         ).filter( (e) => ++e ).sort( (a,b) => a>b )
        ) ] /* take the input array, c, and transform each fret
               position into a note. remove non-notes (-1), sort
               in tone order, remove duplicates. An input of
               positions X 13 18 10 11 10 becomes notes
               (-1) 6 4 1 6 10 then 1 4 6 10. */

    d = [ ...n, n[0] + 12 ].reduce(
        (a,c,i) => i ? [ ...a, (c - n[i-1] + 12)%12 ] : [], 0
    ).join``.repeat(2)
    /* convert the note array, n, into an interval string, d,
       including the lowest note repeated above it to capture
       all intervals. Repeat it twice so that, regardless of the
       inversion played, the intervals will appear in root order
       somewhere. E.g. notes 1-4-6-10 and 13 (1+12)
       become intervals 3 2 4 3, and string for searching
       32433243 */

    m = +d.match( /(34|43)(5|32)/g )[0];
      /* m is the matched chord pattern. In this case, 4332. */

    return 'E0F0F#0G0G#0A0A#0B0C0C#0D0D#'.split(0)[
    n[ d.indexOf(m) ]
    /* get the position in the interval string where the root
       interval first occurs. this corresponds to the position
       of the chord root note in the note array, n. convert this
       number 0-12 to a note name E - D# */
    ] + s.get(m)
       /* add the suffix corresponding to the matched
       chord interval pattern */
}
Chris M
fuente
1
Bienvenido al sitio! Me alegra saber que lo disfrutas. :) Desafortunadamente, no conozco ningún JS, así que no tengo ningún consejo, pero es posible que puedas encontrar algunos aquí
DJMcMayhem