มีกี่ semitones


21

แนวทาง

งาน

เมื่อได้รับโน้ตสองรายการให้ป้อนเป็นสตริงหรือรายการ / อาร์เรย์คำนวณจำนวนเซมิโคลอนแยกออกเป็นสองส่วน

คำอธิบายของ semitone:

semitone เป็นขั้นตอนเดียวขึ้นหรือลงบนคีย์บอร์ด ตัวอย่างคือ C ถึง C # ดังที่คุณเห็นด้านล่างโน้ต C อยู่ในโน้ตสีขาวและ C # คือโน้ตดำด้านบน Semitones เป็นการกระโดดจากโน้ตดำไปยังโน้ตสีขาวถัดไปขึ้นหรือลงยกเว้น:

  • B ถึง C
  • C ถึง B
  • E ถึง F
  • F ถึง E

แป้นพิมพ์

ตัวอย่าง

'A, C' -> 4

'G, G#' -> 2

'F#, B' -> 6

'Bb, Bb' -> 13


กฎระเบียบ

  • ระยะทางที่ใหญ่ที่สุดระหว่างสองโน้ตคือ 13 semitones
  • บันทึกที่ป้อนที่สองจะอยู่เหนือบันทึกที่ป้อนครั้งแรกเสมอ
  • คุณสามารถรับอินพุตเป็นสตริงหรืออาร์เรย์ / รายการ หากคุณใช้มันเป็นสตริงบันทึกจะคั่นด้วยเครื่องหมายจุลภาค (เช่นString -> 'A, F', Array -> ['A', 'F'])
  • คุณสามารถสันนิษฐานได้ว่าคุณจะได้รับโน้ตที่ถูกต้องสองครั้งเสมอ
  • Sharps จะแสดงเป็น#และแฟลตจะแสดงเป็นb
  • รหัสของคุณต้องรองรับการเพิ่มประสิทธิภาพเทียบเท่า (เช่นต้องสนับสนุนทั้ง F # และ Gb)
  • รหัสของคุณไม่จำเป็นต้องรองรับบันทึกย่อที่ตั้งชื่อด้วย แต่สามารถตั้งชื่อได้โดยไม่มีความคมหรือแบน (เช่นคุณไม่จำเป็นต้องรองรับ E # หรือ Cb) คะแนนโบนัสหากรหัสของคุณรองรับ
  • รหัสของคุณไม่จำเป็นต้องรองรับการแบ่งช่วงแบบสองเท่าหรือสองเท่า
  • คุณสามารถสันนิษฐานได้ว่าถ้าคุณได้ทั้งโน้ตตัวเดียวกันหรือพิทช์เดียวกัน (เช่น 'Gb, Gb' หรือ 'A #, Bb') อันดับที่สองจะไม่เท่ากับหนึ่งคู่เหนือระดับแรก
  • นี่คือรหัสกอล์ฟดังนั้นคำตอบที่มีจำนวนไบต์น้อยที่สุดจะเป็นผู้ชนะ

ฉันได้รับ 2 ราคา G -> G#เพราะพวกเขาทั้งสองรวมอยู่ด้วย
HyperNeutrino

@HyperNeutrino อ๋อขอโทษ ความผิดพลาดในนามของฉัน
Amorris

1
เราต้องตอบสนองความต้องการบันทึกเช่น CbหรือE#? สิ่งที่เกี่ยวกับ double sharps / flats?
Sok

1
@ ไม่ต้องใช้รหัสของคุณไม่จำเป็นต้องรองรับบันทึกย่อเช่น E # หรือ Cb และไม่จำเป็นต้องรองรับการใช้ชาร์ปสองเท่าหรือแฟลต ฉันได้อัปเดตคำถามเพื่อให้ชัดเจนยิ่งขึ้น ขออภัยในความสับสน
Amorris

2
เพียงเพื่อให้ชัดเจนเมื่อพูดจากระยะทางทฤษฎีความรู้สึกทางดนตรีในเซมิโคลอนไม่รวมถึงบันทึกย่อที่คุณเริ่มต้น ในวิชาคณิตศาสตร์มันจะถูกแทนด้วย(X, Y]C ถึง C # คือ 1 semitone และ C to C คือ 12 semitones
Dom

คำตอบ:


7

Python 2 , 66 ไบต์

r=1
for s in input():r=cmp(s[1:]+s,s)-ord(s[0])*5/3-r
print-r%12+2

ลองออนไลน์!


Python 2 , 68 ไบต์

lambda s,t:13-(q(s)-q(t))%12
q=lambda s:ord(s[0])*5/3+cmp(s,s[1:]+s)

ลองออนไลน์!


คะแนนพิเศษสำหรับความสามารถในการจัดการบันทึกย่อเช่น B # และ Fb ในขณะที่ยังคงอยู่ที่สั้นที่สุด
Amorris

7

JavaScript (ES6), 78 ไบต์

บันทึกแล้ว 1 ไบต์ขอบคุณ @Neil

(a)(b)จดบันทึกในไวยากรณ์ currying

a=>b=>((g=n=>'0x'+'_46280ab_91735'[parseInt(n+3,36)*2%37%14])(b)-g(a)+23)%12+2

กรณีทดสอบ

ฟังก์ชันแฮช

วัตถุประสงค์ของฟังก์ชั่นแฮชคือการแปลงโน้ตเป็นตัวชี้ในตารางการค้นหาที่มีเซมิโคลอนออฟเซ็ต (C = 0, C # = 1, ... , B = 11) เก็บไว้ในเลขฐานสิบหก

ครั้งแรกที่เราผนวก'3'ที่จะต้องทราบและแยกสตริงผลในฐาน-36 นำไปสู่การเป็นจำนวนเต็มN เพราะ'#'เป็นอักขระที่ไม่ถูกต้องดังนั้นจึงถูกละเว้นพร้อมกับอักขระที่ตามมา

จากนั้นเราคำนวณ:

H(N) = ((N * 2) MOD 37) MOD 14

ด้านล่างนี้เป็นบทสรุปของผลลัพธ์

 note | +'3' | parsed as | base 36->10 |   *2  | %37 | %14 | offset
------+------+-----------+-------------+-------+-----+-----+--------
  C   |  C3  |    c3     |         435 |   870 |  19 |   5 |  0x0
  C#  |  C#3 |    c      |          12 |    24 |  24 |  10 |  0x1
  Db  |  Db3 |    db3    |       17247 | 34494 |  10 |  10 |  0x1
  D   |  D3  |    d3     |         471 |   942 |  17 |   3 |  0x2
  D#  |  D#3 |    d      |          13 |    26 |  26 |  12 |  0x3
  Eb  |  Eb3 |    eb3    |       18543 | 37086 |  12 |  12 |  0x3
  E   |  E3  |    e3     |         507 |  1014 |  15 |   1 |  0x4
  F   |  F3  |    f3     |         543 |  1086 |  13 |  13 |  0x5
  F#  |  F#3 |    f      |          15 |    30 |  30 |   2 |  0x6
  Gb  |  Gb3 |    gb3    |       21135 | 42270 |  16 |   2 |  0x6
  G   |  G3  |    g3     |         579 |  1158 |  11 |  11 |  0x7
  G#  |  G#3 |    g      |          16 |    32 |  32 |   4 |  0x8
  Ab  |  Ab3 |    ab3    |       13359 | 26718 |   4 |   4 |  0x8
  A   |  A3  |    a3     |         363 |   726 |  23 |   9 |  0x9
  A#  |  A#3 |    a      |          10 |    20 |  20 |   6 |  0xa
  Bb  |  Bb3 |    bb3    |       14655 | 29310 |   6 |   6 |  0xa
  B   |  B3  |    b3     |         399 |   798 |  21 |   7 |  0xb

เกี่ยวกับแฟลตและเซียน

ด้านล่างนี้เป็นหลักฐานที่กัญชานี้เพื่อให้แน่ใจว่าฟังก์ชั่นบันทึกตามด้วย'#'ให้ผลเดียวกันกว่าทราบต่อไปตามด้วย'B' ในย่อหน้านี้เราใช้คำนำหน้า@สำหรับปริมาณ -36 ฐาน

ตัวอย่างเช่นDbจะถูกแปลงเป็น@ db3และC #จะถูกแปลงเป็น@c (ดูย่อหน้าก่อนหน้า) เราต้องการพิสูจน์ว่า:

H(@db3) = H(@c)

หรือในกรณีทั่วไปโดยมีY = X + 1 :

H(@Yb3) = H(@X)

@ b3คือ399ในทศนิยม ดังนั้น:

H(@Yb3) =
@Yb3 * 2 % 37 % 14 =
(@Y * 36 * 36 + 399) * 2 % 37 % 14 =
((@X + 1) * 36 * 36 + 399) * 2 % 37 % 14 =
(@X * 1296 + 1695) * 2 % 37 % 14

1296สอดคล้องกับ1โมดูโล37ดังนั้นสิ่งนี้สามารถทำให้ง่ายขึ้นเป็น:

(@X + 1695) * 2 % 37 % 14 =
((@X * 2 % 37 % 14) + (1695 * 2 % 37 % 14)) % 37 % 14 =
((@X * 2 % 37) + 23) % 37 % 14 =
((@X * 2 % 37) + 37 - 14) % 37 % 14 =
@X * 2 % 37 % 14 =
H(@X)

กรณีพิเศษคือการเปลี่ยนจากG #เป็นAbตามที่เราคาดหวังHbเพื่อให้สอดคล้องกับสูตรข้างต้น อย่างไรก็ตามอันนี้ก็ใช้งานได้เพราะ:

@ab3 * 2 % 37 % 14 = @hb3 * 2 % 37 % 14 = 4

@ Neil ขอบคุณ! การเพิ่มประสิทธิภาพของคุณบันทึกได้มากกว่าไบต์
Arnauld

อืมฉันพบสิ่งที่ตรงกันข้ามกับโซลูชันแบทช์ของฉัน ...
Neil

@Neil เพราะสัญลักษณ์ของ modulo ใน Batch เป็นสัญลักษณ์ของตัวหารฉันเดาว่า?
Arnauld

ไม่มันเป็นสัญลักษณ์ของการจ่ายเงินปันผลเช่นเดียวกับใน JS แต่มันกลับกลายเป็นนักกอล์ฟที่มีความถูกต้องเล็กน้อยในการแก้ไขสัญลักษณ์ของผลที่กลับด้านเนื่องจากการเล่นกอล์ฟก่อนหน้านี้
Neil

4

Perl, 39 32 ไบต์

รวม+1สำหรับp

ให้บันทึกย่อเริ่มต้นและสิ้นสุดเป็นสองบรรทัดใน STDIN

(echo "A"; echo "C") | perl -pe '$\=(/#/-/b/-$\+5/3*ord)%12+$.}{'; echo

เพียงแค่รหัส:

$\=(/#/-/b/-$\+5/3*ord)%12+$.}{


@wastl ดังนั้นฉันได้รับการบอก ฉันต้องการที่จะรู้ว่าโพสต์เมตา แต่เพื่อให้ฉันสามารถไปที่นั่นและไม่เห็นด้วย :-)
Ton Hospel

ความคิดเห็นของฉันคือลิงค์ คลิกที่มันฟรี
wastl

ดูเหมือนว่างานนี้จะคล้ายกับของฉันมาก แต่สั้นมากสำหรับ Perl, +1
Level River St

@ LevelRiverSt ดีนี่คือ Ton Hospel
msh210

4

Japt , 27 ไบต์

®¬x!b"C#D EF G A"ÃrnJ uC +2

ทดสอบออนไลน์! รับอินพุตเป็นอาร์เรย์ของสองสตริง

ใช้งานได้กับจำนวนชาร์ปหรือแฟลตใด ๆ ในโน้ตฐาน!

คำอธิบาย

®¬x!b"C#D EF G A"ÃrnJ uC +2   Let's call the two semitones X and Y.
®                Ã            Map X and Y by
 ¬                              splitting each into characters,
  x                             then taking the sum of
   !b"C#D EF G A"               the 0-based index in this string of each char.
                                C -> 0, D -> 2, E -> 4, F -> 5, G -> 7, A -> 9.
                                # -> 1, adding 1 for each sharp in the note.
                                b -> -1, subtracting 1 for each flat in the note.
                                B also -> -1, which happens to be equivalent to 11 mod 12.
                                The sum will be -2 for Bb, 2 for D, 6 for F#, etc.
                              Now we have a list of the positions of the X and Y.
                  rnJ         Reduce this list with reversed subtraction, starting at -1.
                              This gets the difference Y - (X - (-1)), or (Y - X) - 1.
                      uC      Find the result modulo 12. This is 0 if the notes are 1
                              semitone apart, 11 if they're a full octave apart.
                         +2   Add 2 to the result.

2

Perl 5 + -p, 66 ไบต์

s/,/)+0x/;y/B-G/013568/;s/#/+1/g;s/b/-1/g;$_=eval"(-(0x$_-1)%12+2"

ลองออนไลน์!

ใช้ค่าที่คั่นด้วยเครื่องหมายจุลภาค ใช้งานได้กับ Cb, B #, E #, Fb และหลาย # / b

คำอธิบาย:

# input example: 'G,G#'
s/,/)+0x/; # replace separator with )+0x (0x for hex) => 'G)+0xG#'
y/B-G/013568/; # replace keys with numbers (A stays hex 10) => '8)+0x8#'
s/#/+1/g; s/b/-1/g; # replace accidentals with +1/-1 => '8)+0x8+1'
$_ = eval # evaluate => 2
    "(-(0x$_-1)%12+2" # add some math => '(-(0x8)+0x8+1-1)%12+2'

คำอธิบายสำหรับ eval:

(
    - (0x8) # subtract the first key => -8
    + 0x8 + 1 # add the second key => 1
    - 1 # subtract 1 => 0
) % 12 # mod 12 => 0
+ 2 # add 2 => 2
# I can't use % 12 + 1 because 12 (octave) % 12 + 1 = 1, which is not allowed

2

Ruby , 56 ไบต์

->a{a.map!{|s|s.ord*5/3-s[-1].ord/32}
13-(a[0]-a[1])%12}

ลองออนไลน์!

ตัวอักษรจะถูกแยกวิเคราะห์ตามรหัส ASCII ของพวกเขาครั้ง5/3ดังต่อไปนี้ (ซึ่งจะให้จำนวน semitones ที่ต้องการบวกออฟเซ็ต 108)

A    B    C    D    E    F    G
108  110  111  113  115  116  118

ตัวอักษรตัวสุดท้าย ( #, bหรือตัวอักษรอีกครั้ง) จะแยกเป็นรหัส ASCII ของหารด้วย 32 ดังต่อไปนี้

# letter (natural) b 
1  { --- 2 --- }   3

นี่จะถูกลบออกจากรหัสตัวอักษร

จากนั้นผลลัพธ์สุดท้ายจะถูกส่งกลับเป็น 13-(difference in semitones)%12


2

Stax , 25 24 ไบต์

╝─°U┤ƒXz☺=≡eA╕δ┴╬\¿☺zt┼§

เรียกใช้และตรวจแก้จุดบกพร่องออนไลน์

การแสดง ascii ที่สอดคล้องกันของโปรแกรมเดียวกันคือสิ่งนี้

{h9%H_H32/-c4>-c9>-mrE-v12%^^

ได้อย่างมีประสิทธิภาพมันจะคำนวณดัชนีแป้นพิมพ์ของแต่ละโน้ตโดยใช้สูตรจากนั้นคำนวณช่วงเวลาที่เกิดขึ้น

  1. เริ่มจากโน้ตฐาน A = 2, B = 4, ... G = 14
  2. คำนวณออฟเซ็ตโดยไม่ตั้งใจโดย2 - code / 32ที่codeเป็นรหัส ascii ของอักขระตัวสุดท้าย
  3. เพิ่มเข้าด้วยกัน
  4. หากผลลัพธ์คือ> 4 ให้ลบ 1 เพื่อลบ B #
  5. หากผลลัพธ์คือ> 7 ให้ลบ 1 เพื่อลบ E #
  6. ลบดัชนีโน้ตที่ได้รับสองรายการแบบแยกส่วนและเพิ่ม 1

1
["F#","B"]ควรเป็น 6
Weijun Zhou

1
ขอบคุณ ฉันเปลี่ยนครึ่งหนึ่งของการคำนวณโดยไม่ต้องปรับอีก มันคงที่
เรียกซ้ำ

1

แบตช์136 135 ไบต์

@set/ac=0,d=2,e=4,f=5,g=7,a=9,r=24
@call:c %2
:c
@set s=%1
@set s=%s:b=-1%
@set/ar=%s:#=+1%-r
@if not "%2"=="" cmd/cset/a13-r%%12

คำอธิบาย: การแทนในcsubroutine แทน#ในนามบันทึกด้วย+1และมีb -1เช่นนี้เป็นกรณีตายจะกลายเป็นBb -1-1ดังนั้นตัวแปรสำหรับC... A(และตัวพิมพ์เล็กและตัวพิมพ์ใหญ่และเล็ก) จึงถูกเลือกให้เป็นจำนวนเซมิโคลอนที่B=-1เหมาะสม สตริงผลลัพธ์จะถูกประเมินและเคล็ดลับของ @ xnor ในการลบผลลัพธ์จากค่าจะให้ผลที่ต้องการในการลบค่าบันทึกจากกันและกัน แก้ไข: ในที่สุดฉันก็ใช้เคล็ดลับของ @ Arnauld ในการลบโมดูโลออกจาก 13 เพื่อให้ได้คำตอบที่ต้องการโดยประหยัด 1 ไบต์


1

Python 3 , 95 ไบต์

lambda a,b:(g(b)+~g(a))%12+2
g=lambda q:[0,2,3,5,7,8,10][ord(q[0])-65]+" #".find(q.ljust(2)[1])

ลองออนไลน์!

-14 ไบต์ขอบคุณ user71546


-8 ไบต์ด้วยการord(q[0])-65แทนที่"ABCDEFG".find(q[0]);)
Shieru Asakoto

โอ้มีอีก -6 ไบต์(g(b)+~g(a))%12+2แทนที่ด้วย1+((g(b)-g(a))%12or 12)
Shieru Asakoto

@ user71546 โอ้ยอดเยี่ยมขอบคุณ!
HyperNeutrino

1

เยลลี่ขนาด 28 ไบต์

O64_ṠH$2¦ḅ-AḤ’d5ḅ4µ€IḞṃ12FṪ‘

ลิงก์ monadic ยอมรับรายการอักขระสองรายการและส่งคืนจำนวนเต็ม

ลองออนไลน์! หรือดูกรณีเป็นไปได้ทั้งหมด

อย่างไร?

ดำเนินการทางคณิตศาสตร์ที่แปลกประหลาดบางอย่างบนลำดับของอักขระอินพุตเพื่อแมปบันทึกลงบนจำนวนเต็มศูนย์ถึงสิบสองแล้วทำการบีบอัดฐานเป็นพร็อกซีสำหรับ modulo สิบสองที่ศูนย์จะถูกแทนที่ด้วย 12 แล้วเพิ่มหนึ่ง

O64_ṠH$2¦ḅ-AḤ’d5ḅ4µ€IḞṃ12FṪ‘ - Main link, list of lists    e.g. [['F','#'],['B']]  ...or [['A','b'],['G','#']]
                  µ€         - for €ach note list          e.g.  ['F','#'] ['B']          ['A','b'] ['G','#']
O                            - { cast to ordinal (vectorises)    [70,35]   [66]           [65,98]   [71,35]
 64                          -   literal 64
   _                         -   subtract (vectorises)           [-6,29]   [-2]           [-1,-34]  [-7,29]
        ¦                    -   sparse application...
       2                     -   ...to indices: [2] (just index 2)
      $                      -   ...do: last two links as a monad:
    Ṡ                        -          sign                     [-6,1]    [-2]           [-1,-1]   [-7,1]
     H                       -          halve                    [-6,-0.5] [-2]           [-1,-0.5] [-7,0.5]
         ḅ-                  -   convert from base -1            5.5       -2             0.5       7.5
           A                 -   absolute value                  5.5       2              0.5       7.5
            Ḥ                -   double                          11.0      4              1.0       15.0
             ’               -   decrement                       10.0      3              0.0       14.0
              d5             -   divmod by 5                     [2.0,2.0] [0,3]          [0.0,0.0] [2.0,4.0]
                ḅ4           -   convert from base 4             10.0      3              0.0       12.0
                             - } -->                             [10.0,3]                 [0.0,12.0]
                    I        - incremental differences           [-7.0]                   [12.0]
                     Ḟ       - floor (vectorises)                [-7]                     [12]
                      ṃ12    - base decompress using [1-12]      [[5]]                    [[1,12]]
                         F   - flatten                           [5]                      [1,12]
                          Ṫ  - tail                              5                        12
                           ‘ - increment                         6                        13

นอกจากนี้ที่ 28 ไบต์ ...

A (ไม่ตรง) พอร์ตของคำตอบ Python 2ของxnor ...

O×5:3z60_Ṡ¥2¦60U1¦Fḅ-‘N%12+2

ลองใช้กรณีที่เป็นไปได้ทั้งหมด


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.