Übersetzen Sie Zahlenpaare in Gitarrennoten

18

Ein Gitarren-Griffbrett-Diagramm sieht folgendermaßen aus:

  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

Wie Sie sehen können, ist der erste geöffnete String (von oben) ein E. Der erste Bund auf der ersten Saite ist ein F. Der vierte Bund auf der dritten Saite ist a B. Beachten Sie, dass die erste Note der nullte Bund ist, nicht der erste.

Dies kann mit Zahlen im Format geschrieben werden string, fret. Die Zeichenfolgen sind von oben nach unten von 1 bis 6 nummeriert. Die Bünde sind von links nach rechts von 0 bis 12 nummeriert. Der erste Eist also 1, 0. Einige andere Beispiele:

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

Herausforderung:

Nehmen Sie NZahlenpaare ( sund f) und geben Sie eine begrenzte Notenfolge aus.

  • Die Eingabe kann in jedem geeigneten Format erfolgen. Tupel, 2D-Matrix, zwei getrennte Listen, eine verwobene Liste (String, Bund, String, Bund ...) usw.
  • Der Ausgabeton sollte getrennt sein, das Trennzeichen ist jedoch optional (Komma, Leerzeichen, Bindestrich ...). Die Ausgabe kann in Groß- oder Kleinschreibung erfolgen.
  • s(für Zeichenkette) liegt im Bereich [1, 6](Sie können wählen, ob i 0 indiziert werden soll)
  • f (für Bund) wird im Bereich sein [0, 12]

Testfälle und Beispiele:

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     

Viel Glück und viel Spaß beim Golfen!

Stewie Griffin
quelle
Weder ein Gitarrist noch ein anständiger Musiker, aber gibt es hier keine nennenswerte Lücke, wenn Sie eine Ausgabe als erkennbare Musik erwarten? Das heißt, die Notendauer - ganze, halbe, Viertelnoten, & c.
Jamesqf
1
@jamesqf Nö, es ist vollkommen in Ordnung, solange du den Song kennst. Dies ist derzeit das beliebteste Lied auf ultimate-guitar.com . Schauen Sie sich das Intro an.
Stewie Griffin

Antworten:

4

05AB1E , 48 47 43 40 Bytes

Verwendet die CP-1252- Codierung.

Sowohl Saiten als auch Bünde basieren auf 0.

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

Erläuterung

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

Probieren Sie es online!

7 Bytes gespart dank Adnan

Emigna
quelle
1
Das Ausnutzen von Bugs ist sehr golfen! .-)
Luis Mendo
"AA#BCC#DD#EFF#GG#"•7V3•3BS£stattdessen "A A# B C C# D D# E F F# G G#"#ist ein paar bytes kürzer :).
Adnan
@Adnan: Ooh, schöner Basiswechsel :)
Emigna
Auch eine komprimierte Version des "AA#BCC#DD#EFF#GG#"Strings: •™ÎÚ,Ülu•žh'#A«‡(da Kleinbuchstaben erlaubt sind: p).
Adnan
9

JavaScript (ES6), 79-70 Byte

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

Benötigt 1-basierte Zeichenfolgen. Bearbeiten: Speichert 9 Bytes durch direkte Berechnung der Konvertierung von Zeichenfolge in Bund basierend auf der alten Antwort von @ nimi.

Neil
quelle
@ Arnauld Danke, aber ich habe mir stattdessen @ nimis Antwort zu Eigen gemacht.
Neil
Viel effizienter in der Tat;)
Arnauld
Klug. sehr hinterhältige Antwort
Rohan Jhunjhunwala
7

Mathematica, 62 Bytes (nicht konkurrierend)

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

Das {24,19,15,10,5,0}und das E2stellen die offenen Saitentöne der sechs Gitarrensaiten dar (die oberste Saite ist beispielsweise 24 Halbtöne über der Note E2). Nichtkonkurrierende , weil sie die Namen der nicht gedruckt Noten-it spielt die Reihenfolge der Noten! (nur wenn Sie leider Mathematica haben) Zum Beispiel,

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

spielt die ersten 4 Takte von Pachelbels Canon. (Das ist ungefähr so ​​viel von Pachelbels Canon, wie ich ausstehen kann)

Greg Martin
quelle
7

MATL , 48 47 45 Bytes

Vielen Dank an @Emigna für die Korrektur des Eingabeformats.

Gitarren- und Codegolf ... ich musste das beantworten!

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

Das Eingabeformat ist: ein Array von (1-basierten) Zeichenfolgen, dann ein Array von (0-basierten) Bünden.

Probieren Sie es online!

Erläuterung

Einige in dieser Antwort verwendete Sprachfunktionen:

  • Eine Zeichenfolge wird automatisch in ein numerisches Array von ASCII-Codepunkten konvertiert , wenn eine arithmetische Operation darauf angewendet wird.
  • Arithmetische Operationen arbeiten elementweise , dh vektorisiert. Die Subtraktion eines Strings und eines numerischen Arrays gleicher Größe ergibt also ein Array mit der Subtraktion entsprechender Einträge.
  • Die Indizierung ist 1-basiert und modular .
  • Ein Zellenarray ist wie eine Liste in anderen Sprachen. Es kann beliebige Elemente enthalten, möglicherweise Arrays unterschiedlicher Art oder Größe. Hier wird ein Zellenarray verwendet, um Zeichenfolgen unterschiedlicher Länge (die Namen der Noten) zu speichern.

Kommentierter Code:

'$)-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
quelle
1
Ich wusste, ich würde eine Antwort von Ihnen finden, sobald ich das Wort "Gitarre"
Suever
1
@ LuisMendo Sehr schön! Ich mag die ASCII-Char Index Trick :)
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;
  }

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

Nimmt Zahlen als string fretPaare auf stdin und gibt die Note nach jedem Paar aus. Z.B:

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

Ruby, 63 Bytes

Nimmt ein Array von 2-Element-Arrays in der Reihenfolge [string,fret].

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

Erläuterung

In der Standardstimmung ist die Gitarre eines der wenigen Saiteninstrumente (Streichinstrumente oder Bünde) mit inkonsistenten Abständen zwischen den Saiten. Die meisten haben entweder ein konsistentes 5-Halbton-Intervall zwischen allen Paaren benachbarter Saiten (ein "viertes") oder ein konsistentes 7-Halbton-Intervall zwischen allen Paaren benachbarter Saiten (ein "fünftes"). Dies entspricht einem Frequenzverhältnis von 3: 4 und 2: 3 und sind nur in der "Oktave" mit dem Frequenzverhältnis 1: 2 von zweiter Bedeutung.

Die Gitarre hat meist 5 Halbtonintervalle. Wenn es 5 davon hätte, hätte es einen Unterschied von 25 Halbtönen zwischen der 1. und 6. Saite. Stattdessen wird das Intervall zwischen der 2. und 3. Saite auf 4 Halbtöne reduziert, was einen Unterschied von 24 Halbtönen (2 Oktaven) ergibt, was für das Spielen von Akkorden besser ist.

Dies ist für das Programm unpraktisch. Daher ändern wir zunächst die 1-indizierte Gitarren-Intonation in eine 0-indizierte 5-Saiten-Bass-Intonation, die alle Intervalle von 5 Halbtönen aufweist:

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

Als nächstes addieren wir 2 und geben die Stimmung eines fiktiven 12-Saiter-Basses mit der folgenden Intonation der offenen Saiten an, und alle Intervalle sind 5 Halbtöne (12-Saiter- "Bässe" existieren, aber ich bin nicht sicher, ob es viele mit genau diesem gibt Abstimmung.)

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

Wie zu sehen ist, sind alle Scharfe zu einer Gruppe zusammengefasst. Dieses Muster kann unendlich oft wiederholt werden. Es wird als „Quintenzirkel“ bekannt und ist von grundlegender Bedeutung für den westlichen Tonleiter (mit einem wenig Tuning Einstellung des Kreis kann aufgrund der Tatsache geschlossen wird , dass (3/2)**12und 2**7sind sehr ähnliche Zahlen.

Jetzt beschäftigen wir uns mit dem Bund-Parameter. Im Gegensatz zu vielen anderen Antworten, bei denen der String-Parameter in mehrere Bünde übersetzt wird, übersetze ich den Bund-Parameter in mehrere Strings. In der obigen Tabelle ist zu sehen, dass durch Hinzufügen von 7 zur String-Nummer ein String entsteht, dessen Notenname einen Halbton höher liegt. (Es ist in einer völlig anderen Oktave, aber das spielt keine Rolle.) Also addieren wir i[1]*7die String-Nummer und nehmen es modulo 12:

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

Wir subtrahieren diesen Wert von 6, um eine Zahl im Bereich von 6 bis -5 zu erhalten, und schlagen den Buchstaben in nach BEADGCF(Ruby lässt zu, dass negative Indizes zum Ende des Arrays zurücklaufen.) Wenn n>=7wir ein #Symbol hinzufügen müssen, um die Ausgabe zu vervollständigen .

Testprogramm

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]

Ausgabe

E
C
A
G
F#
E
C#
F#
G
G#
D
G#
B
Level River St
quelle
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]));}

Geben Sie zwei separate Listen ein. Die Zeichenfolgen basieren auf 1.

Taco
quelle
1
Willkommen auf der Seite! Schöne erste Antwort.
DJMcMayhem
@ DJMcMayhem: Danke :-)
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#]!

Erläuterung

@ numerischer Modus (Eingabe als Zahlen lesen)

T[0,7,2,10,5,0,7] Eingaben mit dem Array transformieren, ex array [Input]

+N Addiere N (Nächster Eingabewert) zum aktuellen Eingang

%12 Modulo 12 der aktuelle Eingabewert

@ Den numerischen Modus ausschalten

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Übersetzen Sie die Eingabe in ein Array

! Eingabe als Ausgabewert verwenden

OPSXCQ
quelle
1

Java 7 197163 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]);



}
Zahlenknoten
quelle
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]

Es gibt wahrscheinlich einige offensichtliche Verbesserungen. Die Eingabe ist eine Liste von Paaren, und die Zeichenfolgen sind mit 0 indiziert, z.

[0, 4], [3, 2], [4, 6]...
DJMcMayhem
quelle
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]!!)

Nimmt eine Liste von Strings und eine Liste von Bünden, beide 0-indiziert. Anwendungsbeispiel:

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

Löschen Sie aus der unendlichen Liste der Noten, die mit beginnt A#, die Anzahl der Noten, die in der Liste [6,1,9,4,11,6]am Index der Zeichenfolge angegeben sind, und wählen Sie die Note am Index des Bundes aus der verbleibenden Liste aus.

nimi
quelle
Leider sind die Intervalle zwischen den Zeichenfolgen nicht alle gleich.
Neil
@Neil: ... behoben.
nimi
Es stellte sich heraus, dass es sich in JavaScript um eine einfache Lösung handelte. Deshalb verwende (s*7)+(s>2)ich diese jetzt in meiner Antwort.
Neil
@Neil: ... auch daran zu arbeiten.
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?"#":""))

Ich wollte eine rein mathematische Antwort versuchen, aber es stellte sich heraus, dass es ein wenig lang war. Vielleicht gibt es eine Möglichkeit, Golf zu spielen ...

Testschnipsel

ETHproductions
quelle
Ich wollte verwenden, hatte toString(17)aber Mühe, es in einer vernünftigen Anzahl von Bytes zu bekommen.
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]._;

Geben Sie beide 0 als Mehrfacharray ein, zum Beispiel '[[2,0], [5,3], [2,12], [3,8], [0,3]]'.

Schöne Alternative 106 Bytes um das # basierend auf Mod 7 kongruent zu setzen

<?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
quelle