[Question]
  [
# Guidelines
### Task
Given two notes, inputted as strings or lists/arrays, calculate how many semitones apart they are (inclusive of the notes themselves), outputting as a number.
**Explanation of a semitone:**
A semitone is one step up or down the keyboard. An example is C to C#. As you can see below the note C is on a white note and C# is the black note just one above it. Semitones are the leaps from a black note to the next white note, up or down, except for:
* B to C
* C to B
* E to F
* F to E
## [keyboard](https://i.stack.imgur.com/j125w.jpg)
### Examples
`'A, C' -> 4`
`'G, G#' -> 2`
`'F#, B' -> 6`
`'Bb, Bb' -> 13`
---
### Rules
* The largest distance between two notes is 13 semitones.
* The second inputted note will always be above the first inputted note.
* You can take input as either a string, or an array/list. If you take it as a string, the notes will be comma-separated (e.g. `String -> 'A, F'`, `Array -> ['A', 'F']`).
* You can assume that you will always be given two valid notes.
* Sharps will be denoted as `#` and flats will be denoted as `b`
* Your code must support enharmonic equivalents (e.g. It must support both F# and Gb)
* Your code does not need to support notes that are named with, but can be named without a sharp or flat (i.e. You do not need to support E#, or Cb). Bonus points if your code does support it though.
* Your code does not need to support double sharps or double flats.
* You can assume that if you get the both the same notes, or same pitch (e.g. 'Gb, Gb' or 'A#, Bb'), the second not will be exactly one octave above the first.
* This is code golf so the answer with the least amount of bytes wins.
  
[Answer]
# [Python 2](https://docs.python.org/2/), 66 bytes
```
r=1
for s in input():r=cmp(s[1:]+s,s)-ord(s[0])*5/3-r
print-r%12+2
```
[Try it online!](https://tio.run/##K6gsycjPM/qfWpGarKSk9L/I1pArLb9IoVghMw@ICkpLNDStimyTcws0iqMNrWK1i3WKNXXzi1KAXINYTS1TfWPdIq6Cosy8Et0iVUMjbaP/QGO0TP6rO6rrqDurc6m7A2l3ZSDDTRnIcgIynJJAjCR1AA "Python 2 – Try It Online")
---
**[Python 2](https://docs.python.org/2/), 68 bytes**
```
lambda s,t:13-(q(s)-q(t))%12
q=lambda s:ord(s[0])*5/3+cmp(s,s[1:]+s)
```
[Try it online!](https://tio.run/##Vc9LDoIwEIDhfU8xgRhaKVEgbkhY8D4EsgCRSCLl0W48PdIxRtn8mXwzm5le6jEKb@3C6/qsh6atQXIVuL5DZyqZM1PF2MH1yBx@18G4tFSW54odLyffvg0TlVyWblDZkq1iVHcJIZRW1FgcrAhj6sYIsU6CQU1RUwxChpDp5BjUArXAmFZFyLT0QtGOGpHBwUgMxn5UaCrMneWmxnhncYPWaPwoId24gHChF4CvBARQvH8BvN3O@LbgHd0G4bH1DQ "Python 2 – Try It Online")
[Answer]
# JavaScript (ES6), 78 bytes
*Saved 1 byte thanks to @Neil*
Takes the notes in currying syntax `(a)(b)`.
```
a=>b=>((g=n=>'0x'+'_46280ab_91735'[parseInt(n+3,36)*2%37%14])(b)-g(a)+23)%12+2
```
### Test cases
```
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
```
### Hash function
The purpose of the hash function is to convert a note into a pointer in a lookup table containing the semitone offsets (C = 0, C# = 1, ..., B = 11), stored in hexadecimal.
We first append a **'3'** to the note and parse the resulting string in base-36, leading to an integer **N**. Because **'#'** is an invalid character, it is simply ignored, along with any character following it.
Then we compute:
```
H(N) = ((N * 2) MOD 37) MOD 14
```
Below is a summary of the results.
```
 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
```
### About flats and sharps
Below is the proof that this hash function ensures that a note followed by a **'#'** gives the same result than the next note followed by a **'b'**. In this paragraph, we use the prefix **@** for base-36 quantities.
For instance, **Db** will be converted to **@db3** and **C#** will be converted to **@c** (see the previous paragraph). We want to prove that: 
```
H(@db3) = H(@c)
```
Or in the general case, with **Y = X + 1**:
```
H(@Yb3) = H(@X)
```
*@b3* is *399* in decimal. Therefore:
```
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* is congruent to *1* modulo *37*, so this can be simplified as:
```
(@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)
```
A special case is the transition from **G#** to **Ab**, as we'd expect **Hb** in order to comply with the above formulae. However, this one also works because:
```
@ab3 * 2 % 37 % 14 = @hb3 * 2 % 37 % 14 = 4
```
[Answer]
# Perl, ~~39~~ 32 bytes
Includes `+1` for `p`
Give the start and end notes as two lines on STDIN
```
(echo "A"; echo "C") | perl -pe '$\=(/#/-/b/-$\+5/3*ord)%12+$.}{'; echo
```
Just the code:
```
$\=(/#/-/b/-$\+5/3*ord)%12+$.}{
```
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 27 bytes
```
®¬x!b"C#D EF G A"ÃrnJ uC +2
```
[Test it online!](https://ethproductions.github.io/japt/?v=1.4.5&code=rqx4IWIiQyNEIEVGIEcgQSLDcm5KIHVDICsy&input=WydGIycsICdCJ10=) Takes input as an array of two strings.
Also works for any amount of sharps or flats on any base note!
### Explanation
```
®¬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.
```
[Answer]
# [Perl 5](https://www.perl.org/) + `-p`, 66 bytes
```
s/,/)+0x/;y/B-G/013568/;s/#/+1/g;s/b/-1/g;$_=eval"(-(0x$_-1)%12+2"
```
[Try it online!](https://tio.run/##K0gtyjH9/79YX0dfU9ugQt@6Ut9J113fwNDY1MxC37pYX1lf21A/HchI0tcFMVTibVPLEnOUNHQ1DCpU4nUNNVUNjbSNlP7/d9Rx5nLXcVfmclPWceJyStJxSvqXX1CSmZ9X/F@3IAcA "Perl 5 - Try It Online")
Takes comma-separated values.
Does also work for Cb, B#, E#, Fb and multiple #/b.
Explanation:
```
# 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'
```
Explanation for 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
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), 56 bytes
```
->a{a.map!{|s|s.ord*5/3-s[-1].ord/32}
13-(a[0]-a[1])%12}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y6xOlEvN7FAsbqmuKZYL78oRctU31i3OFrXMBbE0zc2qrU2NNbVSIw2iNVNjDaM1VQ1NKr9X6CQFq1aXu2o4K5cG/sfAA "Ruby – Try It Online")
The letters are parsed according to their ASCII code times `5/3` as follows (this gives the required number of semitones plus an offset of 108)
```
A    B    C    D    E    F    G
108  110  111  113  115  116  118
```
The last character (`#`, `b` or the letter again) is parsed as its ASCII code divided by 32 as follows
```
# letter (natural) b 
1  { --- 2 --- }   3
```
This is subtracted from the letter code.
Then the final result is returned as `13-(difference in semitones)%12`
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 25 24 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
╝─°U┤ƒXz☺=≡eA╕δ┴╬\¿☺zt┼§
```
[Run and debug it online](https://staxlang.xyz/#c=%E2%95%9D%E2%94%80%C2%B0U%E2%94%A4%C6%92Xz%E2%98%BA%3D%E2%89%A1eA%E2%95%95%CE%B4%E2%94%B4%E2%95%AC%5C%C2%BF%E2%98%BAzt%E2%94%BC%C2%A7&i=%5B%22A%22%2C+%22C%22%5D%0A%5B%22G%22%2C+%22G%23%22%5D%0A%5B%22F%23%22%2C+%22B%22%5D%0A%5B%22Bb%22%2C+%22Bb%22%5D%0A%5B%22Ab%22%2C+%22G%23%22%5D&a=1&m=2)
The corresponding ascii representation of the same program is this.
```
{h9%H_H32/-c4>-c9>-mrE-v12%^^
```
Effectively, it calculates the keyboard index of each note using a formula, then calculates the resulting interval.
1. Start from the base note, A = 2, B = 4, ... G = 14
2. Calculate the accidental offset `2 - code / 32` where `code` is the ascii code of the last character.
3. Add them together.
4. If the result is > 4, subtract 1 to remove B#.
5. If the result is > 7, subtract 1 to remove E#.
6. Modularly subtract the two resulting note indexes, and add 1.
[Answer]
## Batch, ~~136~~ 135 bytes
```
@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
```
Explanation: The substitutions in the `c` subroutine replace `#` in the note name with `+1` and `b` with `-1`. As this is case insensitive, `Bb` becomes `-1-1`. The variables for `C`...`A` (also case insensitive) are therefore chosen to be the appropriate number of semitones away from `B=-1`. The resulting string is then evaluated, and @xnor's trick of subtracting the result from the value gives the desired effect of subtracting the note values from each other. Edit: Finally I use @Arnauld's trick of subtracting the modulo from 13 to achieve the desired answer, saving 1 byte.
[Answer]
# [Python 3](https://docs.python.org/3/), 95 bytes
```
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])
```
[Try it online!](https://tio.run/##VcnLCoJAFADQvV8hI8G9eBMdsUJwkUF@xDSLGWTMMF/Zok2/PmlE4Pac/jVduza2JrvYRt11qVxFOoUKNPrvChTiJuI@d6rs10MqQuIUU0J7OlAUStGNJQwilLjdJdJnrscCU7ezBc3t@ZiAo4gk2n6s2wkMsCMjl50YovOnYqHCW9nZWzBfWa6/pme0Hw "Python 3 – Try It Online")
-14 bytes thanks to user71546
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 28 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
O64_ṠH$2¦ḅ-AḤ’d5ḅ4µ€IḞṃ12FṪ‘
```
A monadic link accepting a list of two lists of characters and returning an integer.
**[Try it online!](https://tio.run/##AUYAuf9qZWxsef//TzY0X@G5oEgkMsKm4biFLUHhuKTigJlkNeG4hTTCteKCrEnhuJ7huYMxMkbhuarigJj///9bIkYjIiwiQiJd "Jelly – Try It Online")** or see [all possible cases](https://tio.run/##y0rNyan8/9/fzCT@4c4FHipGh5Y93NGq6/hwx5JHDTNTTIEck0NbHzWt8Xy4Y97Dnc2GRm4Pd6561DDj/8Mdmx7unG50dM/hdqC0ysNdfUDKG4gj//93VnBWVnBJUnBRcFFWcE1ScFVwU3BTVnBPUnBXcFdWcExScFRwVFZwSlJwAgA "Jelly – Try It Online").
### How?
Performs some bizarre arithmetic on the ordinals of the input characters to map the notes onto the integers zero to twelve and then performs a base-decompression as a proxy for modulo by twelve where zero is then replaced by 12 then adds one.
```
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
```
---
### Also at 28 bytes...
A (not so direct) port of [xnor's Python 2 answer](https://codegolf.stackexchange.com/a/156233/53748)...
```
O×5:3z60_Ṡ¥2¦60U1¦Fḅ-‘N%12+2
```
[Try all possible cases](https://tio.run/##y0rNyan8/9//8HRTK@MqM4P4hzsXHFpqdGiZmUGo4aFlbg93tOo@apjhp2popG30/@GOTQ93Tjc6uudw@6OmNSoPd/UBKW8gjvz/31nBWVnBJUnBRcFFWcE1ScFVwU3BTVnBPUnBXcFdWcExScFRwVFZwSlJwQkA "Jelly – Try It Online")
[Answer]
# [CJam](http://cjam.readthedocs.io/en/latest/index.html), 67 bytes
```
l',/~)@)@{ciW*50+_z/}_@\~@@~-@@{ci65- 2*_9>-_3>-}_@\~@@~12+\- 12%+)
```
Online interpreter: <http://cjam.aditsu.net/>
[Answer]
# [Raku](https://raku.org/), 121 bytes
I write quite a lot of music in EDOs other than 12 so I implemented an option to choose a particular EDO.
```
{1+(round($^c*log2(3))*([-](map {m:P5/([A-G])(\#*)(b*)/;4613502.comb[$0.ord-65]+7*($1.comb-$2.comb)},($^b,$^a)))%$c||$c)}
```
No TIO link because TIO has an outdated Rakudo, so here are some examples:
```
f("A", "C", 12) # => 4
f("Bb", "Bb", 12) # => 13
f("F#", "B", 19) # => 9
f("G", "G#", 31) # => 3
f("C", "Dbb", 31) # => 2
```
]