Menerjemahkan pasangan angka ke catatan gitar

18

Diagram fretboard gitar terlihat seperti ini:

  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

Seperti yang Anda lihat, string pertama (dari atas) terbuka adalah E. Fret pertama pada string pertama adalah F. Fret keempat pada string ketiga adalah a B. Perhatikan bahwa not pertama adalah fret nol, bukan yang pertama.

Ini dapat ditulis dengan angka pada format string, fret. String diberi nomor dari 1 hingga 6 dari atas ke bawah. Fret diberi nomor dari 0 hingga 12 dari kiri ke kanan. Yang pertama Ekarena itu 1, 0. Beberapa contoh lain:

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

Tantangan:

Ambil Npasangan angka ( sdan f), dan hasilkan suksesi nada terbatas.

  • Masukan mungkin dalam format apa pun yang sesuai. tuple, 2D-matrix, dua daftar terpisah, daftar yang saling terkait (string, fret, string, fret ...) dll.
  • Nada keluaran harus dipisahkan, tetapi pembatasnya opsional (koma, spasi, tanda hubung ...). Outputnya bisa dalam huruf besar atau kecil.
  • s(untuk string) akan berada dalam kisaran [1, 6](Anda dapat memilih untuk memiliki indeks 0)
  • f (untuk fret) akan berada dalam kisaran [0, 12]

Uji kasus dan contoh:

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     

Semoga sukses, dan senang bermain golf!

Stewie Griffin
sumber
Bukan gitaris (atau bahkan musisi yang baik, sungguh), tetapi tidakkah ada penghilangan signifikan di sini, jika Anda mengharapkan output sebagai lagu yang dikenali? Yaitu, durasi not - keseluruhan, half, quarter note, & c.
jamesqf
1
@ jamesqf Tidak, tidak apa-apa asalkan Anda tahu lagunya. Ini saat ini lagu paling populer di ultimate-guitar.com . Lihatlah intro.
Stewie Griffin

Jawaban:

4

05AB1E , 48 47 43 40 byte

Menggunakan pengodean CP-1252 .

Baik senar maupun fret berbasiskan 0.

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

Penjelasan

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

Cobalah online!

Disimpan 7 byte berkat Adnan

Emigna
sumber
1
Mengeksploitasi bug sangat golf! .-)
Luis Mendo
"AA#BCC#DD#EFF#GG#"•7V3•3BS£bukannya "A A# B C C# D D# E F F# G G#"#beberapa byte lebih pendek :).
Adnan
@ Adnan: Ooh, perubahan basis yang bagus :)
Emigna
Juga versi terkompresi dari "AA#BCC#DD#EFF#GG#"string: •™ÎÚ,Ülu•žh'#A«‡(karena huruf kecil diperbolehkan: 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])

Membutuhkan string berbasis 1. Sunting: Disimpan 9 byte dengan langsung menghitung konversi string ke fret, berdasarkan jawaban lama @ nimi.

Neil
sumber
@Arnauld Terima kasih, tetapi akhirnya saya memilih jawaban @ nimi sebagai gantinya.
Neil
Jauh lebih efisien;)
Arnauld
Pintar. jawaban yang sangat licik
Rohan Jhunjhunwala
7

Mathematica, 62 byte (tidak bersaing)

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

The {24,19,15,10,5,0}dan the E2mewakili nada senar terbuka dari enam senar gitar (misalnya, senar teratas adalah 24 semi nada di atas catatan E2). Non-bersaing karena tidak mencetak nama not-not — ia memainkan urutan not! (hanya jika Anda memiliki Mathematica, sayangnya) Misalnya,

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

memainkan 4 bar pembuka dari Canon Pachelbel. (yaitu tentang sebanyak Pachelbel Canon yang saya bisa berdiri)

Greg Martin
sumber
7

MATL , 48 47 45 byte

Terima kasih kepada @Emigna untuk koreksi terkait format input.

Gitar dan kode golf ... Saya harus menjawab yang ini!

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

Format input adalah: array string (berbasis 1), kemudian array fret (berbasis).

Cobalah online!

Penjelasan

Beberapa fitur bahasa yang digunakan dalam jawaban ini:

  • Sebuah string secara otomatis dikonversi ke array numerik poin kode ASCII ketika beberapa operasi aritmatika diterapkan.
  • Operasi aritmetika bekerja berdasarkan elemen , yaitu vektor. Jadi pengurangan string dan array numerik dengan ukuran yang sama memberikan array dengan pengurangan entri yang sesuai.
  • Pengindeksan adalah berbasis 1 dan modular .
  • Sebuah array sel adalah seperti daftar dalam bahasa lain. Ini dapat berisi elemen sewenang-wenang, mungkin array dari berbagai jenis atau ukuran. Di sini array sel akan digunakan untuk menyimpan string dengan panjang berbeda (nama catatan).

Kode yang dikomentari:

'$)-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
sumber
1
Saya tahu saya akan menemukan jawaban dari Anda segera setelah saya melihat kata "Guitar"
Suever
1
@LuisMendo Sangat bagus! Saya suka trik indeks ascii-char :)
Emigna
4

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

Tidak Disatukan:

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

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

Mengambil angka sebagai string fretpasangan di stdin, dan mengeluarkan catatan setelah setiap pasangan. Misalnya:

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

Ruby, 63 byte

mengambil array array 2-elemen, dalam urutan [string,fret].

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

Penjelasan

Dalam penyetelan standar, gitar adalah salah satu dari beberapa instrumen senar (tertekuk atau resah) yang memiliki interval tidak konsisten di antara senar-senarnya. Sebagian besar memiliki interval 5-semiton yang konsisten antara semua pasangan string yang berdekatan ("keempat") atau interval 7-semiton yang konsisten antara semua pasangan string yang berdekatan ("kelima.") Ini sesuai dengan rasio frekuensi 3: 4 dan 2: 3 masing-masing, dan yang terpenting kedua hanya untuk "oktaf" dengan rasio frekuensi 1: 2.

Gitar sebagian besar memiliki interval 5-semitone. Jika memiliki 5 di antaranya akan memiliki perbedaan 25 semiton antara string 1 dan 6. Sebagai gantinya, interval antara string ke-2 dan ke-3 dikurangi menjadi 4 semiton, memberikan perbedaan 24 semiton (2 oktaf) yang lebih baik untuk memainkan akord.

Ini tidak nyaman untuk program ini, jadi kami mulai dengan mengubah intonasi gitar 1-indeks menjadi intonasi 5-string-bass 0 yang diindeks, yang memiliki semua interval 5 semiton:

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

Selanjutnya kita tambahkan 2, dan memberikan tuning dari 12 senar bass fiktif, dengan intonasi dari senar terbuka sebagai berikut, dan semua interval menjadi 5 semitones (12 senar "bass" memang ada tetapi saya tidak yakin ada banyak dengan tepat ini penyetelan.)

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

Seperti dapat dilihat, semua benda tajam dikelompokkan bersama. Pola ini dapat diulangi sampai tak terhingga. Ini dikenal sebagai "lingkaran kelima" dan merupakan dasar bagi skala musik Barat (dengan sedikit penyesuaian tuning, lingkaran dapat ditutup karena fakta bahwa (3/2)**12dan 2**7jumlahnya sangat mirip.

Sekarang kita berurusan dengan parameter fret. Tidak seperti banyak jawaban lain di sini, yang menerjemahkan parameter string menjadi sejumlah fret, saya menerjemahkan parameter fret ke sejumlah string. Dalam tabel di atas dapat dilihat bahwa menambahkan 7 ke nomor string menempatkan kita pada string yang nama notnya satu semitone lebih tinggi. (Ini dalam oktaf yang sama sekali berbeda tapi itu tidak masalah.) Jadi kita tambahkan i[1]*7ke nomor string, dan bawa modulo 12:

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

Kami mengurangi ini dari 6 untuk mendapatkan angka dalam kisaran 6 hingga -5 dan mencari huruf dalam BEADGCF(Ruby memungkinkan indeks negatif untuk membungkus kembali ke akhir array.) Jika n>=7kita perlu menambahkan #simbol untuk menyelesaikan output .

Program uji

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]

Keluaran

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

Masukkan dua daftar terpisah, string berdasarkan 1.

Taco
sumber
1
Selamat datang di situs ini! Jawaban pertama yang bagus.
DJMcMayhem
@DJMcMayhem: Terima kasih :-)
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#]!

Penjelasan

@ mode numerik (baca input sebagai angka)

T[0,7,2,10,5,0,7] Ubah input menggunakan array, ex array [Input]

+N Tambahkan N (Nilai input berikutnya) ke Input saat ini

%12 Modulo 12 nilai input saat ini

@ Tandai mode numerik mati

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Terjemahkan input ke dalam array

! Gunakan input sebagai nilai output

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

Tidak disatukan

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

Mungkin ada beberapa perbaikan nyata yang harus dilakukan. Input adalah daftar pasangan, dan string diindeks 0, misalnya:

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

Mengambil daftar string dan daftar fret, keduanya diindeks 0. Contoh penggunaan:

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

Dari daftar nada tak terbatas yang dimulai dengan A#, jatuhkan jumlah catatan yang diberikan oleh daftar [6,1,9,4,11,6]di indeks string dan pilih catatan di indeks fret dari daftar yang tersisa.

nimi
sumber
Sayangnya interval antara string tidak semuanya sama.
Neil
@ Neil: ... diperbaiki.
nimi
Ternyata itu adalah perbaikan sederhana dalam JavaScript - (s*7)+(s>2)- jadi saya sekarang menggunakan jawaban saya.
Neil
@Neil: ... mengerjakannya juga.
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?"#":""))

Saya ingin mencoba semua jawaban matematika, tetapi ternyata agak lama. Mungkin ada cara untuk golf itu ...

Cuplikan tes

Produksi ETH
sumber
Saya ingin menggunakan toString(17)tetapi berjuang untuk mendapatkannya dalam jumlah byte yang masuk akal.
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]._;

Input sebagai banyak larik keduanya berdasarkan 0 misalnya '[[2,0], [5,3], [2,12], [3,8], [0,3]]'

Alternatif bagus 106 Bytes untuk mengatur # berdasarkan mod 7 kongruen

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