Tôi vừa chơi gì? Dịch ngón tay guitar theo hợp âm


22

Liên quan: Âm nhạc: những gì trong hợp âm này? , Ghi chú cho Tablature , Tạo tab guitar? , Dịch cặp số sang ghi chú guitar

Cho một ngón đàn guitar, xuất ra hợp âm mà nó đại diện. Bạn có thể sử dụng đầu vào và đầu ra tiêu chuẩn hoặc viết một hàm trả về một chuỗi.

Các ngón tay đầu vào sẽ được phân loại là một trong những hợp âm sau, được thể hiện như sau (nếu ghi chú gốc là C):

  • bộ ba chính: C
  • bộ ba nhỏ: Cm
  • (chiếm ưu thế) thứ bảy: C7
  • thứ bảy nhỏ: Cm7

Hợp âm có thể bị đảo ngược, vì vậy bạn không thể dựa vào nốt thấp nhất là gốc. Bạn cũng không thể dựa vào điều này là một ngón tay dễ dàng hoặc phổ biến trong thế giới thực. Tổng quát hơn, đầu ra của chương trình của bạn phải bỏ qua quãng tám của các nốt và coi tất cả các nốt tương ứng với cùng một nốt nhạc (nghĩa là A) bằng nhau.

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng.

định dạng đầu vào

Đầu vào là một chuỗi gồm 6 giá trị cho biết, đối với mỗi chuỗi của guitar 6 dây trong điều chỉnh tiêu chuẩn (EADGBE), sẽ băn khoăn chuỗi đó sẽ được phát. Nó cũng có thể chỉ ra rằng chuỗi này hoàn toàn không được phát. Băn khoăn "zeroth" còn được gọi là vị trí mở và số lượng băn khoăn đếm từ đó. Giả sử đàn guitar có 21 vị trí băn khoăn, sao cho vị trí băn khoăn cao nhất là số 20.

Ví dụ: đầu vào X 3 2 0 1 0có nghĩa là đặt các ngón tay ở các vị trí sau trên đỉnh cổ của guitar:

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

và xâu chuỗi thứ 2 đến thứ 6. Nó tương ứng với tab ASCII này :

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

Bạn có một số linh hoạt trong việc chọn loại đầu vào bạn muốn: mỗi vị trí băn khoăn có thể được thể hiện dưới dạng một chuỗi hoặc một số. Các dây đàn guitar không được chơi thường được chỉ định bằng một X, nhưng bạn có thể chọn một giá trị sentinel khác nếu điều đó giúp bạn dễ dàng hơn (chẳng hạn như -1nếu bạn đang sử dụng số). Chuỗi 6 vị trí băn khoăn có thể được nhập vào dưới dạng bất kỳ danh sách, mảng hoặc loại chuỗi nào, một chuỗi được phân tách bằng dấu cách hoặc một lần nữa là đầu vào tiêu chuẩn, một lần nữa, bạn chọn.

Bạn có thể dựa vào đầu vào tương ứng với một trong 4 loại hợp âm được đề cập ở trên.

Vui lòng giải thích trong bài viết của bạn về hình thức đầu vào mà giải pháp của bạn thực hiện.

Định dạng đầu ra

Bạn phải quay lại hoặc in ra đầu ra tiêu chuẩn một chuỗi mô tả hợp âm mà ngón tay dành cho. Chuỗi này bao gồm hai phần được nối với nhau. Vấn đề vốn. Khoảng trống Trailing được cho phép.

Phần đầu tiên chỉ ra nốt gốc , một trong những A, A#/ Bb, B, C, C#/ Db, D, D#/ Eb, E, F, F#/ Gb, Ghay G#/ Ab. (Tôi đang sử dụng #thay vì , và bthay vì , để tránh yêu cầu Unicode.) Ghi chú rễ có thể được thể hiện mà không có một sắc nét hoặc căn hộ phải được thể hiện mà không có họ (không bao giờ đầu ra B#, Fbhoặc Dbb); những cái không thể được thể hiện bằng một biểu tượng sắc nét hoặc phẳng (nghĩa là C#hoặc Db, nhưng không bao giờ B##). Nói cách khác, bạn phải giảm thiểu số lượng tai nạn (vật sắc nhọn hoặc căn hộ) trong tên của ghi chú.

Phần thứ hai chỉ ra loại hợp âm, hoặc trống cho một bộ ba chính, mcho một bộ ba nhỏ, 7cho thứ bảy chiếm ưu thế, hoặc m7cho thứ bảy thứ yếu. Vì vậy, một G chính là đầu ra đơn giản là G, trong khi một D thứ bảy có thể là đầu ra là D#m7hoặc Ebm7. Nhiều ví dụ có thể được tìm thấy trong các trường hợp thử nghiệm ở cuối.

Lý thuyết & gợi ý

Nốt nhạc

Thang màu có 12 nốt trên mỗi quãng tám. Khi được điều chỉnh để tính khí bằng nhau, mỗi nốt này đều cách xa nhau so với các nước láng giềng 1 . Các nốt cách nhau 12 nửa cung (một quãng tám) được coi là cùng một nốt nhạc. Điều này có nghĩa là chúng ta có thể xử lý các ghi chú như số nguyên modulo 12, từ 0 đến 11. Bảy trong số này được đặt tên chữ cái 2 từ A đến G. Điều này không đủ để đặt tên cho tất cả 12 nốt, nhưng thêm các sửa lỗi vô tình: thêm một ( sắc nét) đến một ghi chú làm cho nó cao hơn một nửa cung và thêm ♭ (phẳng) làm cho nó thấp hơn một nửa cung.

Hợp âm

Một hợp âm là 2 hoặc nhiều nốt được chơi cùng nhau. Loại hợp âm phụ thuộc vào mối quan hệ giữa các nốt, có thể được xác định bởi khoảng cách giữa chúng. Một hợp âm có một nốt gốc, như đã đề cập trước đó. Chúng tôi sẽ coi ghi chú gốc là 0 trong các ví dụ này, nhưng điều này là tùy ý và tất cả những gì quan trọng trong thử thách này là khoảng cách giữa các ghi chú trong số học modulo. Sẽ luôn có một loại hợp âm duy nhất cho câu trả lời, đó là hợp âm ba hoặc hợp âm thứ bảy . Ghi chú gốc sẽ không phải luôn luôn là tần số thấp nhất; chọn ghi chú gốc sao cho bạn có thể mô tả hợp âm là một trong bốn loại hợp âm sau:

  • Một bộ ba chính là một hợp âm với các nốt 0 4 7.
  • Một bộ ba nhỏ là một hợp âm với các nốt 0 3 7.
  • Một hợp âm thứ bảy chiếm ưu thế (hoặc chính / phụ) có các nốt 0 4 7 10.
  • Một hợp âm thứ bảy (hoặc nhỏ / phụ) có các nốt 0 3 7 10. 3

Điều chỉnh guitar

Điều chỉnh tiêu chuẩn trên đàn guitar 6 dây bắt đầu bằng E trên dây thấp nhất và sau đó nhấn các nốt trong các khoảng thời gian 5, 5, 5, 4, sau đó 5 nửa cung đi lên dây. Lấy E thấp nhất là 0, điều này có nghĩa là xâu chuỗi tất cả các dây của đàn guitar mang lại cho bạn các nốt được đánh số 0 5 10 15 19 24, mà modulo 12 tương đương với 0 5 10 3 7 0hoặc các nốt E A D G B E.

Ví dụ làm việc

Nếu đầu vào của bạn là 0 2 2 0 0 0, điều này tương ứng với các ghi chú E B E G B E, do đó, chỉ E, B và G. Những hình thức này là hợp âm Em, có thể được nhìn thấy bằng cách đánh số chúng với gốc là E, cho chúng ta 0 3 7. (Kết quả sẽ giống nhau cho X 2 X 0 X 0, hoặc 12 14 14 12 12 12.)

Nếu đầu vào của bạn là 4 4 6 4 6 4, đánh số này bằng gốc C root đưa ra 7 0 7 10 4 7, hoặc 0 4 7 10, vì vậy câu trả lời là C#7(hoặc Db7). Nếu đó là thay vào đó 4 4 6 4 5 4, việc đánh số sẽ cho 7 0 7 10 3 7, hoặc 0 3 7 10, đó là C#m7(hoặc Dbm7).

Các trường hợp thử nghiệm

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 bởi các logarit của tần số của chúng

2 hoặc, trong solfège , tên như do, re, mi . Trong thử thách này, sử dụng tên chữ cái.

3 Điều này cũng có thể được gọi là hợp âm thứ sáu lớn, với một sự lựa chọn khác nhau của ghi chú gốc. Trong thử thách này, gọi nó bằng tên thứ bảy nhỏ của nó.


3
Thử thách lớn!
Luis Mendo

1
Bị cám dỗ đóng cửa như một kẻ lừa bịp từ thử thách trong tương lai của tôi: D (Tôi có một thử thách rất giống trong tâm trí, nhưng bạn đã nhanh nhẹn hơn rất nhiều.)
flawr

Là khoảng trắng theo dõi được phép trong chuỗi đầu ra?
Luis Mendo

@LuisMendo chắc chắn; đó là tốt.
Dan Getz

1
@officialaimm không, bạn không cần phải xử lý bất kỳ tình huống nào khác. Bạn có thể cho rằng nó sẽ luôn là một trong 4 loại hợp âm đó. Nói cách khác, mã của bạn có thể làm bất cứ điều gì bạn muốn (bao gồm lỗi hoặc trả lời sai) nếu nó có một hợp âm khác.
Dan Getz

Câu trả lời:


9

TOÁN , 115 114 byte

[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

Định dạng đầu vào là [N 3 2 0 1 0], trong đó Nchỉ ra chuỗi không sử dụng.

Chuỗi đầu ra luôn sử dụng # , không b.

Hãy thử trực tuyến!Hoặc xác minh tất cả các trường hợp kiểm tra, trong hai phần để tránh thời gian trình biên dịch trực tuyến hết thời gian:

Giải trình

[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

Tệp MS-DOS .COM (179 byte)

Tệp (ở đây được hiển thị dưới dạng HEX):

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

Đầu vào được đưa ra thông qua dòng lệnh. Đầu vào không hợp lệ sẽ dẫn đến hành vi chương trình không hợp lệ!

Mã trình biên dịch mã trông như thế này:

.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

Các trường hợp thử nghiệm:

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

Tôi đã thấy hai người chơi đàn piano chơi với nhau "bốn tay" trên một cây đàn piano.

Trường hợp thử nghiệm này là lần đầu tiên tôi đọc về người chơi guitar làm điều này!

Ngay cả khi chạm tay phải, bạn cũng không thể chơi một sợi dây như thế này!


Hmm, có lẽ một con mực có thể chơi hợp âm đó? Tôi nghĩ đó là một trong những cái tôi tìm thấy trong một tìm kiếm ngẫu nhiên để có thể có một số trường hợp thử nghiệm "khó".
Dan Getz

3

Ruby, 129 byte

Là phiên bản trước nhưng sử dụng một vòng lặp duy nhất, với toán tử ternary để tuần tự giữa bước phân tích cú pháp và bước đầu ra. Một số sửa đổi nhỏ khác được yêu cầu để làm cho công việc này.

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

Hàm Llamda chấp nhận một mảng gồm 6 số làm đối số và xuất ra thiết bị xuất chuẩn. Chuỗi không sử dụng được biểu thị bằng một giá trị giả (giá trị giả duy nhất trong ruby ​​là nilfalse.)

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

Giải trình

Tôi sử dụng một đại diện của 12 nốt nhạc dựa trên vòng tròn thứ năm . Điều này có nghĩa là mỗi nốt được theo sau bởi cao hơn 7 nửa cung (hoặc thấp hơn 5 nửa cung) cho chuỗiF C G D A E B F# C# G# D# A# . Có 2 lợi thế cho việc này. Một là tất cả các vật sắc nhọn xuất hiện cùng nhau. Một điều nữa là các nốt nhạc mở của bass 5 dây xuất hiện cùng nhau: GDAEB (guitar có liên quan nhưng phức tạp hơn một chút, xem bên dưới).

Vòng lặp đầu tiên chạy 6 lần. Biểu thức 6--~j%5(tương đương 6-(j+1)%5) đưa ra các giá trị ghi chú cho các chuỗi mở : E=5 A=4 D=3 G=2 B=6 E=5. Để làm điều này, chúng tôi thêm số băn khoăn nhân với 7 (như có thể thấy ở trên, thêm một nửa cung di chuyển chúng tôi 7 vị trí về phía trước trong chuỗi.) Sau đó, chúng tôi lấy toàn bộ modulo 12 và tạo một bitmap của các ghi chú hiện diện (chúng tôi sử dụng 4097<<note valueđể cho 2 quãng tám liên tiếp.)

Sau khi soạn bitmap, chúng tôi sẵn sàng tìm kiếm hợp âm và xuất nó.

Chúng tôi quan tâm đến các lưu ý sau:

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

Bắt đầu bằng cách kiểm tra hợp âm F, chúng tôi kiểm tra xem có gốc và thứ năm hay không: bit 0 và 1 (tính từ ít nhất có ý nghĩa: các bit 1 và 2.) Để từ chối hợp âm thứ sáu, chúng tôi cũng cần kiểm tra xem hợp âm thứ sáu không không có: bit 3 (bit 8). vì vậy chúng tôi kiểm tra xem r&&11==3và nếu vậy chúng tôi sẽ in hợp âm.

Chúng tôi bỏ qua phần ba chính và hoàn toàn dựa vào bit 9 (phần ba nhỏ) và bit 10 (phần 7 nhỏ) để tìm ra loại hợp âm. Biểu thức r>>9&3được sử dụng để chọn loại hợp âm chính xác từ một mảng.

Vào cuối vòng lặp, chúng tôi dịch chuyển bitmap sang phải một bit r/=2để kiểm tra các gốc hợp âm có thể theo thứ tự : F C G D A E B F# C# G# D# A#.

Ungolfed trong chương trình thử nghiệm

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 byte

Thích thử thách này và PPCG SE! Đây là môn đánh gôn đầu tiên của tôi - những gợi ý được chào đón vì tôi chắc chắn rằng nó có thể được cải thiện rất nhiều. (loại bỏ 2 byte như tôi đã bao gồm f = trong số đếm)

Hàm flấy một chuỗi các chuỗi, biểu thị các số và 'X', thích f(['X','3','2','0','1','0'])và trả về một hợp âm (tự nhiên hoặc sắc nét) như thế nào E#m7. Các dòng mới được thêm vào cho rõ ràng (không bao gồm trong số byte)

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]

Ví dụ sử dụng:

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

Để chạy các trường hợp thử nghiệm:

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

Phiên bản Ungolfed với lời giải thích:

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
Chào mừng đến với trang web! Tôi rất vui khi nghe bạn thích nó. :) Thật không may, tôi không biết bất kỳ JS nào vì vậy tôi không có bất kỳ lời khuyên nào, nhưng bạn có thể tìm thấy một số ở đây
DJMcMayhem
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.