ฉันเพิ่งเล่นอะไร แปลกีตาร์นิ้วเป็นคอร์ด


22

ที่เกี่ยวข้อง: เพลง: มีอะไรในคอร์ดนี้? , หมายเหตุ tablature , ฝ่ายผลิตแท็บกีต้าร์? , แปลคู่จำนวนบันทึกกีตาร์

ให้นิ้วกีตาร์เอาท์พุทคอร์ดที่มันหมายถึง คุณสามารถใช้อินพุตและเอาต์พุตมาตรฐานหรือเขียนฟังก์ชันที่ส่งคืนสตริง

การป้อนข้อมูลด้วยนิ้วจะจัดเป็นหนึ่งในคอร์ดต่อไปนี้ที่จะแสดงดังต่อไปนี้ (ถ้าบันทึกรูทเป็น C):

  • คณะสาม C
  • รองลงมา: Cm
  • (เด่น) เจ็ด: C7
  • น้อยเจ็ด: Cm7

คอร์ดอาจจะกลับด้านดังนั้นคุณไม่สามารถเชื่อใจโน้ตที่ต่ำที่สุดว่าเป็นราก คุณไม่สามารถเชื่อใจได้ว่าสิ่งนี้เป็นนิ้วที่ง่ายหรือเป็นเรื่องธรรมดาในโลกแห่งความเป็นจริง โดยทั่วไปเอาต์พุตของโปรแกรมของคุณจะต้องละเว้นอ็อกเทฟของพิทช์และปฏิบัติต่อพิทช์ทั้งหมดที่สอดคล้องกับโน้ตเพลงเดียวกัน (เช่นA) เท่ากัน

นี่คือดังนั้นโค้ดที่สั้นที่สุดในหน่วยไบต์ชนะ

รูปแบบอินพุต

อินพุตเป็นชุดของค่า 6 ค่าที่ระบุสำหรับแต่ละสายของกีตาร์ 6-string ในการปรับแต่งมาตรฐาน (EADGBE) ซึ่งทำให้ไม่สบายใจที่สตริงนั้นจะเล่น มันอาจบ่งบอกว่าสายไม่ได้เล่นเลย หงุดหงิด "zeroth" เป็นที่รู้จักกันว่าตำแหน่งที่เปิดและทำให้ไม่สบายใจจำนวนนับจากที่นั่น สมมติว่ากีต้าร์มีตำแหน่งหงุดหงิด 21 ตำแหน่งซึ่งตำแหน่งหงุดหงิดสูงสุดคือหมายเลข 20

ตัวอย่างเช่นอินพุตX 3 2 0 1 0หมายถึงการวางนิ้วมือที่ตำแหน่งต่อไปนี้ที่ด้านบนของคอกีตาร์:

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

และก้าวเดินสายที่ 2 ถึงสายที่ 6 มันสอดคล้องกับแท็บ ASCIIนี้:

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

คุณมีความยืดหยุ่นในการเลือกประเภทของการป้อนข้อมูลที่คุณต้องการ: แต่ละตำแหน่งที่ไม่สบายใจสามารถแสดงเป็นสตริงหรือตัวเลข สายกีต้าร์ที่ไม่ได้เล่นมักจะระบุด้วยXแต่คุณสามารถเลือกค่า Sentinel ที่แตกต่างได้ถ้ามันทำให้คุณง่ายขึ้น (เช่น-1ถ้าคุณกำลังใช้ตัวเลข) ชุดของตำแหน่งที่หงุดหงิด 6 ตำแหน่งสามารถป้อนเป็นรายการอาร์เรย์หรือลำดับใด ๆ ก็ได้สตริงที่คั่นด้วยช่องว่างเดียวหรือเป็นอินพุตมาตรฐาน - อีกครั้งที่คุณเลือก

คุณสามารถพึ่งพาอินพุตที่สอดคล้องกับหนึ่งใน 4 ชนิดของคอร์ดที่กล่าวถึงข้างต้น

โปรดอธิบายในโพสต์ของคุณว่ารูปแบบการป้อนข้อมูลของคุณเป็นอย่างไร

รูปแบบผลลัพธ์

คุณต้องส่งคืนหรือพิมพ์ไปที่เอาต์พุตมาตรฐานสตริงที่อธิบายคอร์ดที่ใช้สำหรับ สตริงนี้ประกอบด้วยสองส่วนที่ต่อกัน การใช้อักษรตัวพิมพ์ใหญ่มีความสำคัญ อนุญาตช่องว่างต่อท้าย

ส่วนแรกแสดงให้เห็นโน้ตราก , หนึ่งA, A#/ Bb, B, C, C#/ Db, D, D#/ Eb, E, F, F#/ Gb, Gหรือ/G# Ab(ฉันใช้#แทนและbแทนเพื่อหลีกเลี่ยงการกำหนด Unicode.) บันทึกรากที่สามารถแสดงได้โดยไม่ต้องมีคมหรือแบนจะต้องแสดงโดยที่พวกเขา (ไม่เคยส่งออกB#, FbหรือDbb); ผู้ที่ไม่สามารถแสดงด้วยสัญลักษณ์คมหรือแบนเดียว (เช่นอย่างใดอย่างหนึ่งC#หรือDbแต่ไม่เคยB##) กล่าวอีกนัยหนึ่งคุณต้องลดจำนวนอุบัติเหตุ (ชาร์ปหรือแฟลต) ให้น้อยที่สุดในชื่อโน้ต

ส่วนที่สองแสดงถึงประเภทของคอร์ดไม่ว่าจะว่างเปล่าสำหรับคณะสามหรือmกลุ่มรอง7สำหรับกลุ่มที่เจ็ดหรือm7สำหรับกลุ่มที่เจ็ด ดังนั้น G ที่สำคัญคือการส่งออกก็เป็นGในขณะที่เจ็ดD♯เล็ก ๆ น้อย ๆ อาจจะออกเป็นอย่างใดอย่างหนึ่งหรือD#m7 Ebm7ตัวอย่างเพิ่มเติมสามารถพบได้ในกรณีทดสอบในตอนท้าย

ทฤษฎีและคำใบ้

โน้ตดนตรี

ระดับสีมี 12 สนามต่อคู่ เมื่อปรับให้เท่ากันนิสัยแต่ละสนามเหล่านี้เป็นสิ่งที่ห่างไกลอย่างเท่าเทียมกันจากประเทศเพื่อนบ้าน1 สนามที่มี 12 semitonesห่างกัน (อ็อกเทฟ) ถือว่าเป็นโน้ตดนตรีเดียวกัน ซึ่งหมายความว่าเราสามารถรักษาโน้ตได้เช่นจำนวนเต็มโมดูโล 12 จาก 0 ถึง 11 เจ็ดรายการเหล่านี้จะได้รับชื่อตัวอักษร2จาก A ถึง G ซึ่งไม่เพียงพอที่จะตั้งชื่อทั้ง 12 สนาม แต่เพิ่มการแก้ไขอุบัติเหตุโดย: เพิ่ม♯ ( คมชัด) สำหรับโน้ตทำให้หนึ่ง semitone สูงขึ้นและการเพิ่ม flat (แฟล็ต) ทำให้หนึ่ง semitone ต่ำลง

คอร์ด

คอร์ดคือ 2 หรือมากกว่าบันทึกเล่นด้วยกัน ประเภทของคอร์ดขึ้นอยู่กับความสัมพันธ์ระหว่างบันทึกซึ่งสามารถกำหนดได้โดยระยะทางระหว่างพวกเขา คอร์ดมีรูทโน้ตตามที่กล่าวไว้ก่อนหน้านี้ เราจะถือว่ารูทโน้ตเป็น 0 ในตัวอย่างเหล่านี้ แต่นี่เป็นเรื่องที่ไม่แน่นอนและสิ่งที่สำคัญในความท้าทายนี้คือระยะห่างระหว่างโน้ตในโมดูโลคณิตศาสตร์ ก็จะเป็นหนึ่งในประเภทคอร์ดที่ไม่ซ้ำกันสำหรับคำตอบทั้งสามหรือคอร์ดที่เจ็ด โน้ตรูทนั้นจะไม่ได้เป็นระดับเสียงต่ำสุดเสมอไป เลือกบันทึกย่อที่คุณสามารถอธิบายคอร์ดเป็นหนึ่งในสี่ประเภทต่อไปนี้:

  • หลักสาม0 4 7เป็นคอร์ดกับบันทึกที่
  • สามรองลงมา0 3 7คือคอร์ดกับบันทึกที่
  • ที่โดดเด่น (หรือที่สำคัญ / เล็กน้อย) เจ็ด0 4 7 10คอร์ดมีการบันทึก
  • เล็กน้อย (หรือรายย่อย / เล็กน้อย) เจ็ด0 3 7 10คอร์ดมีการบันทึก 3

การปรับจูนกีตาร์

การปรับจูนแบบมาตรฐานของกีตาร์ 6-string เริ่มต้นด้วย E บนสตริงที่ต่ำที่สุดจากนั้นจะบันทึกโน้ตเป็นระยะ 5, 5, 5, 4 และ 5 เซมิโคลนขึ้นไป การ E ต่ำสุดเป็น 0 หมายถึงนี้ก้าวเดินทุกสายของกีต้าร์ช่วยให้คุณโหมโรงเลข0 5 10 15 19 24ที่โมดูโล 12 เทียบเท่ากับหรือบันทึก0 5 10 3 7 0E A D G B E

ทำงานตัวอย่าง

ถ้าใส่ของคุณ0 2 2 0 0 0สอดคล้องนี้เพื่อบันทึกE B E G B Eดังนั้นเพียงแค่ E, B และกรัมรูปแบบเหล่านี้คอร์ดEmซึ่งสามารถมองเห็นได้ด้วยเลขพวกเขามีรากเป็น E 0 3 7ให้เรา (ผลลัพธ์จะเหมือนกันสำหรับX 2 X 0 X 0หรือ12 14 14 12 12 12.)

หากอินพุตของคุณคือการ4 4 6 4 6 4นับหมายเลขเหล่านี้ด้วยรูทของC♯ให้7 0 7 10 4 7หรือ0 4 7 10ดังนั้นคำตอบคือC#7(หรือDb7) หากเป็นเช่น4 4 6 4 5 4นั้นการนับจะให้7 0 7 10 3 7หรือ0 3 7 10ซึ่งก็คือC#m7(หรือDbm7)

กรณีทดสอบ

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ตามลอการิทึมของความถี่

2หรือในSolfègeชื่อชอบทำใหม่ไมล์ ในการท้าทายนี้ใช้ชื่อตัวอักษร

3สิ่งนี้อาจเรียกได้ว่าเป็นคอร์ดที่หกที่สำคัญโดยมีทางเลือกที่แตกต่างกันของโน๊ตรูท ในการท้าทายนี้ให้เรียกชื่อนี้ด้วยชื่อที่รองลงมาที่เจ็ด


3
ท้าทายมาก!
Luis Mendo

1
ล่อลวงให้ใกล้เคียงกับคู่ปรับจากการท้าทายในอนาคตของฉัน: D (ฉันมีความท้าทายที่คล้ายกันมากในใจ แต่คุณเร็วขึ้นอย่างน่ารังเกียจ)
ข้อบกพร่อง

อนุญาตให้มีช่องว่างต่อท้ายในสตริงเอาต์พุตได้หรือไม่
Luis Mendo

@ LuisMendo แน่นอน; ไม่เป็นไร.
Dan Getz

1
@ อย่างเป็นทางการไม่คุณไม่จำเป็นต้องจัดการกับสถานการณ์อื่น ๆ คุณสามารถสันนิษฐานได้ว่ามันจะเป็นหนึ่งใน 4 ประเภทคอร์ดเหล่านั้น กล่าวอีกนัยหนึ่งรหัสของคุณสามารถทำสิ่งที่คุณต้องการ (รวมถึงข้อผิดพลาดหรือให้คำตอบที่ผิด) ถ้ามันได้รับคอร์ดที่แตกต่างกัน
Dan Getz

คำตอบ:


9

MATL , 115 114 ไบต์

[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

รูปแบบอินพุตคือ[N 3 2 0 1 0]โดยที่Nระบุถึงสตริงที่ไม่ได้ใช้

สตริงเอาท์พุทมักจะใช้ไม่ได้#b

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมดในสองส่วนเพื่อหลีกเลี่ยงการหมดเวลาคอมไพเลอร์ออนไลน์:

คำอธิบาย

[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 (179 ไบต์)

ไฟล์ (แสดงที่นี่เป็น 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

อินพุตได้รับผ่านทางบรรทัดคำสั่ง อินพุตที่ไม่ถูกต้องจะนำไปสู่การทำงานของโปรแกรมที่ไม่ถูกต้อง!

รหัสแอสเซมเบลอร์มีลักษณะดังนี้:

.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

กรณีทดสอบ:

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

ฉันเห็นผู้เล่นเปียโนสองคนเล่นด้วยกัน "สี่มือ" บนเปียโน

กรณีทดสอบนี้เป็นครั้งแรกที่ฉันอ่านเกี่ยวกับผู้เล่นกีต้าร์ที่ทำสิ่งนี้!

ถึงแม้จะมีการแตะมือขวาคุณก็ไม่สามารถเล่นสายนี้ได้!


อืมอาจเป็นปลาหมึกที่สามารถเล่นคอร์ดนั้นได้? ฉันคิดว่าเป็นหนึ่งในรายการที่ฉันพบโดยการค้นหาแบบสุ่มเพื่อให้มีกรณีทดสอบ "ยาก"
Dan Getz

3

ทับทิมขนาด 129 ไบต์

เป็นเวอร์ชันก่อนหน้า แต่ใช้ลูปเดียวที่มีตัวดำเนินการประกอบไปด้วยเพื่อเรียงลำดับระหว่างขั้นตอนการแยกวิเคราะห์และขั้นตอนเอาต์พุต ต้องมีการแก้ไขเล็กน้อยอื่น ๆ เพื่อให้ทำงาน

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

ทับทิม 136 ไบต์

ฟังก์ชัน Llamda ยอมรับอาร์เรย์จำนวน 6 ตัวเป็นอาร์กิวเมนต์และแสดงผลเป็น stdout สตริงที่ไม่ได้ใช้งานจะถูกแทนด้วยค่าที่ผิดพลาด (ค่าที่เป็นเท็จเท่านั้นในทับทิมคือnilและ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}}

คำอธิบาย

ผมใช้เป็นตัวแทนของ 12 โหมโรงขึ้นอยู่กับที่วงกลมของเศษ ซึ่งหมายความว่าในแต่ละสนามจะตามด้วยสนามที่ 7 semitones สูงกว่า (หรือ 5 semitones ลด) F C G D A E B F# C# G# D# A#ให้ลำดับ มีข้อดี 2 ข้อดังนี้ หนึ่งคือความคมชัดทั้งหมดปรากฏขึ้นพร้อมกัน อื่น ๆ คือโน้ตแบบเปิดของสตริงเบส 5 ตัวปรากฏขึ้นพร้อมกัน: GDAEB (กีต้าร์เกี่ยวข้อง แต่ซับซ้อนกว่าเล็กน้อยดูด้านล่าง)

ลูปแรกรัน 6 ครั้ง การแสดงออก6--~j%5(เท่า6-(j+1)%5) E=5 A=4 D=3 G=2 B=6 E=5ให้บันทึกค่าสำหรับสายเปิด: ในการนี้เราจะเพิ่มหมายเลขเฟร็ทคูณด้วย 7 (ดังที่เห็นด้านบนการเพิ่มเซมิโคลอนหนึ่งอันจะเลื่อนเราไปข้างหน้าตามลำดับที่ 7) จากนั้นเราก็นำโมดูโล 12 ทั้งหมดมาทำบิตแมปของโน้ตที่มีอยู่ ใช้4097<<note valueเพื่อให้อ็อกเทฟ 2 อันติดต่อกัน)

หลังจากแต่งบิตแมปเราก็พร้อมที่จะค้นหาคอร์ดและส่งออกมัน

เราสนใจบันทึกต่อไปนี้:

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 เราทดสอบเพื่อดูว่ามีการรูตและที่ห้าหรือไม่: บิต 0 และ 1 (นับจากจำนวนที่มีนัยสำคัญน้อยที่สุด: บิต 1 และ 2) เพื่อที่จะปฏิเสธคอร์ดที่หกเราต้องตรวจสอบว่า ไม่มีอยู่: บิต 3 (บิต 8) ดังนั้นเราจึงตรวจสอบr&&11==3และถ้าเป็นเช่นนั้นเราจะพิมพ์คอร์ด

เราไม่สนใจหลักที่สามและพึ่งพาทั้งหมด 9 บิต (เล็กน้อยสาม) และบิต 10 (เล็กน้อย 7) เพื่อหาประเภทคอร์ด การแสดงออกที่r>>9&3ใช้ในการเลือกประเภทคอร์ดที่ถูกต้องจากอาร์เรย์

ในตอนท้ายของวงเราเปลี่ยนบิตแมปทางขวาหนึ่งบิตเพื่อทดสอบรากคอร์ดที่เป็นไปได้ในลำดับที่: r/=2F C G D A E B F# C# G# D# A#

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 ไบต์

รักความท้าทายนี้และ PPCG SE! นี่คือสนามกอล์ฟครั้งแรกของฉัน - ยินดีต้อนรับคำแนะนำเนื่องจากฉันแน่ใจว่ามันจะดีขึ้นมาก (ล้มลง 2 ไบต์เนื่องจากฉันรวม f = ไว้ในการนับ)

ฟังก์ชั่นfใช้อาร์เรย์ของสตริงแทนตัวเลขและ 'X' f(['X','3','2','0','1','0'])เช่นE#m7ไลค์และส่งคืนคอร์ด (ธรรมชาติหรือคม) เช่น เพิ่มบรรทัดใหม่เพื่อความชัดเจน (ไม่รวมอยู่ในจำนวนไบต์)

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]

ตัวอย่างการใช้งาน:

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

ในการรันกรณีทดสอบ:

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

รุ่นที่ไม่ได้รับการอธิบายพร้อมคำอธิบาย:

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
ยินดีต้อนรับสู่เว็บไซต์! ฉันดีใจที่ได้ยินคุณสนุกกับมัน :) น่าเสียดายที่ฉันไม่รู้จัก JS เลยฉันไม่มีคำแนะนำใด ๆ แต่คุณอาจหาได้ที่นี่
DJMcMayhem
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.