Sayı çiftlerini gitar notalarına çevirin


18

Bir gitar klavyesi şeması şöyle görünür:

  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

Gördüğünüz gibi, açılan ilk dize (üstten) bir E. İlk dizgideki ilk perde bir F. Üçüncü teldeki dördüncü perde a B. İlk notanın birinci değil sıfırıncı perde olduğuna dikkat edin.

Bu biçimdeki sayılarla yazılabilir string, fret. Dizeler yukarıdan aşağıya 1'den 6'ya kadar numaralandırılmıştır. Perdeler soldan sağa doğru 0 ile 12 arasında numaralandırılmıştır. Birincisi Ebu yüzden 1, 0. Diğer bazı örnekler:

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

Meydan okuma:

Bir Nçift ​​sayı ( sve f) alın ve sınırlandırılmış bir nota çıkın .

  • Giriş uygun herhangi bir formatta olabilir. tuples, 2D-matris, iki ayrı liste, iç içe bir liste (dize, perde, dize, perde ...) vb.
  • Çıktı tonu ayrılmalıdır, ancak sınırlayıcı isteğe bağlıdır (virgül, boşluk, tire ...). Çıktı büyük veya küçük harf olabilir.
  • s(dize için) aralıkta olacaktır [1, 6](i 0 dizinini eklemeyi seçebilirsiniz)
  • f (perde için) aralıkta olacak [0, 12]

Test örnekleri ve örnekler:

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     

İyi şanslar ve mutlu golf!


Gitarist değil (hatta iyi bir müzisyen bile), ancak çıktıyı tanınabilir ezgiler olarak bekliyorsanız, burada önemli bir ihmal yok mu? Yani, nota süresi - bütün, yarım, çeyrek notalar & c.
jamesqf

1
@jamesqf Hayır, şarkıyı bildiğin sürece gayet iyi. Şu anda ultimate-guitar.com'daki en popüler şarkı . Giriş bölümüne bir göz atın.
Stewie Griffin

Yanıtlar:


4

05AB1E , 48 47 43 40 bayt

CP-1252 kodlamasını kullanır .

Hem teller hem de perdeler 0 tabanlıdır.

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

açıklama

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

Çevrimiçi deneyin!

Adnan sayesinde 7 bayt kurtardı


1
Böcek sömürmek çok golfy! .-)
Luis Mendo

"AA#BCC#DD#EFF#GG#"•7V3•3BS£Bunun yerine "A A# B C C# D D# E F F# G G#"#birkaç bayt daha kısadır :).
Adnan

@Adnan: Ooh, güzel temel değişim :)
Emigna

Ayrıca "AA#BCC#DD#EFF#GG#"dizenin sıkıştırılmış bir sürümü : •™ÎÚ,Ülu•žh'#A«‡(küçük harflere izin verildiği için: p).
Adnan

9

JavaScript (ES6), 79 70 bayt

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

1 tabanlı dizeler gerektirir. Düzenleme: @ nimi eski cevabına dayanarak, doğrudan dönüştürme için dize hesaplayarak 9 bayt kaydedildi.


@Arnauld Teşekkürler ama bunun yerine @ nimi'nin cevabına sahip oldum.
Neil

Gerçekten çok daha verimli;)
Arnauld

Zeki. sinsi cevap
Rohan Jhunjhunwala

7

Mathematica, 62 bayt (rakip olmayan)

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

{24,19,15,10,5,0}Ve E2(örneğin, üst dize notu E2 yukarıda 24 semitones olan) altı gitar dizeleri açık dize sesleri temsil eder. Rekabet etmiyor çünkü nota isimlerini basmıyor — nota sırasını çalıyor ! (yalnızca ne yazık ki Mathematica'nız varsa) Örneğin,

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

Pachelbel Canon'dan 4 bar kadar oynuyor. (Pachelbel'in Canon'unun dayanabildiğim kadarıyla)


7

MATL , 48 47 45 bayt

Giriş formatı ile ilgili düzeltme için @Emigna'ya teşekkürler.

Gitar ve kod golfü ... Buna cevap vermek zorunda kaldım!

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

Girdi biçimi: (1 tabanlı) dize dizisi, sonra (0 tabanlı) perdeler dizisi.

Çevrimiçi deneyin!

açıklama

Bu cevapta kullanılan bazı dil özellikleri:

  • Bir dize otomatik olarak dönüştürülür kendisine bazı aritmetik işlemler uygulandığında sayısal bir ASCII kod noktaları dizisine .
  • Aritmetik işlemler eleman bazında çalışır , yani vektörize edilmiştir. Dolayısıyla, bir dizenin ve aynı boyuttaki sayısal bir dizinin çıkarılması, karşılık gelen girdilerin çıkarılmasıyla bir dizi verir.
  • Endeksleme 1 tabanlı ve modülerdir .
  • Bir hücre dizisi Diğer dillerde listesi gibidir. Rasgele öğeler, muhtemelen farklı tür veya boyutlardaki diziler içerebilir. Burada farklı uzunluktaki dizeleri (notların adları) saklamak için bir hücre dizisi kullanılacaktır.

Yorumlanan kod:

'$)-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
"Gitar" kelimesini görür görmez sizden bir cevap bulacağımı biliyordum
Suever

1
@LuisMendo Çok hoş! Ascii-char endeks hilesini
seviyorum

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, 104103 bayt

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

Sayıları string fretstdin'de çift olarak alır ve her çiftten sonra not verir. Örneğin:

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

3

Ruby, 63 bayt

sırasıyla 2 elemanlı diziler dizisini alır [string,fret].

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

açıklama

Standart ayarda gitar, telleri arasında tutarsız aralıklar olan birkaç telli enstrümandan (eğik veya perdeli) biridir. Çoğu, bitişik dizelerin tüm çiftleri arasında tutarlı bir 5-yarı ton aralığına ("dördüncü") veya bitişik dizelerin tüm çiftleri arasında tutarlı bir 5-yarı ton aralığına ("beşinci") sahiptir. Bunlar 3: 4 frekans oranlarına karşılık gelir ve sırasıyla 2: 3 olup, sadece frekans oranı 1: 2 olan "oktav" için ikinci sıradadır.

Gitarın çoğunlukla 5 yarı ton aralığı vardır. Bunlardan 5'i olsaydı, 1. ve 6. ipler arasında 25 yarı ton fark olurdu. Bunun yerine, 2. ve 3. dize arasındaki aralık 4 yarı tona düşürülür ve akorları çalmak için daha iyi olan 24 yarı ton (2 oktav) farkı verir.

Bu program için elverişsizdir, bu nedenle 1 endeksli gitar tonlamasını, 5 yarı tonun tüm aralıklarına sahip 0 indeksli 5 telli bas tonlamasına dönüştürerek başlıyoruz:

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

Sonra 2 ekliyoruz ve açık dizelerin tonlaması aşağıdaki gibi kurgusal 12 telli bas ayarını veriyoruz ve tüm aralıklar 5 yarı ton (12 telli "bas" var ama kesin olarak bununla çok fazla olduğundan emin değilim akort.)

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

Görülebileceği gibi, tüm keskinlikler birlikte gruplandırılmıştır. Bu örüntü sonsuz olarak tekrarlanabilir. "Beşinci daire" olarak bilinir ve Batı müzik ölçeği için temeldir (biraz ayarlama ayarlamasıyla daire (3/2)**12ve2**7 çok benzer sayılardır.

Şimdi fret parametresi ile ilgileniyoruz. Burada string parametresini bir dizi perdeye çeviren diğer birçok cevabın aksine, fret parametresini bir dizi dizeye çeviriyorum. Yukarıdaki tabloda, dize numarasına 7 eklemenin bizi not adı bir yarı ton daha yüksek olan bir dizeye koyduğu görülebilir. (Tamamen farklı bir oktavda ama önemli değil.) Yani i[1]*7dize numarasına ekliyoruz ve modulo 12'yi alıyoruz:

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

6 ile -5 arasında bir sayı elde etmek için 6'dan çıkarırız ve içindeki harfi BEADGCFararız (Ruby negatif dizinlerin dizinin sonuna kadar geri dönmesine izin verir.) Çıktıyı tamamlamak için n>=7bir #sembol eklememiz gerekiyorsa .

Test programı

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]

Çıktı

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

3

C #, 131 bayt

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

İki ayrı liste girin, dizeler 1 tabanlıdır.


1
Siteye Hoşgeldiniz! Güzel ilk cevap.
DJMcMayhem

@DJMcMayhem: Teşekkür ederim :-)
Taco

1

Clora , 55 bayt

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

açıklama

@ sayısal mod (girişi sayı olarak oku)

T[0,7,2,10,5,0,7] [Array] dizisini kullanarak girişi dönüştürün

+N Mevcut Girişe N (Sonraki giriş değeri) ekle

%12 Modulo 12 mevcut giriş değeri

@ Sayısal modu kapat

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Girişi bir diziye çevirin

! Girişi çıkış değeri olarak kullan


1

Java 7 197163 bayt

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 bayt

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]

Muhtemelen bazı belirgin iyileştirmeler yapılacaktır. Girdi, bir çiftler listesidir ve dizeler 0 dizinlidir, örn:

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

0

Haskell, 83 82 bayt

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

Her ikisi de 0 dizinli dizelerin ve perdelerin bir listesini alır. Kullanım örneği:

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

İle başlayan sonsuz not A#listesinden [6,1,9,4,11,6], dizenin dizinindeki listenin verdiği not sayısını bırakın ve kalan listeden perdenin dizinindeki notu seçin.


Ne yazık ki, dizeler arasındaki aralıkların hepsi eşit değildir.
Neil

@Neil: ... düzeltildi.
nimi

JavaScript'te basit bir düzeltme olduğu ortaya çıktı - (s*7)+(s>2)- şimdi cevabımda kullanıyorum.
Neil

@Neil: ... bunun üzerinde de çalışıyorum.
nimi

0

JavaScript (ES6), 82 81 bayt

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

Tam bir matematik cevabı denemek istedim, ama biraz uzun çıktı. Belki golf oynamanın bir yolu var ...

Test snippet'i


Kullanmak istedim toString(17)ama makul bir bayt sayısına ulaşmak için mücadele ettim.
Neil

0

PHP, 102 Bayt

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

'0 [[2,0], [5,3], [2,12], [3,8], [0,3]]' temel alınarak birden çok dizi olarak giriş yapın.

# Dayalı güzel bir alternatif 106 bayt Mod 7 uyumlu

<?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]._;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.