Az önce ne çaldım? Akorlara gitar parmaklarını çevir


22

Related: Müzik: Bu akorda neler var? , Tablatura Notları , Gitar sekmeleri oluşturma? , Sayı çiftlerini gitar notalarına çevirin

Bir gitar parmağı verildiğinde, temsil ettiği akoru verin. Standart girdi ve çıktıları kullanabilir veya bir dize döndüren bir işlev yazabilirsiniz.

Girdi parmak izleri, aşağıdaki şekilde ifade edilecek (kök nota C ise), aşağıdaki akorlardan biri olarak sınıflandırılabilir:

  • majör triad: C
  • küçük triad: Cm
  • (baskın) yedinci: C7
  • küçük yedinci: Cm7

Akor ters olabilir, bu nedenle en düşük nota kök olarak güvenemezsiniz. Bunun gerçek dünyadaki kolay ya da yaygın bir parmak olmasına da güvenemezsiniz. Daha genel olarak, programınızın çıktısı, perdelerin oktavlarını görmezden gelmeli ve aynı nota (yani A) karşılık gelen tüm perdelere eşit olarak davranmalıdır .

Bu , yani bayt cinsinden en kısa kod kazanır.

Giriş formatı

Giriş, standart ayardaki (EADGBE) 6 telli bir gitarın her bir teli için, o tizin çalınacağını belirten 6 değerlik bir seridir. Ayrıca, dizginin hiç oynatılmadığını gösterebilir. "Sıfır" perdesi açık konum olarak da bilinir ve perde sayıları buradan sayılır. Gitarın 21 perde pozisyonuna sahip olduğunu varsayalım, öyle ki en yüksek perde pozisyonu 20 numara.

Örneğin giriş X 3 2 0 1 0, parmaklarını gitarın boynunun üstündeki aşağıdaki konumlara yerleştirmek anlamına gelir:

(6th) |---|---|---|---|---
      |-X-|---|---|---|---
      |---|---|---|---|---
      |---|-X-|---|---|---
      |---|---|-X-|---|---
(1st) |---|---|---|---|---

ve 2. ile 6. diziler arasında tıngırdatmaya. Bu ASCII sekmesine karşılık gelir :

e |-0-|
B |-1-|
G |-0-|
D |-2-|
A |-3-|
E |---|

İstediğiniz giriş türünü seçme konusunda biraz esnekliğe sahipsiniz: her perdeli konum bir dize veya bir sayı olarak ifade edilebilir. Çalınamayan gitar telleri genel olarak bir ile gösterilir X, ancak eğer sizin için kolaylaştırırsa (örneğin, -1numaraları kullanıyorsanız) farklı bir sentinel değeri seçebilirsiniz . 6 perde pozisyonları serisi herhangi bir liste, dizi veya dizi tipi, boşlukla ayrılmış tek bir dize veya standart giriş olarak girilebilir - bir kez daha, seçiminiz.

Yukarıda belirtilen 4 akor türünden birine karşılık gelen girişe güvenebilirsiniz.

Lütfen gönderiminizde çözümünüzün ne tür girdiler aldığını açıklayın.

Çıkış biçimi

Standart çıktısına, parmak için gereken akoru tanımlayan bir dize döndürmek veya yazdırmanız gerekir. Bu dizge bir araya getirilmiş iki bölümden oluşur. Büyük harf kullanımı önemlidir. İzleyen boşlukta izin var.

İlk bölüm gösterir kök notu , biri A, A#/ Bb, B, C, C#/ Db, D, D#/ Eb, E, F, F#/ Gb, Gveya G#/ Ab. (Kullanıyorum #yerine ve byerine Unicode gerektiren önlemek için,.) Onlar olmadan ifade edilmelidir keskin veya düz olmayan eksprese edilebilir Kök notlar (hiçbir çıkış B#, Fbya da Dbb); tek bir keskin veya düz sembolle ifade edilemeyecek olanlar (yani veya C#veya Dbasla B##). Başka bir deyişle, notun ismindeki kaza sayısını (keskin veya düz) en aza indirmelisiniz.

İkinci bölüm, büyük bir üçlü için boş, mküçük bir üçlü 7için, baskın yedinci veya m7küçük yedinci için akor tipini gösterir . Böylece bir G major basitçe çıktı Giken, D output minor yedinci biri D#m7veya olarak çıkarılabilir Ebm7. Sonunda test vakalarında daha fazla örnek bulunabilir.

Teori ve ipuçları

Müzik notaları

Kromatik ölçekte oktav başına 12 adım vardır. Eşit mizaç ayarlandığı zaman, bu ziftlerin her biri, komşularından 1 eşit derecede uzaktır . 12 yarı tonlu (bir oktav) birbirinden uzak kalan tohumlar aynı nota olarak kabul edilir. Bu, 0'dan 11'e kadar olan 11 numaralı tamsayı gibi notları işleme koyabileceğimiz anlamına gelir. Bunlardan yedisine A'dan G'ye 2'ye harf isimleri verilmiştir. Keskin) bir nota bir yarı ton daha yüksek ve ♭ (düz) eklemek bir yarı ton daha düşük yapar.

Akorlar

Bir akor birlikte çalınan 2 veya daha fazla notadır. Akor türü, aralarındaki mesafelerle belirlenebilecek notlar arasındaki ilişkilere bağlıdır. Bir akorun daha önce de belirtildiği gibi bir kök notası vardır. Kök notayı bu örneklerde 0 olarak kabul edeceğiz, ancak bu isteğe bağlı ve bu zorlukla ilgilenen tek şey modulo aritmetiğindeki notalar arasındaki mesafe. Üçlü veya yedinci bir akor olan cevap için her zaman benzersiz bir akor türü olacaktır . Kök nota her zaman en düşük frekans aralığı olmayacak; akoru aşağıdaki dört akor türünden biri olarak tanımlayabileceğiniz kök notayı seçin:

  • Bir büyük üçlüsü notları ile bir akor olduğunu 0 4 7.
  • Bir minör üçlü notları ile bir akor olduğunu 0 3 7.
  • Bir baskın (ya da majör / minör), yedinci akor notlar sahiptir 0 4 7 10.
  • Bir minör (veya küçük / minör), yedinci akor notlar sahiptir 0 3 7 10. 3

Gitar tuning

6 telli bir gitarda standart ayar, en düşük teldeki E ile başlar ve 5, 5, 5, 4, ardından 5 yarı ton arasındaki aralıklarla notaları vurur. En düşük E'yi 0 olarak alarak, bu, gitarın tüm tellerinin tıngırdatılması, size 0 5 10 15 19 24modulo 12'nin eşdeğeri 0 5 10 3 7 0olan notaları veya notaları verir E A D G B E.

Çalıştı örnekleri

Eğer girişiniz buysa 0 2 2 0 0 0, bu notlara tekabül eder E B E G B E, bu yüzden sadece E, B ve G. Bunlar Embize kök olarak E ile numaralandırılarak görülebilen akoru oluşturur 0 3 7. (Sonuç X 2 X 0 X 0, veya için aynı olacaktır 12 14 14 12 12 12.)

4 4 6 4 6 4Girişiniz ise , bunları bir C root kökü ile numaralandırmak 7 0 7 10 4 7, veya 0 4 7 10, yani cevabı C#7(veya Db7) verir. Bunun yerine 4 4 6 4 5 4, numaralandırma (veya ) olan 7 0 7 10 3 7ya da verecekti .0 3 7 10C#m7Dbm7

Test durumları

X 3 2 0 1 0  --->  C
0 2 2 0 0 0  --->  Em
X 2 X 0 X 0  --->  Em
4 4 6 4 6 4  --->  C#7  (or Db7)
4 4 6 4 5 4  --->  C#m7 (or Dbm7)
0 2 2 1 0 0  --->  E
0 0 2 2 2 0  --->  A
X X 4 3 2 2  --->  F#   (or Gb)
3 2 0 0 0 1  --->  G7
X X 0 2 1 1  --->  Dm7
3 3 5 5 5 3  --->  C
4 6 6 5 4 4  --->  G#   (or Ab)
2 2 4 4 4 5  --->  B7
0 7 5 5 5 5  --->  Am7
7 6 4 4 X X  --->  B
8 6 1 X 1 3  --->  Cm
8 8 10 10 9 8 -->  Fm
0 19 5 16 8 7 -->  Em
6 20 0 3 11 6 -->  A#   (or Bb)
X 14 9 1 16 X -->  G#m  (or Abm)
12 14 14 12 12 12 --> Em
15 14 12 12 12 15 --> G
20 X 20 20 20 20  --> Cm7
X 13 18 10 11 10  --> A#7 (or Bb7)

1 frekanslarının logaritmaları ile

2 veya solfejde , do, re, mi gibi isimler . Bu mücadelede harf adlarını kullanın.

3 Bu, farklı bir kök nota seçeneğiyle, ana altıncı akor olarak da adlandırılabilir. Bu mücadelede, küçük yedinci adıyla adlandırın.


3
Büyük zorluk!
Luis Mendo

1
Benim gelecekteki meydan gelen dupe olarak sona cazip: D (aklımda çok benzer bir meydan okuma vardı ama obvously hıza sahipler.)
flawr

Çıkış dizesinde izleyen boşluk boşluğuna izin veriyor mu?
Luis Mendo

@LuisMendo emin; bu iyi.
Dan Getz

1
@ officialaimm hayır, başka herhangi bir durumla uğraşmanıza gerek yok. Her zaman bu 4 akor türünden biri olacağını varsayabilirsiniz. Başka bir deyişle, kodunuz farklı bir akor alırsa ne istersen yapabilir (hata veya yanlış cevap vermek dahil).
Dan Getz

Yanıtlar:


9

MATL , 115 114 bayt

[OAXICO]+tZN~)Y@!"@t1)XH- 12\XzXJK7hm?O.]JI7hm?'m'.]J[KCX]m?'7'.]J[ICX]m?'m7'.]]'FF#GG#AA#BCC#DD#E'l2741B~QY{HX)wh

Girdi biçimi [N 3 2 0 1 0]nerede, Nkullanılmayan dize belirtir.

Çıkış dizesi her zaman kullanır #, kullanmaz b.

Çevrimiçi deneyin! Veya çevrimiçi derleyicinin zaman aşımına uğramasını önlemek için tüm test durumlarını iki kısımda doğrulayın:

açıklama

[OAXICO]            % Push [0 5 10 3 7 0]. This represents the pitch of each open
                    % string relative to the lowest string, modulo 12
+                   % Add to implicit input. May contain NaN's, for unused strings
tZN~)               % Remove NaN's
Y@!                 % Matrix of all permutations, each in a column
"                   % For each column
  @                 %   Push current column
  t1)               %   Duplicate and get first entry
  XH                %   Copy into clipboard H
  - 12\             %   Subtract. This amounts to considering that the first note
                    %   of the current permutation is the root, and computing
                    %   all intervals with respect to that
  12\               %   Modulo 12
  Xz                %   Remove zeros
  XJ                %   Copy into clipboard J
  K7hm?             %   Are all intervals 4 or 7? If so: it's a major chord
    O               %     Push 0 (will become space when converted to char)
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  I7hm?             %   Are all intervals 3 or 7? If so: it's a minor chord
    'm'             %     Push this string
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  [KCX]m?           %   Are all intervals 4, 7 or 10? If so: it's a dominant-7th
                    %   chord
    '7'             %     Push this string
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  [ICX]m?           %   Are all intervals 3, 7 or 10? If so: it's a minor 7th chord
    'm7'            %     Push this string
    .               %     Break for loop
  ]                 %   End if
]                   % End for. The loop is always exited via one of the 'break'
                    % statements. When that happens, the stack contains 0, 'm',
                    % '7' or 'm7', indicating the type of chord; and clipboard H
                    % contains a number that tells the root note using the lowest 
                    % string as base (1 is F, 2 is F# etc)
'FF#GG#AA#BCC#DD#E' % Push this string. Will be split into strings of length 1 or 2
l                   % Push 1
2741B~Q             % Push [1 2 1 2 1 2 1 1 2 1 2 1] (obtained as 2741 in binary,
                    % negated, plus 1)
Y{                  % Split string using those lengths. Gives a cell array of
                    % strings: {'F', 'F#', ..., 'E'}
H                   % Push the identified root note
X)                  % Index into cell array of strings
wh                  % Swap and concatenate. Implicitly display

4

MS-DOS .COM dosyası (179 bayt)

Dosya (burada HEX olarak görüntülenir):

fc be 81 00 bf 72 01 31 db b9 06 00 51 e8 73 00
59 e2 f9 b9 0c 00 be 48 01 ad 39 c3 74 0d 40 75
f8 d1 fb 73 03 80 c7 08 e2 ec c3 31 db 88 cb 8a
87 59 01 e8 42 00 8a 87 65 01 e8 3b 00 81 c6 08
00 ac e8 33 00 ac eb 30 91 00 89 00 91 04 89 04
ff ff 00 00 6d 00 37 00 6d 37 42 41 41 47 47 46
46 45 44 44 43 43 00 23 00 23 00 23 00 00 23 00
23 00 04 09 02 07 0b 04 84 c0 74 06 b4 02 88 c2
cd 21 c3 8a 0d 47 ac 3c 20 76 fb 30 ed 3c 41 73
22 2c 30 72 0b 86 c5 b4 0a f6 e4 00 c5 ac eb ed
88 e8 00 c8 30 e4 b1 0c f6 f1 88 e1 b8 01 00 d3
e0 09 c3

Giriş komut satırı üzerinden verilir. Geçersiz giriş, geçersiz program davranışına neden olacaktır!

Assembler kodu şöyle görünür:

.text
.code16
ComFileStart:
    cld
    mov $0x81, %si
    mov $(TuneTable-ComFileStart+0x100), %di
    xor %bx, %bx
    # 6 strings: Build the mask of played tones
    mov $6, %cx
NextStringRead:
    push %cx
    call InsertIntoMask
    pop %cx
    loop NextStringRead

    # Check all base tones...
    mov $12, %cx
TestNextTone:
    mov $0x100+ChordTable-ComFileStart, %si
TestNextChord:
    lodsw
    # Is it the chord we are searching for?
    cmp %ax, %bx
    je FoundChord 
    # Is it the end of the table?
    inc %ax
    jnz TestNextChord
    # Transpose the chord we really play
    # and go to the next tone
    # This code rotates the low 12 bits of
    # BX one bit right
    sar $1, %bx
    jnc NoToneRotated
    add $8, %bh
NoToneRotated:
    loop TestNextTone
EndOfProgram:
    ret

FoundChord:
    # Get and print the tone name
    xor %bx, %bx
    mov %cl, %bl
    mov (ToneNamesTable+0x100-1-ComFileStart)(%bx),%al
    call printChar
    mov (ToneNamesTable+0x100+12-1-ComFileStart)(%bx),%al
    call printChar
    # Get the chord name suffix and print it
    add $(ChordNamesTable-ChordTable-2),%si
    lodsb
    call printChar
    lodsb
    # Note: Under MS-DOS 0x0000 is the first word on
    # the stack so the "RET" of printChar will jump
    # to address 0x0000 which contains an "INT $0x21"
    # (end of program) instruction
    jmp printChar

ChordTable:
    # Major, Minor, Major-7, Minor-7
    .word 0x91, 0x89, 0x491, 0x489, 0xFFFF
ChordNamesTable:
    .byte 0,0,'m',0,'7',0,'m','7'
ToneNamesTable:
    .ascii "BAAGGFFEDDCC"
    .byte 0,'#',0,'#',0,'#',0,0,'#',0,'#',0
TuneTable:
    .byte 4,9,2,7,11,4

#
# Subfunction: Print character AL;
#              Do nothing if AL=0
#
printChar:
    test %al, %al
    jz noPrint
    mov $2, %ah
    mov %al, %dl
    int $0x21
noPrint:
    ret

#
# Subfunction: Get one finger position
#              and insert it into a bit mask
#              of tones being played
#
# Input:
#
#   [DS:DI] = 
#        Tuning of current string (0=C, 1=C#, ..., 11=B)
#        Actually only 2=D, 4=E, 7=G, 9=A and 11=B are used
#
#   DS:SI = Next character to read
#
#   DF = Clear
#
# Input and Output:
#
#    BX = Bit mask
#    DI = Will be incremented
#
# Destroys nearly all registers but SI and BX
#
InsertIntoMask:
    mov (%di), %cl
    inc %di
SkipSpaces:
    lodsb
    cmp $' ', %al
    jbe SkipSpaces
# Now evaluate each digit
    xor %ch, %ch
GetNextDigit:
    # Number = 10*Number+Digit
    cmp $'A', %al
    jae DigitIsX
    sub $'0', %al
    jb DigitsDone
    xchg %al, %ch
    mov $10, %ah
    mul %ah
    add %al, %ch
    lodsb
    jmp GetNextDigit
DigitsDone:
    # Add the tune of the string
    # and perform modulus 12
    mov %ch, %al
    add %cl, %al
    xor %ah, %ah
    mov $12, %cl
    div %cl
    mov %ah, %cl
    mov $1, %ax
    shl %cl, %ax
    or %ax, %bx
DigitIsX:
    ret

Test durumları:

6 20 0 3 11 6 -->  A#   (or Bb)

İki piyano çaların "dördü elle" piyanoda çaldığını gördüm.

Bu test davası, bunu yapan gitaristleri ilk okuduğumda!

Sağ dokunulduğunda bile böyle bir kabloyu çalamazsınız!


Hmm, belki bir kalamar bu akoru oynayabilir? Sanırım rastgele bir aramada bulduğumlardan biri, bu yüzden bazı "zor" test durumları olabilir.
Dan Getz

3

Ruby, 129 bayt

Önceki sürümde olduğu gibi, ancak ayrıştırma adımı ve çıkış adımı arasında sıralama yapmak için üçlü operatörle birlikte tek bir döngü kullanır. Bu işi yapmak için başka bazı küçük değişiklikler yapılması gerekiyordu.

->a{r=0
18.times{|j|j<6?a[j]&&r|=8194<<(6--~j%5+a[j]*7)%12:(r/=2)&11==3&&puts("CGDAEBF"[j%7]+?#*(j/13)+['',?m,?7,'m7'][r>>9&3])}}

Ruby, 136 bayt

Llamda işlevi, 6 sayı dizisini argüman olarak kabul eder ve stdout'a çıkar. Kullanılmayan dize, sahte bir değerle temsil edilir (yakuttaki tek sahte değer nilve false.)

->a{r=0
6.times{|j|a[j]&&r|=4097<<(6--~j%5+a[j]*7)%12}
12.times{|j|r&11==3&&puts("FCGDAEB"[j%7]+?#*(j/7)+['',?m,?7,'m7'][r>>9&3]);r/=2}}

açıklama

Beşinci daireyi temel alan 12 aralığın gösterimini kullanıyorum . Bu, her bir perdesi, sekansı veren 7 yarı ton yüksek (veya 5 yarı ton düşük) izler F C G D A E B F# C# G# D# A#. Bunun 2 avantajı var. Birincisi, tüm keskin uçların bir arada göründüğü. Diğeri ise 5 telli basın açık telli notalarının birlikte ortaya çıkmasıdır: GDAEB (gitar ilişkilidir ancak biraz daha karmaşıktır, aşağıya bakınız).

İlk döngü 6 kez çalışır. İfadesi 6--~j%5(eşit biçimde 6-(j+1)%5) açık dizeleri not değerleri verir: E=5 A=4 D=3 G=2 B=6 E=5. Buna, perdesi 7 ile çarpılan perdeyi ekleriz (yukarıda görüldüğü gibi, bir yarı ton eklemek bizi sırayla 7 basamak ileri götürür.) Sonra, modulo 12'nin tamamını alır ve mevcut notların bitmapini yaparız (biz 4097<<note valueardışık 2 oktav vermek için kullanılır .)

Bitmap'i besledikten sonra, akoru aramaya ve çıkarmaya hazırız.

Aşağıdaki notlarla ilgileniyoruz:

Note       position in      position in             Note      position in 
           semitone domain  circle of fifths                  circle of fifths 
Root       0                0                       Root      0
Minor 3rd  3                9                       Fifth     1
Major 3rd  4                4                       Sixth     3
Fifth      7                1                       Major 3rd 4
Sixth      9                3                       Minor 3rd 9
Minor 7th  10               10                      Minor 7th 10

F akorunu kontrol ederek başlayarak, kökün ve beşincinin mevcut olup olmadığını kontrol ederiz: bit 0 ve 1 (en az anlamlı olan sayım: 1 ve 2'nin bitleri.) Altıncı akorları reddetmek için ayrıca altıncı yok: bit 3 (8's bit.) öyleyse kontrol ederiz r&&11==3ve öyleyse akoru basarız.

Büyük üçüncü kişiyi görmezden geliyoruz ve tamamen akor tipini bulmak için 9 bit (minör üçüncü) ve 10 bit (7. İfade r>>9&3, bir diziden doğru akor tipini seçmek için kullanılır.

Döngünün sonunda, bitmap doğru bir bit vardiya r/=2sırayla mümkün akor kökleri test etmek: F C G D A E B F# C# G# D# A#.

Test programında Ungolfed

f=->a{                            #Accept array of 6 numbers as argument.
  r=0                             #Setup an empty bitmap.

  6.times{|j|                     #For each string
    a[j]&&                        #if the fret value is truthy (not nil or false)
    r|=4097<<(6--~j%5+a[j]*7)%12  #calculate the note value in the circle of fifths and add to the bitmap.
  }

  12.times{|j|                    #For each possible root note
    r&11==3&&                     #if root and fifth are present (bits 0 and 1) and sixth is absent (bit 3) 
    puts("FCGDAEB"[j%7]+?#*(j/7)+ #output the note name and a sharp symbol if necessary, followed by
    ['',?m,?7,'m7'][r>>9&3])      #m and/or 7 as indicate by bits 9 and 10.
    r/=2
  }
}

print 1;f[[nil,3,2,0,1,0]]       #  C
print 2;f[[0,2,2,0,0,0]]         #  Em
print 3;f[[nil,2,nil,0,nil,0]]   #  Em
print 4;f[[4,4,6,4,6,4]]         #  C#7 
print 5;f[[4,4,6,4,5,4]]         #  C#m7 
print 6;f[[0,2,2,1,0,0]]         #  E
print 7;f[[0,0,2,2,2,0]]         #  A
print 8;f[[nil,nil,4,3,2,2]]     #  F#  
print 9;f[[3,2,0,0,0,1]]         #  G7
print 10;f[[nil,nil,0,2,1,1]]    #  Dm7
print 11;f[[3,3,5,5,5,3]]        #  C
print 12;f[[4,6,6,5,4,4]]        #  G#  
print 13;f[[2,2,4,4,4,5]]        #  B7
print 14;f[[0,7,5,5,5,5]]        #  Am7
print 15;f[[7,6,4,4,nil,nil]]    #  B
print 16;f[[8,6,1,nil,1,3]]      #  Cm
print 17;f[[8,8,10,10,9,8]]      #  Fm
print 18;f[[0,19,5,16,8,7]]      #  Em
print 19;f[[6,20,0,3,11,6]]      #  A#  
print 20;f[[nil,14,9,1,16,nil]]  #  G#m 
print 21;f[[12,14,14,12,12,12]]  #  Em
print 22;f[[15,14,12,12,12,15]]  #  G
print 23;f[[20,nil,20,20,20,20]] #  Cm7
print 24;f[[nil,13,18,10,11,10]] #  A#7

2

Javascript (ES6), 335 333 bayt

Bu meydan okuma ve PPCG SE seviyorum! Bu benim ilk golf - önerileriniz memnuniyetle karşılıyor. (Ben f = sayıma dahil ettiğim için 2 bayt çaldı)

İşlev f, sayıları ve 'X' i temsil eden bir dizi diziyi alır, benzer f(['X','3','2','0','1','0'])ve bir akor (doğal veya keskin) benzeri döndürür E#m7. Netlik için eklenen yeni satırlar (bayt sayısına dahil değil)

f=c=>[s=new Map([[435,''],[345,'m'],[4332,7],[3432,'m7']]),
n=[...new Set(c.map((e,i)=>e?(+e+[0,5,10,3,7,0][i])%12:-1)
.filter(e=>++e).sort((a,b)=>a>b))],d=[...n,n[0]+12].reduce(
(a,c,i)=>i?[...a,(c-n[i-1]+12)%12]:[],0).join``.repeat(2),
m=+d.match(/(34|43)(5|32)/g)[0],'E0F0F#0G0G#0A0A#0B0C0C#0D0D#'
.split(0)[n[d.indexOf(m)]]+s.get(m)][4]

Kullanım örneği:

console.log(f(['0','2','2','0','0','0'])); // Em

Test durumlarını çalıştırmak için:

tests=`X 3 2 0 1 0 ---> C
0 2 2 0 0 0 ---> Em
X 2 X 0 X 0 ---> Em
4 4 6 4 6 4 ---> C#7 (or Db7)
4 4 6 4 5 4 ---> C#m7 (or Dbm7)`; // and so on...

tests.split`\n`.forEach(e=>{
    console.log(`Test: ${e}
      Result: ${f(e.split(' ').slice(0,6))}`)
})

Açıklama ile Ungolfed versiyonu:

f = (c) => {
    s = new Map([
        [435,''], [345,'m'], [4332,7], [3432,'m7'] 
    ]) /* Each key in s describes the intervals (semitones)
          between consecutive notes in a chord, when it is
          reduced to a single octave, including the interval
          from highest back to lowest. The values describe
          the corresponding chord suffix. E.g. C-E-G has
          intervals C-4-E-3-G-5-C. 435=major=no suffix. */

    n = [ ...new Set(
        c.map( 
         (e,i) => e ? ( +e + [0,5,10,3,7,0][i] )%12 : -1 
         ).filter( (e) => ++e ).sort( (a,b) => a>b )
        ) ] /* take the input array, c, and transform each fret
               position into a note. remove non-notes (-1), sort
               in tone order, remove duplicates. An input of
               positions X 13 18 10 11 10 becomes notes
               (-1) 6 4 1 6 10 then 1 4 6 10. */

    d = [ ...n, n[0] + 12 ].reduce(
        (a,c,i) => i ? [ ...a, (c - n[i-1] + 12)%12 ] : [], 0
    ).join``.repeat(2)
    /* convert the note array, n, into an interval string, d,
       including the lowest note repeated above it to capture
       all intervals. Repeat it twice so that, regardless of the
       inversion played, the intervals will appear in root order
       somewhere. E.g. notes 1-4-6-10 and 13 (1+12)
       become intervals 3 2 4 3, and string for searching
       32433243 */

    m = +d.match( /(34|43)(5|32)/g )[0];
      /* m is the matched chord pattern. In this case, 4332. */

    return 'E0F0F#0G0G#0A0A#0B0C0C#0D0D#'.split(0)[
    n[ d.indexOf(m) ]
    /* get the position in the interval string where the root
       interval first occurs. this corresponds to the position
       of the chord root note in the note array, n. convert this
       number 0-12 to a note name E - D# */
    ] + s.get(m)
       /* add the suffix corresponding to the matched
       chord interval pattern */
}

1
Siteye Hoşgeldiniz! Hoşunuza gittiğini duyduğuma sevindim. :) Ne yazık ki, herhangi bir JS tanımıyorum, bu yüzden herhangi bir ipucu yok, ancak bazılarını burada
DJMcMayhem
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.