자바 스크립트 (ES6), 78 바이트
@Neil 덕분에 1 바이트 절약
카레 구문에서 메모를합니다 (a)(b)
.
a=>b=>((g=n=>'0x'+'_46280ab_91735'[parseInt(n+3,36)*2%37%14])(b)-g(a)+23)%12+2
테스트 사례
let f =
a=>b=>((g=n=>'0x'+'_46280ab_91735'[parseInt(n+3,36)*2%37%14])(b)-g(a)+23)%12+2
console.log(f('A')('C')) // 4
console.log(f('G')('G#')) // 2
console.log(f('F#')('B')) // 6
console.log(f('Bb')('Bb')) // 13
해시 기능
해시 함수의 목적은 16 진수로 저장된 반음 오프셋 (C = 0, C # = 1, ..., B = 11)을 포함하는 조회 테이블에서 메모를 포인터로 변환하는 것입니다.
먼저 노트에 '3' 을 추가하고 base-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 은 10 진수 로 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의 우리 예상대로, 헤모글로빈을 상기 식을 준수하기 위해. 그러나 이것은 또한 다음과 같은 이유로 작동합니다.
@ab3 * 2 % 37 % 14 = @hb3 * 2 % 37 % 14 = 4
G -> G#
둘 다 포함되어 있기 때문에 .