Traduzir pares de números em notas de guitarra

18

Um diagrama do braço da guitarra fica assim:

  0  1  2  3  4  5  6  7  8  9 10 11 12   <- Fret number (0 means it's open)
|-E--F--F#-G--G#-A--A#-B--C--C#-D--D#-E
|-B--C--C#-D--D#-E--F--F#-G--G#-A--A#-B 
|-G--G#-A--A#-B--C--C#-D--D#-E--F--F#-G
|-D--D#-E--F--F#-G--G#-A--A#-B--C--C#-D
|-A--A#-B--C--C#-D--D#-E--F--F#-G--G#-A
|-E--F--F#-G--G#-A--A#-B--C--C#-D--D#-E

Como você pode ver, a primeira string (de cima) aberta é um E. O primeiro traste da primeira corda é um F. O quarto traste na terceira corda é a B. Note que a primeira nota é o traste zeroth, não a primeira.

Isso pode ser escrito com números no formato string, fret. As seqüências são numeradas de 1 a 6, de cima para baixo. Os trastes são numerados de 0 a 12 da esquerda para a direita. O primeiro Eé, portanto 1, 0. Alguns outros exemplos:

1, 0 --> E
1, 1 --> F
3, 5 --> C
5, 1 --> A# 
6, 6 --> A#

Desafio:

Pegue Npares de números ( se f) e produza uma sucessão de notas delimitada.

  • A entrada pode estar em qualquer formato adequado. tuplas, matriz 2D, duas listas separadas, uma lista entrelaçada (corda, traste, corda, traste ...) etc.
  • O tom de saída deve ser separado, mas o delimitador é opcional (vírgula, espaço, traço ...). A saída pode estar em maiúsculas ou minúsculas.
  • s(para string) estará no intervalo [1, 6](você pode optar por indexar i 0)
  • f (por tras) estará na faixa [0, 12]

Casos de teste e exemplos:

1 4 5 2 1 3   <- String
4 2 6 3 5 1   <- Fret
G# E D# D A G#

6 2 3 1 4 2 3 2 2 2 6 5 2
0 1 2 3 4 5 6 7 8 9 10 11 12
E C A G F# E C# F# G G# D G# B  

3 3 3 3 3 3 3 3 3 3 3 3 3   <- String
0 3 5 0 3 6 5 0 3 5 3 0 0   <- Fret
G A# C G A# C# C G A# C A# G G     

// The same test case, but different input and output format:
(3,0)(3,3)(3,5)(3,3)(3,6)(3,5)(3,0)(3,3)(3,5)(3,3)(3,0)(3,0)    
G,A#,C,G,A#,C#,C,G,A#,C,A#,G,G     

Boa sorte e feliz golfe!

Stewie Griffin
fonte
Não é guitarrista (nem mesmo músico decente), mas não há uma omissão significativa aqui, se você está esperando uma saída como músicas reconhecíveis? Ou seja, a duração da nota - inteiras, semínimas, semínimas, etc.
Jamesqf 27/09/16
1
@jamesqf Não, está perfeitamente bem desde que você conheça a música. Atualmente, é a música mais popular em ultimate-guitar.com . Dê uma olhada na introdução.
Stewie Griffin

Respostas:

4

05AB1E , 48 47 43 40 bytes

Usa a codificação CP-1252 .

Ambas as cordas e os trastes são baseados em 0.

v7YT5¾7)y`Šè+•™ÎÚ,Ülu•žh'#A«‡•7V3•3BS£è,

Explicação

v                                # for each pair in input
 7YT5¾7)                         # the list [7,2,10,5,0,7]
 y`                              # flatten the pair [string, fret] and places on stack
 Šè                              # index into the list above using the string
 +                               # add the fret
 •™ÎÚ,Ülu•žh'#A«‡•7V3•3BS£       # list of accords
 è                               # index into the string using the number calculated above
 ,                               # print

Experimente online!

Economizou 7 bytes graças a Adnan

Emigna
fonte
1
Explorar bugs é muito divertido! .-)
Luis Mendo
"AA#BCC#DD#EFF#GG#"•7V3•3BS£em vez de "A A# B C C# D D# E F F# G G#"#é alguns bytes mais curto :).
Adnan
@Adnan: Ooh, boa base de troca :)
Emigna
Também uma versão compactada da "AA#BCC#DD#EFF#GG#"string: •™ÎÚ,Ülu•žh'#A«‡(uma vez que letras minúsculas são permitidas: p).
Adnan
9

JavaScript (ES6), 79 70 bytes

a=>a.map(([s,f])=>"AA#BCC#DD#EFF#GG#".match(/.#?/g)[(s*7+(s>2)+f)%12])

Requer seqüências baseadas em 1. Editar: salvou 9 bytes calculando diretamente a conversão de string para traste, com base na resposta antiga do @ nimi.

Neil
fonte
@ Arnauld Obrigado, mas acabei me apropriando da resposta de @ nimi.
Neil
Muito mais eficiente, de fato;)
Arnauld
Esperto. resposta muito furtiva
Rohan Jhunjhunwala
7

Mathematica, 62 bytes (não concorrente)

<<Music`;MusicScale[100(#2+{24,19,15,10,5,0}[[#]])&@@@#,E2,9]&

O {24,19,15,10,5,0}e o E2representam os tons de corda aberta das seis cordas da guitarra (por exemplo, a corda superior tem 24 semitons acima da nota E2). Não competir porque não imprime os nomes das notas - toca a sequência das notas! (somente se você tiver o Mathematica, infelizmente) Por exemplo,

<<Music`;MusicScale[100(#2+{24,19,15,10,5,0}[[#]])&@@@#,E2,9]&@
 {{4,0},{3,2},{2,3},{1,2},{5,0},{4,2},{3,2},{2,2},
  {5,2},{4,4},{2,0},{2,3},{6,2},{4,4},{3,2},{2,2},
  {6,3},{4,0},{3,0},{2,0},{4,0},{4,4},{3,2},{2,3},
  {6,3},{3,0},{2,0},{2,3},{5,0},{4,2},{3,2},{2,2},{4,0}}

toca as 4 barras de abertura da Canon de Pachelbel. (que é o máximo que posso da Canon de Pachelbel)

Greg Martin
fonte
7

MATL , 48 47 45 bytes

Obrigado a @Emigna pela correção em relação ao formato da entrada.

Guitarra e código de golfe ... Eu tive que responder a esta!

'$)-27<'i)-'F F# G G# A A# B C C# D D#

O formato de entrada é: uma matriz de seqüência de caracteres (com base em 1) e, em seguida, uma matriz de trastes (com base em 0).

Experimente online!

Explicação

Alguns recursos de idioma usados ​​nesta resposta:

  • Uma string é automaticamente convertida em uma matriz numérica de pontos de código ASCII quando alguma operação aritmética é aplicada a ela.
  • Operações aritméticas funcionam em elementos , isto é, vetorizadas. Portanto, a subtração de uma string e uma matriz numérica do mesmo tamanho fornece uma matriz com a subtração das entradas correspondentes.
  • A indexação é baseada em 1 e modular .
  • Uma matriz de células é como uma lista em outros idiomas. Pode conter elementos arbitrários, possivelmente matrizes de diferentes tipos ou tamanhos. Aqui, uma matriz de células será usada para armazenar cadeias de tamanhos diferentes (os nomes das notas).

Código comentado:

'$)-27<'                       % Push this string
i                              % Take first input (array of guitar strings)
)                              % Index into the string. For example, input [1 3] gives
                               % the string '$-' (indexing is 1-based)
-                              % Implicitly take second input (array of guitar frets).
                               % Subtract element-wise. This automatically converts the
                               % previous string into an array of ASCII codes. For
                               % example, second input [1 5] gives a result [-35 -40],
                               % which is [1 5] minus [36 45], where 36 and 45 are the
                               % ASCII codes of '$-' 
'F F# G G# A A# B C C# D D# E' % Push this string
Yb                             % Split at spaces. Gives a cell array of 12 (sub)strings:
                               % {'F', 'F#', 'G', ..., 'E'}
w)                             % Swap and index into the cell array of strings.
                               % Indexing is 1-based and modular. In the example, since
                               % the cell array has 12 elements, the indexing array
                               % [-35 -40] is the same [1 8], and thus it gives a 
                               % (sub-)array formed by the first and eighth cells: 
                               % {'F', 'C'}. This is displayed as the cells' contents,
                               % one per line
Luis Mendo
fonte
1
Eu sabia que ia encontrar uma resposta de você assim que eu vi a palavra "guitarra"
Suever
1
@LuisMendo Very nice! Gosto da doçura ASCII-char índice :)
Emigna
4

Java, 174

String f(int[]s,int[]f){String o="";for(int i=0;i<s.length;++i){int n =(7*s[i]-7+f[i]+(s[i]>2?1:0))%12*2;o+="E F F#G G#A A#B C C#D D#".substring(n,n+2).trim()+" ";}return o;}

Ungolfed:

  String f(int[] s, int[] f) {
    String o = "";
    for (int i = 0; i < s.length; ++i) {
      int n = (7 * s[i] - 7 + f[i] + (s[i] > 2 ? 1 : 0)) % 12 * 2;
      o += "E F F#G G#A A#B C C#D D#".substring(n, n + 2).trim() + " ";
    }
    return o;
  }

fonte
3

C, 104 103 bytes

main(s,f){for(;~scanf("%d%d",&s,&f);printf("%.2s\n",
"E F F#G G#A A#B C C#D D#"+(f+7*~-s+(s>2))%12*2));}

Pega números como string fretpares em stdin e emite a nota após cada par. Por exemplo:

1 4
G#
4 2
E 
5 6
D#
2 3
D 
orlp
fonte
3

Ruby, 63 bytes

leva uma matriz de matrizes de 2 elementos, na ordem [string,fret].

->x{x.map{|i|"BEADGCF"[6-n=((i[0]-3)%5+2+i[1]*7)%12]+?#*(n/7)}}

Explicação

Na afinação padrão, o violão é um dos poucos instrumentos de corda (curvados ou trastes) que possui intervalos inconsistentes entre as cordas. A maioria possui um intervalo consistente de 5 semitons entre todos os pares de cadeias adjacentes (um "quarto") ou um intervalo consistente de 7 semitons entre todos os pares de cadeias adjacentes (um "quinto"). Eles correspondem a taxas de frequência de 3: 4 e 2: 3, respectivamente, e são secundários em importância apenas para a "oitava" com taxa de frequência 1: 2.

A guitarra tem intervalos principalmente de 5 semitons. Se tivesse 5 delas, teria uma diferença de 25 semitons entre a 1ª e a 6ª corda. Em vez disso, o intervalo entre a 2ª e a 3ª corda é reduzido para 4 semitons, dando uma diferença de 24 semitons (2 oitavas), o que é melhor para tocar acordes.

Isso é inconveniente para o programa, por isso começamos alterando a entonação de guitarra indexada em 1 em entonação de 5 cordas e baixo indexada em 0, que possui todos os intervalos de 5 semitons:

formula (i[0]-3)%5
Before                            After
String      6 5 4 3 2 1           String 4 3 2 1 0
Note        E A D G B E           Note   B E A D G

Em seguida, adicionamos 2 e ajustamos um baixo fictício de 12 cordas, com entonação das cordas abertas da seguinte maneira, e todos os intervalos são 5 semitons (existem 12 "baixos" de cordas), mas não tenho certeza de que existem muitos com exatamente isso. sintonia.)

String       11 10 9  8  7  6  5  4  3  2  1  0 
Note         A# D# G# C# F# B  E  A  D  G  C  F

Como pode ser visto, todos os objectos cortantes estão agrupados. Esse padrão pode ser repetido ad infinitum. É conhecido como o "ciclo das quintas" e é fundamental para a escala musical Western (com um pouco de ajuste de ajuste do círculo pode ser fechada devido ao fato de que (3/2)**12e 2**7são números muito semelhantes.

Agora lidamos com o parâmetro fret. Ao contrário de muitas outras respostas aqui, que traduzem o parâmetro de string em um número de trastes, eu traduzo o parâmetro de traste em um número de strings. Na tabela acima, pode-se ver que adicionar 7 ao número da string nos coloca em uma string cujo nome da nota é um semitom maior. (Está em uma oitava completamente diferente, mas isso não importa.) Portanto, adicionamos i[1]*7ao número da string e o modulamos 12:

n=(i[0]-3)%5+2+i[1]*7)%12

Subtraímos isso de 6 para obter um número no intervalo de 6 a -5 e procuramos a letra BEADGCF(Ruby permite que índices negativos retornem ao final da matriz.) Se n>=7precisarmos adicionar um #símbolo para concluir a saída .

Programa de teste

f=->x{x.map{|i|"BEADGCF"[6-n=((i[0]-3)%5+2+i[1]*7)%12]+?#*(n/7)}}

z=[[6, 2, 3, 1, 4, 2, 3, 2, 2, 2, 6,5,2],[0, 1, 2, 3, 4 ,5 ,6 ,7, 8, 9, 10, 11, 12]].transpose

puts f[z]

Resultado

E
C
A
G
F#
E
C#
F#
G
G#
D
G#
B
Level River St
fonte
3

C #, 131 bytes

string n(int[]s,int[]f){return string.Join(" ",s.Zip(f,(x,y)=>"E,F,F#,G,G#,A,A#,B,C,C#,D,D#".Split(',')[(7*x-7+y+(x<3?0:1))%12]));}

Insira duas listas separadas, as strings são baseadas em 1.

Taco
fonte
1
Bem vindo ao site! Ótima primeira resposta.
DJMcMayhem
@DJMcMayhem: Obrigado :-)
Taco
1

Clora , 55 bytes

@T[0,7,2,10,5,0,7]+N%12@T[,A,A#,B,C#,D,D#,E,F,F#,G,G#]!

Explicação

@ modo numérico (leia a entrada como números)

T[0,7,2,10,5,0,7] Transformar entrada usando o array, ex array [Input]

+N Adicione N (próximo valor de entrada) à entrada atual

%12 Módulo 12 o valor atual de entrada

@ Sinalizar modo numérico desativado

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Traduzir a entrada em uma matriz

! Usar entrada como valor de saída

OPSXCQ
fonte
1

Java 7 197, 163 bytes

void f(int[]s,int[]f){String[]l={"A","A#","B","C","C#","D","D#","E","F","F#","G","G#"};int[]d={0,7,2,10,5,0,7};int j=0;for(int i:s)out.print(l[(d[i]+f[j++])%12]);}

Ungolfed

  void f(int[]s,int[]f){
 String[]l={"A","A#","B","C","C#","D","D#","E","F","F#","G","G#"};
int[]d={0,7,2,10,5,0,7};
    int j=0;
    for(int i:s)
        out.print(l[(d[i]+f[j++])%12]);



}
Numberknot
fonte
0

Python 2, 94, 91 , 88 bytes

for s,f in input():print"A A# B C C# D D# E F F# G G#".split()[([7,2,10,5,0,7][s]+f)%12]

Provavelmente existem algumas melhorias óbvias a serem feitas. Entrada é uma lista de pares e as seqüências são indexadas em 0, por exemplo:

[0, 4], [3, 2], [4, 6]...
DJMcMayhem
fonte
0

Haskell, 83 82 bytes

zipWith$(!!).(`drop`cycle(words"A# B C C# D D# E F F# G G# A")).([6,1,9,4,11,6]!!)

Leva uma lista de strings e uma lista de trastes, ambos indexados em 0. Exemplo de uso:

Prelude >  ( zipWith$(!!).(`drop`cycle$words"A# B C C# D D# E F F# G G# A").([6,1,9,4,11,6]!!) ) [0,1,2,3,4,5] [0,0,0,0,0,0]
["E","B","G","D","A","E"]

Da lista infinita de notas que começa com A#, solte o número de notas fornecidas pela lista [6,1,9,4,11,6]no índice da sequência e escolha a nota no índice do traste da lista restante.

nimi
fonte
Infelizmente, os intervalos entre as strings não são todos iguais.
Neil
@ Neil: ... fixo.
nimi
Acabou sendo uma correção simples no JavaScript - (s*7)+(s>2)- agora estou usando isso na minha resposta.
Neil
@ Neil: ... trabalhando nisso também.
nimi
0

JavaScript (ES6), 82 81 bytes

a=>a.map(b=>(q=(b[0]+.3+b[1]*7.3|0)%12/1.7+10.3).toString(17)[0]+(q%1>.5?"#":""))

Eu queria tentar uma resposta totalmente matemática, mas acabou um pouco longa. Talvez haja uma maneira de jogar golfe ...

Snippet de teste

ETHproductions
fonte
Eu queria usar, toString(17)mas lutei para obtê-lo em uma contagem razoável de bytes.
Neil
0

PHP, 102 bytes

<?foreach($_GET[i]as$t)echo[E,F,"F#",G,"G#",A,"A#",B,C,"C#",D,"D#"][[0,7,3,10,5][$t[0]%5]+$t[1]%12]._;

Insira como matriz múltipla ambos os 0 baseados, por exemplo, '[[2,0], [5,3], [2,12], [3,8], [0,3]]'

Boa alternativa 106 bytes para definir o # com base no mod 7 congruente

<?foreach($_GET[i]as$t)echo EFFGGAABCCDD[$d=[0,7,3,10,5][$t[0]%5]+$t[1]%12].["","#"][$d%7?$d%7%2?0:1:0]._;
Jörg Hülsermann
fonte