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.