Traduci coppie di numeri in note di chitarra


18

Un diagramma di tastiera per chitarra è simile al seguente:

  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

Come puoi vedere, la prima stringa (dall'alto) aperta è un E. Il primo tasto sulla prima corda è un F. Il quarto tasto sulla terza corda è a B. Nota che la prima nota è il tasto zeroth, non il primo.

Questo può essere scritto con numeri sul formato string, fret. Le stringhe sono numerate da 1 a 6 dall'alto verso il basso. I tasti sono numerati da 0 a 12 da sinistra a destra. Il primo Eè quindi 1, 0. Alcuni altri esempi:

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

Sfida:

Prendi Ncoppie di numeri ( se f) e genera una successione di note delimitata.

  • L'input può essere in qualsiasi formato adatto. tuple, matrice 2D, due elenchi separati, un elenco intrecciato (stringa, tasto, stringa, tasto ...) ecc.
  • Il tono di uscita deve essere separato, ma il delimitatore è facoltativo (virgola, spazio, trattino ...). L'output può essere in maiuscolo o minuscolo.
  • s(per stringa) sarà compreso nell'intervallo [1, 6](puoi scegliere di avere l'indicizzazione 0)
  • f (per il tasto) sarà nell'intervallo [0, 12]

Casi di prova ed esempi:

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     

Buona fortuna e buon golf!


Non un chitarrista (nemmeno un musicista decente, in realtà), ma non c'è un'omissione significativa qui, se ti aspetti l'uscita come melodie riconoscibili? Cioè, la durata della nota - intera, metà, quarti e così via.
jamesqf,

1
@jamesqf No, va benissimo purché tu conosca la canzone. Questa è attualmente la canzone più popolare su ultimate-guitar.com . Dai un'occhiata all'intro.
Stewie Griffin,

Risposte:


4

05AB1E , 48 47 43 40 byte

Utilizza la codifica CP-1252 .

Sia le stringhe che i tasti sono basati su 0.

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

Spiegazione

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

Provalo online!

Salvataggio di 7 byte grazie ad Adnan


1
Sfruttare i bug è molto goloso! .-)
Luis Mendo,

"AA#BCC#DD#EFF#GG#"•7V3•3BS£invece di "A A# B C C# D D# E F F# G G#"#qualche byte in meno :).
Adnan,

@Adnan: Ooh, bel cambio di base :)
Emigna,

Anche una versione compressa della "AA#BCC#DD#EFF#GG#"stringa: •™ÎÚ,Ülu•žh'#A«‡(poiché è consentita la minuscola: 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])

Richiede stringhe basate su 1. Modifica: salvato 9 byte calcolando direttamente la conversione da stringa a tastiera, in base alla vecchia risposta di @ nimi.


@Arnauld Grazie, ma ho finito per appropriarmi della risposta di @nimi.
Neil,

Molto più efficace in effetti;)
Arnauld il

Intelligente. risposta molto subdola
Rohan Jhunjhunwala,

7

Mathematica, 62 byte (non concorrenti)

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

Il {24,19,15,10,5,0}e il E2rappresentano i toni di stringa aperta delle sei corde di chitarra (ad esempio, la corda superiore è di 24 semitoni sopra la nota E2). Non competitiva perché non stampa i nomi delle note, ma riproduce la sequenza delle note! (solo se hai Mathematica, sfortunatamente) Ad esempio,

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

suona le prime 4 battute dal Canon di Pachelbel. (che è circa la Canon di Pachelbel che posso sopportare)


7

MATL , 48 47 45 byte

Grazie a @Emigna per una correzione relativa al formato di input.

Chitarra e codice golf ... Ho dovuto rispondere a questa domanda!

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

Il formato di input è: un array di stringhe (basato su 1), quindi un array di tasti (basato su 0).

Provalo online!

Spiegazione

Alcune funzioni linguistiche utilizzate in questa risposta:

  • Una stringa viene automaticamente convertita in una matrice numerica di punti di codice ASCII quando viene applicata qualche operazione aritmetica.
  • Le operazioni aritmetiche funzionano in termini di elementi , cioè vettorializzati. Quindi la sottrazione di una stringa e una matrice numerica della stessa dimensione fornisce una matrice con la sottrazione delle voci corrispondenti.
  • L'indicizzazione è basata su 1 e modulare .
  • Un array di celle è come un elenco in altre lingue. Può contenere elementi arbitrari, possibilmente array di diversi tipi o dimensioni. Qui un array di celle verrà utilizzato per memorizzare stringhe di diverse lunghezze (i nomi delle note).

Codice commentato:

'$)-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

1
Sapevo che avrei trovato una tua risposta non appena ho visto la parola "Guitar"
Suever,

1
@LuisMendo Very nice! Mi piace il trucco dell'indice 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;}

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

3

C, 104 103 byte

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

Prende i numeri come string fretcoppie sullo stdin e genera la nota dopo ogni coppia. Per esempio:

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

3

Rubino, 63 byte

accetta una matrice di matrici a 2 elementi, nell'ordine [string,fret].

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

Spiegazione

Nell'accordatura standard, la chitarra è uno dei pochi strumenti a corda (ad arco o a tastiera) che ha intervalli incoerenti tra le sue corde. La maggior parte ha un intervallo di 5 semitoni coerente tra tutte le coppie di stringhe adiacenti (un "quarto") o un intervallo di 7 semitoni coerente tra tutte le coppie di stringhe adiacenti (un "quinto"). Questi corrispondono a rapporti di frequenza di 3: 4 e 2: 3 rispettivamente, e sono secondi in importanza solo rispetto all '"ottava" con rapporto di frequenza 1: 2.

La chitarra ha principalmente intervalli di 5 semitoni. Se ne avesse 5, avrebbe una differenza di 25 semitoni tra la prima e la sesta stringa. Invece, l'intervallo tra la seconda e la terza corda è ridotto a 4 semitoni, dando una differenza di 24 semitoni (2 ottave) che è meglio per suonare gli accordi.

Questo è scomodo per il programma, quindi iniziamo cambiando l'intonazione di chitarra a 1 indice in un'intonazione di 0 corde a 5 corde indicizzata, che ha tutti gli intervalli di 5 semitoni:

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

Quindi aggiungiamo 2 e diamo l'accordatura di un basso fittizio a 12 corde, con l'intonazione delle corde aperte come segue, e tutti gli intervalli sono 5 semitoni (esistono "bassi" a 12 corde ma non sono sicuro che ce ne siano molti con questo messa a punto.)

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

Come si può vedere, tutti gli oggetti taglienti sono raggruppati insieme. Questo schema può essere ripetuto all'infinito. E 'noto come il "circolo delle quinte" ed è fondamentale per la scala musicale occidentale (con un po' di regolazione messa a punto del cerchio può essere chiuso a causa del fatto che (3/2)**12e 2**7sono numeri molto simili.

Ora ci occupiamo del parametro tasto. A differenza di molte altre risposte qui, che traducono il parametro stringa in un numero di tasti, traduco il parametro tasto in un numero di stringhe. Nella tabella sopra si può vedere che l'aggiunta di 7 al numero di stringa ci mette su una stringa il cui nome della nota è superiore di un semitono. (È in un'ottava completamente diversa ma non importa.) Quindi aggiungiamo i[1]*7al numero di stringa e prendiamo modulo 12:

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

Sottraiamo questo da 6 per ottenere un numero compreso tra 6 e -5 e cerchiamo la lettera in BEADGCF(Ruby consente agli indici negativi di tornare alla fine dell'array.) Se n>=7è necessario aggiungere un #simbolo per completare l'output .

Programma di 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]

Produzione

E
C
A
G
F#
E
C#
F#
G
G#
D
G#
B

3

C #, 131 byte

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

Immettere due elenchi separati, le stringhe sono basate su 1.


1
Benvenuti nel sito! Bella prima risposta.
DJMcMayhem

@DJMcMayhem: Grazie :-)
Taco,

1

Clora , 55 byte

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

Spiegazione

@ modalità numerica (leggi input come numeri)

T[0,7,2,10,5,0,7] Trasforma l'input usando l'array, ex array [Input]

+N Aggiungi N (valore di input successivo) all'input corrente

%12 Modulo 12 il valore di input corrente

@ Flag modalità numerica disattivata

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Traduci l'input in un array

! Usa input come valore di output


1

Java 7 197, 163 byte

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



}

0

Python 2, 94, 91 , 88 byte

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]

Probabilmente ci sono alcuni ovvi miglioramenti da apportare. L'input è un elenco di coppie e le stringhe sono indicizzate 0, ad esempio:

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

0

Haskell, 83 82 byte

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

Prende un elenco di stringhe e un elenco di tasti, entrambi con indice 0. Esempio di utilizzo:

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

Dall'elenco infinito di note che iniziano con A#, rilascia il numero di note dato dall'elenco [6,1,9,4,11,6]all'indice della stringa e scegli la nota all'indice del tasto dall'elenco rimanente.


Sfortunatamente gli intervalli tra le stringhe non sono tutti uguali.
Neil,

@Neil: ... risolto.
nimi,

Si è rivelata una semplice correzione in JavaScript (s*7)+(s>2)- quindi ora la sto usando nella mia risposta.
Neil,

@Neil: ... ci stiamo lavorando anche.
nimi,

0

JavaScript (ES6), 82 81 byte

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

Volevo provare una risposta tutta matematica, ma si è rivelata un po 'lunga. Forse c'è un modo per giocare a golf ...

Snippet di prova


Volevo usare toString(17)ma ho faticato a ottenerlo in un conteggio di byte ragionevole.
Neil,

0

PHP, 102 byte

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

Immettere come array multiplo entrambi basati su 0, ad esempio '[[2,0], [5,3], [2,12], [3,8], [0,3]]'

Bella alternativa 106 byte per impostare # in base al congruente mod 7

<?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]._;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.