Traduire des paires de numéros en notes de guitare

18

Un diagramme de manche de guitare ressemble à ceci:

  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

Comme vous pouvez le voir, la première chaîne (du haut) ouverte est un E. La première case de la première corde est un F. La quatrième case de la troisième corde est un B. Notez que la première note est la case zéro, pas la première.

Cela peut être écrit avec des chiffres sur le format string, fret. Les cordes sont numérotées de 1 à 6 de haut en bas. Les frettes sont numérotées de 0 à 12 de gauche à droite. Le premier Eest donc 1, 0. Quelques autres exemples:

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

Défi:

Prenez des Npaires de nombres ( set f) et générez une succession de notes délimitées.

  • L'entrée peut être dans n'importe quel format approprié. tuples, matrice 2D, deux listes séparées, une liste entrelacée (chaîne, frette, chaîne, frette ...) etc.
  • La tonalité de sortie doit être séparée, mais le délimiteur est facultatif (virgule, espace, tiret ...). La sortie peut être en majuscule ou en minuscule.
  • s(pour la chaîne) sera dans la plage [1, 6](vous pouvez choisir d'avoir i 0 indexé)
  • f (pour la frette) sera dans la plage [0, 12]

Cas de test et exemples:

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     

Bonne chance et bon golf!

Stewie Griffin
la source
Pas un guitariste (ni même un musicien décent, vraiment), mais n'y a-t-il pas une omission importante ici, si vous vous attendez à une sortie sous forme de morceaux reconnaissables? C'est-à-dire la durée des notes - entières, demi-notes, noires, etc.
jamesqf
1
@jamesqf Non, c'est très bien tant que vous connaissez la chanson. C'est actuellement la chanson la plus populaire sur ultimate-guitar.com . Jetez un œil à l'intro.
Stewie Griffin

Réponses:

4

05AB1E , 48 47 43 40 octets

Utilise l' encodage CP-1252 .

Les chaînes et les frettes sont basées sur 0.

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

Explication

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

Essayez-le en ligne!

7 octets enregistrés grâce à Adnan

Emigna
la source
1
L'exploitation des bugs est très golfique! .-)
Luis Mendo
"AA#BCC#DD#EFF#GG#"•7V3•3BS£au lieu de "A A# B C C# D D# E F F# G G#"#quelques octets plus court :).
Adnan
@Adnan: Ooh, beau changement de base :)
Emigna
Également une version compressée de la "AA#BCC#DD#EFF#GG#"chaîne: •™ÎÚ,Ülu•žh'#A«‡(puisque les minuscules sont autorisées: p).
Adnan
9

JavaScript (ES6), 79 70 octets

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

Nécessite des chaînes basées sur 1. Edit: 9 octets enregistrés en calculant directement la conversion de chaîne en frette, basée sur l'ancienne réponse de @ nimi.

Neil
la source
@Arnauld Merci mais j'ai fini par m'approprier la réponse de @ nimi à la place.
Neil
Beaucoup plus efficace en effet;)
Arnauld
Intelligent. réponse très sournoise
Rohan Jhunjhunwala
7

Mathematica, 62 octets (non concurrent)

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

Le {24,19,15,10,5,0}et le E2représentent les sons de cordes ouvertes des six cordes de guitare (par exemple, la corde du haut est de 24 demi-tons au-dessus de la note E2). Non compétitif car il n'imprime pas le nom des notes - il joue la séquence de notes! (seulement si vous avez Mathematica, malheureusement) Par exemple,

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

joue les 4 premières mesures du Canon de Pachelbel. (qui représente autant de Canon de Pachelbel que je peux le supporter)

Greg Martin
la source
7

MATL , 48 47 45 octets

Merci à @Emigna pour une correction concernant le format d'entrée.

Guitare et golf de code ... J'ai dû répondre à celui-ci!

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

Le format d'entrée est: un tableau de chaînes (basées sur 1), puis un tableau de frettes (basées sur 0).

Essayez-le en ligne!

Explication

Certaines fonctionnalités linguistiques utilisées dans cette réponse:

  • Une chaîne est automatiquement convertie en un tableau numérique de points de code ASCII lorsqu'une opération arithmétique lui est appliquée.
  • Les opérations arithmétiques fonctionnent par éléments , c'est -à- dire vectorisées. Ainsi, la soustraction d'une chaîne et d'un tableau numérique de la même taille donne un tableau avec la soustraction des entrées correspondantes.
  • L'indexation est basée sur 1 et modulaire .
  • Un tableau de cellules est comme une liste dans d'autres langues. Il peut contenir des éléments arbitraires, éventuellement des tableaux de différents types ou tailles. Ici, un tableau de cellules sera utilisé pour stocker des chaînes de différentes longueurs (les noms des notes).

Code commenté:

'$)-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
la source
1
Je savais que j'allais trouver une réponse de votre part dès que j'aurais vu le mot "Guitar"
Suever
1
@LuisMendo Very nice! J'aime l'astuce index ascii-char :)
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;}

Non golfé:

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

la source
3

C, 104 103 octets

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

Prend les nombres par string fretpaires sur stdin et sort la note après chaque paire. Par exemple:

1 4
G#
4 2
E 
5 6
D#
2 3
D 
orlp
la source
3

Rubis, 63 octets

prend un tableau de tableaux à 2 éléments, dans l'ordre [string,fret].

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

Explication

Dans l'accordage standard, la guitare est l'un des rares instruments à cordes (à archet ou fretté) qui a des intervalles incohérents entre ses cordes. La plupart ont soit un intervalle cohérent de 5 demi-tons entre toutes les paires de chaînes adjacentes (un "quatrième") ou un intervalle cohérent de 7 demi-tons entre toutes les paires de chaînes adjacentes (un "cinquième"). Cela correspond à des rapports de fréquence de 3: 4 et 2: 3 respectivement, et sont la deuxième importance seulement à "l'octave" avec un rapport de fréquence 1: 2.

La guitare a principalement des intervalles de 5 demi-tons. S'il en avait 5, il y aurait une différence de 25 demi-tons entre la 1ère et la 6ème corde. Au lieu de cela, l'intervalle entre la 2e et la 3e chaîne est réduit à 4 demi-tons, ce qui donne une différence de 24 demi-tons (2 octaves), ce qui est préférable pour jouer des accords.

Cela n'est pas pratique pour le programme, nous commençons donc par changer l'intonation de guitare à 1 index en une intonation de basse à 5 cordes indexée, qui a tous les intervalles de 5 demi-tons:

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

Ensuite, nous ajoutons 2 et accordons une basse fictive à 12 cordes, avec l'intonation des cordes ouvertes comme suit, et tous les intervalles étant de 5 demi-tons (des "basses" à 12 cordes existent mais je ne suis pas sûr qu'il y en ait beaucoup avec précisément ce réglage.)

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

Comme on peut le voir, tous les objets tranchants sont regroupés. Ce modèle peut être répété à l'infini. Il est connu comme le « cercle des quintes » et est essentiel à l'échelle musicale occidentale (avec un peu d'ajustement de réglage du cercle peut être fermé en raison du fait que (3/2)**12et 2**7sont des nombres très similaires.

Nous traitons maintenant le paramètre fret. Contrairement à de nombreuses autres réponses ici, qui traduisent le paramètre de chaîne en un certain nombre de frettes, je traduis le paramètre de frette en un certain nombre de chaînes. Dans le tableau ci-dessus, on peut voir que l'ajout de 7 au numéro de chaîne nous place sur une chaîne dont le nom de note est supérieur d'un demi-ton. (C'est dans une octave complètement différente mais cela n'a pas d'importance.) Donc, nous ajoutons i[1]*7au numéro de chaîne et le prenons modulo 12:

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

Nous soustrayons cela de 6 pour obtenir un nombre compris entre 6 et -5 et recherchons la lettre BEADGCF(Ruby permet aux indices négatifs de revenir à la fin du tableau.) Si n>=7nous devons ajouter un #symbole pour terminer la sortie .

Programme de test

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]

Production

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

C #, 131 octets

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

Entrez deux listes distinctes, les chaînes sont basées sur 1.

Taco
la source
1
Bienvenue sur le site! Belle première réponse.
DJMcMayhem
@DJMcMayhem: Merci :-)
Taco
1

Clora , 55 octets

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

Explication

@ mode numérique (lire l'entrée sous forme de nombres)

T[0,7,2,10,5,0,7] Transformer l'entrée à l'aide du tableau, ex tableau [Input]

+N Ajouter N (valeur d'entrée suivante) à l'entrée actuelle

%12 Modulo 12 la valeur d'entrée actuelle

@ Désactiver le mode numérique

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Traduire l'entrée en un tableau

! Utiliser l'entrée comme valeur de sortie

OPSXCQ
la source
1

Java 7 197, 163 octets

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

Non golfé

  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
la source
0

Python 2, 94, 91 , 88 octets

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]

Il y a probablement des améliorations évidentes à apporter. L'entrée est une liste de paires et les chaînes sont indexées 0, par exemple:

[0, 4], [3, 2], [4, 6]...
DJMcMayhem
la source
0

Haskell, 83 82 octets

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

Prend une liste de chaînes et une liste de frettes, toutes deux indexées 0. Exemple d'utilisation:

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"]

Dans la liste infinie de notes commençant par A#, supprimez le nombre de notes données par la liste [6,1,9,4,11,6]à l'index de la chaîne et choisissez la note à l'index de la frette dans la liste restante.

nimi
la source
Malheureusement, les intervalles entre les chaînes ne sont pas tous égaux.
Neil
@Neil: ... fixe.
nimi
Cela s'est avéré être une solution simple en JavaScript - (s*7)+(s>2)- donc j'utilise maintenant cela dans ma réponse.
Neil
@Neil: ... y travaille aussi.
nimi
0

JavaScript (ES6), 82 81 octets

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

Je voulais essayer une réponse entièrement mathématique, mais cela s'est avéré un peu long. Peut-être qu'il y a un moyen de jouer au golf ...

Extrait de test

ETHproductions
la source
Je voulais l'utiliser toString(17)mais j'ai eu du mal à l'obtenir dans un nombre d'octets raisonnable.
Neil
0

PHP, 102 octets

<?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]._;

Saisie sous forme de tableau multiple à la fois 0 basé par exemple sur «[[2,0], [5,3], [2,12], [3,8], [0,3]]»

Belle alternative 106 octets pour définir le # basé sur le mod 7 congruent

<?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
la source