Có bao nhiêu nửa cung


21

Hướng dẫn

Bài tập

Đưa ra hai ghi chú, được nhập dưới dạng chuỗi hoặc danh sách / mảng, tính toán chúng cách nhau bao nhiêu nửa cung (bao gồm các ghi chú), xuất ra dưới dạng số.

Giải thích về một nửa cung:

Một nửa cung là một bước lên hoặc xuống bàn phím. Một ví dụ là C đến C #. Như bạn có thể thấy bên dưới ghi chú C nằm trên một ghi chú màu trắng và C # là ghi chú màu đen chỉ một ở trên nó. Semitones là những bước nhảy từ nốt đen sang nốt trắng tiếp theo, lên hoặc xuống, ngoại trừ:

  • B đến C
  • C đến B
  • E đến F
  • Từ F đến E

bàn phím

Ví dụ

'A, C' -> 4

'G, G#' -> 2

'F#, B' -> 6

'Bb, Bb' -> 13


Quy tắc

  • Khoảng cách lớn nhất giữa hai nốt nhạc là 13 nửa cung.
  • Ghi chú đầu vào thứ hai sẽ luôn ở trên ghi chú đầu vào đầu tiên.
  • Bạn có thể lấy đầu vào là một chuỗi hoặc một mảng / danh sách. Nếu bạn mang nó như là một chuỗi, các ghi chú sẽ bằng dấu phẩy (ví dụ String -> 'A, F', Array -> ['A', 'F']).
  • Bạn có thể cho rằng bạn sẽ luôn được cung cấp hai ghi chú hợp lệ.
  • Sharps sẽ được ký hiệu là #và căn hộ sẽ được ký hiệu làb
  • Mã của bạn phải hỗ trợ tương đương nâng cao (ví dụ: Nó phải hỗ trợ cả F # và Gb)
  • Mã của bạn không cần hỗ trợ các ghi chú được đặt tên, nhưng có thể được đặt tên mà không có sắc nét hoặc bằng phẳng (tức là Bạn không cần hỗ trợ E # hoặc Cb). Điểm thưởng nếu mã của bạn không hỗ trợ nó mặc dù.
  • Mã của bạn không cần phải hỗ trợ gấp đôi hoặc căn hộ đôi.
  • Bạn có thể giả sử rằng nếu bạn nhận được cả hai nốt giống nhau hoặc cùng một nốt (ví dụ: 'Gb, Gb' hoặc 'A #, Bb'), thì nốt thứ hai sẽ không chính xác hơn một quãng tám so với nốt đầu tiên.
  • Đây là mã golf nên câu trả lời có số byte ít nhất sẽ thắng.

Tôi nhận được 2 G -> G#vì cả hai đều được bao gồm.
HyperNeutrino

@HyperNeutrino Yep xin lỗi. Sai lầm thay cho tôi.
Amorris

1
Chúng ta phải phục vụ cho ghi chú như Cbhay E#? Điều gì về sắc nét gấp đôi / căn hộ?
Sok

1
@Sok Không, mã của bạn không cần hỗ trợ các ghi chú như E # hoặc Cb và không cần hỗ trợ gấp đôi hoặc căn hộ. Tôi đã cập nhật câu hỏi để làm cho nó rõ ràng hơn. Xin lỗi về bất kỳ sự nhầm lẫn.
Amorris

2
Nói rõ hơn, khi nói từ khoảng cách lý thuyết âm nhạc trong semitones không bao gồm ghi chú bạn bắt đầu. Trong toán học, wold được biểu diễn vì (X, Y]vậy C đến C # là 1 nửa cung và C đến C là 12 nửa cung.
Dom

Câu trả lời:



7

JavaScript (ES6), 78 byte

Đã lưu 1 byte nhờ @Neil

Có các ghi chú trong cú pháp currying (a)(b).

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

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

Hàm băm

Mục đích của hàm băm là chuyển đổi một ghi chú thành một con trỏ trong bảng tra cứu có chứa các phần tử nửa cung (C = 0, C # = 1, ..., B = 11), được lưu trữ dưới dạng thập lục phân.

Đầu tiên chúng ta append một '3' đến ghi chú và phân tích chuỗi kết quả trong cơ sở-36, dẫn đến một số nguyên N . Bởi vì '#' là một ký tự không hợp lệ, nó chỉ bị bỏ qua, cùng với bất kỳ ký tự nào theo sau nó.

Sau đó, chúng tôi tính toán:

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

Dưới đây là một bản tóm tắt các kết quả.

 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

Về căn hộ và vật sắc nhọn

Dưới đây là bằng chứng cho thấy hàm băm này đảm bảo rằng một ghi chú được theo sau bởi '#' cho kết quả tương tự so với ghi chú tiếp theo theo sau là 'b' . Trong đoạn này, chúng tôi sử dụng tiền tố @ cho số lượng cơ sở 36.

Chẳng hạn, Db sẽ được chuyển đổi thành @ db3C # sẽ được chuyển đổi thành @c (xem đoạn trước). Chúng tôi muốn chứng minh rằng:

H(@db3) = H(@c)

Hoặc trong trường hợp chung, với Y = X + 1 :

H(@Yb3) = H(@X)

@ b3399 trong số thập phân. Vì thế:

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 phù hợp với 1 modulo 37 , vì vậy điều này có thể được đơn giản hóa như sau:

(@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)

Một trường hợp đặc biệt là sự chuyển đổi từ G # sang Ab , như chúng ta mong đợi Hb để tuân thủ các công thức trên. Tuy nhiên, cái này cũng hoạt động vì:

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

@Neil Cảm ơn! Tối ưu hóa của bạn tiết kiệm nhiều byte hơn của tôi.
Arnauld

Huh, tôi thực sự đã tìm thấy điều ngược lại với giải pháp Batch của mình ...
Neil

@Neil Bởi vì dấu hiệu của modulo trong Batch là dấu hiệu của ước số, tôi đoán vậy?
Arnauld

Không, đó là dấu hiệu của cổ tức, như trong JS, nhưng hóa ra đó là một tay golf hơi sửa sai cho dấu hiệu của kết quả đã bị đảo ngược do một golf trước đó.
Neil

4

Perl, 39 32 byte

Bao gồm +1chop

Đưa ra ghi chú bắt đầu và kết thúc dưới dạng hai dòng trên STDIN

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

Chỉ cần mã:

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


@wastl Vậy là tôi đã nói rồi. Tôi muốn biết meta bài nào mặc dù vậy tôi có thể đến đó và không đồng ý :-)
TonMedel

Nhận xét của tôi là một liên kết. Hãy nhấp vào nó.
lãng phí

Có vẻ như điều này hoạt động rất giống với tôi - nhưng cực kỳ ngắn đối với Perl, +1
Level River St

@LevelRiverSt tốt, đây TonMedel.
msh210

4

Japt , 27 byte

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

Kiểm tra nó trực tuyến! Lấy đầu vào là một mảng của hai chuỗi.

Cũng hoạt động cho bất kỳ số lượng vật sắc nhọn hoặc căn hộ trên bất kỳ lưu ý cơ bản!

Giải trình

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

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

Hãy thử trực tuyến!

Có các giá trị được phân tách bằng dấu phẩy. Cũng hoạt động cho Cb, B #, E #, Fb và nhiều # / b.

Giải trình:

# 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'

Giải thích cho 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 byte

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

Hãy thử trực tuyến!

Các chữ cái được phân tích cú pháp theo thời gian mã ASCII của chúng 5/3như sau (điều này mang lại số lượng nửa cung cần thiết cộng với độ lệch là 108)

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

Ký tự cuối cùng ( #, bhoặc lá thư một lần nữa) được phân tách như mã ASCII của nó chia cho 32 như sau

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

Điều này được trừ từ mã thư.

Sau đó, kết quả cuối cùng được trả về là 13-(difference in semitones)%12


2

Stax , 25 24 byte

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

Chạy và gỡ lỗi trực tuyến

Đại diện ascii tương ứng của cùng một chương trình là đây.

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

Thực tế, nó tính toán chỉ số bàn phím của từng ghi chú bằng một công thức, sau đó tính khoảng thời gian kết quả.

  1. Bắt đầu từ ghi chú cơ bản, A = 2, B = 4, ... G = 14
  2. Tính toán bù ngẫu nhiên 2 - code / 32trong đó codemã ascii của ký tự cuối cùng.
  3. Thêm chúng lại với nhau.
  4. Nếu kết quả là> 4, trừ 1 để loại bỏ B #.
  5. Nếu kết quả là> 7, hãy trừ 1 để xóa E #.
  6. Modular trừ hai chỉ số ghi chú kết quả, và thêm 1.

1
["F#","B"]nên là 6.
Weijun Zhou

1
Cảm ơn. Tôi đã thay đổi một nửa tính toán mà không điều chỉnh nửa còn lại. Nó đã được sửa.
đệ quy

1

Mẻ, 136 135 byte

@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

Giải thích: Sự thay thế trong cchương trình con thay thế #trong tên ghi chú bằng +1bvới -1. Vì đây là trường hợp không nhạy cảm, Bbtrở thành -1-1. Do đó, các biến cho C... A(cũng không phân biệt chữ hoa chữ thường) được chọn là số lượng nửa cung thích hợp B=-1. Chuỗi kết quả sau đó được đánh giá và thủ thuật trừ kết quả của @ xnor trừ giá trị mang lại hiệu quả mong muốn là trừ các giá trị ghi chú lẫn nhau. Chỉnh sửa: Cuối cùng tôi sử dụng thủ thuật của @ Arnauld để trừ modulo từ 13 để đạt được câu trả lời mong muốn, tiết kiệm 1 byte.



1

Thạch , 28 byte

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

Một liên kết đơn âm chấp nhận danh sách hai danh sách các ký tự và trả về một số nguyên.

Hãy thử trực tuyến! hoặc xem tất cả các trường hợp có thể .

Làm sao?

Thực hiện một số số học kỳ quái trên các số thứ tự của các ký tự đầu vào để ánh xạ các ghi chú lên các số nguyên từ 0 đến 12 và sau đó thực hiện giải nén cơ sở như một proxy cho modulo bằng mười hai trong đó số 0 được thay thế bằng 12 rồi thêm một.

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

Cũng ở mức 28 byte ...

Một cổng (không trực tiếp) của câu trả lời Python 2 của xnor ...

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

Hãy thử tất cả các trường hợp có thể


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.