半音数


21

ガイドライン

仕事

文字列またはリスト/配列として入力された2つのノートが与えられた場合、それらが離れている半音の数(ノート自体を含む)を計算し、数値として出力します。

半音の説明:

半音は、キーボードを1段上げまたは下げます。例は、CからC#です。以下に示すように、音符Cは白い音符の上にあり、C#はその1つ上の黒い音符です。半音は、次の場合を除き、黒の音符から次の白の音符に上下にジャンプします。

  • BからC
  • CからB
  • EからF
  • FからE

キーボード

'A, C' -> 4

'G, G#' -> 2

'F#, B' -> 6

'Bb, Bb' -> 13


ルール

  • 2つのノート間の最大距離は13半音です。
  • 2番目に入力されたノートは常に最初に入力されたノートの上になります。
  • 入力は、文字列または配列/リストとして取得できます。あなたは文字列としてそれを取る場合は、ノートがなり、カンマ区切り(例えばString -> 'A, F'Array -> ['A', 'F'])。
  • 常に2つの有効なメモが与えられると仮定できます。
  • シャープはと表示され#、フラットはと表示されますb
  • コードは調和的な同等物をサポートする必要があります(例:F#とGbの両方をサポートする必要があります)
  • コードは、名前の付いたメモをサポートする必要はありませんが、シャープまたはフラットなしで名前を付けることができます(つまり、E#やCbをサポートする必要はありません)。ただし、コードでサポートされている場合はボーナスポイントです。
  • コードでダブルシャープまたはダブルフラットをサポートする必要はありません。
  • 同じ音符または同じ音高(たとえば、「Gb、Gb」または「A#、Bb」)の両方を取得した場合、2番目の音は最初の音よりも正確に1オクターブ上ではないと想定できます。
  • これはコードゴルフであるため、バイト数が最も少ない答えが優先されます。

G -> G#両方が含まれているため、2を取得します。
ハイパーニュートリノ

@HyperNeutrinoうんごめん。私に代わって間違い。
アモリス

1
Cbまたはのようなメモに対応する必要がありE#ますか?ダブルシャープ/フラットはどうですか?
ソク

1
@Sokいいえ、コードでE#やCbなどのメモをサポートする必要はありません。また、ダブルシャープやフラットをサポートする必要もありません。質問をより明確にするために更新しました。混乱についてすみません。
アモリス

2
明確にするために、音楽理論の意味である半音の距離から話をする場合、開始時の音含まれません。数学では(X, Y]、CからC#が1半音、CからCが12半音として表されます。
ドム

回答:



7

JavaScript(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

テストケース

ハッシュ関数

ハッシュ関数の目的は、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

12961モジュロ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 Batchのモジュロの符号は除数の符号なので、推測しますか?
アーナウルド

いいえ、JSのように配当のサインですが、以前のゴルフのために反転した結果のサインを修正するわずかにゴルファーであることが判明しました。
ニール

4

Perl、39 32バイト

含み+1のためにp

STDINの開始行と終了行を2行で入力してください

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

コードだけ:

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


@wastlだから私は言われました。ただし、どのメタ投稿を知りたいので、そこに行って意見を異にすることができます:
トンホスペル

私のコメントはリンクです。気軽にクリックしてください。
wastl

これは私のものと非常によく似ているように見えます-しかし、Perlの素晴らしく短い+1
Level River St

@LevelRiverStさて、これトン・ホスペルです。
msh210

4

Japt、27バイト

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

オンラインでテストしてください!入力を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

ルビー、56バイト

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

オンラインでお試しください!

文字は、ASCIIコード時間5/3に従って次のように解析されます(これにより、必要な半音数にオフセット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

スタックス25 24 バイト

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

オンラインで実行してデバッグする

同じプログラムの対応するASCII表現はこれです。

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

実際には、式を使用して各ノートのキーボードインデックスを計算し、結果の間隔を計算します。

  1. ベースノートから開始、A = 2、B = 4、... G = 14
  2. オフセット偶然の計算最後の文字のASCIIコードです。2 - code / 32code
  3. それらを一緒に追加します。
  4. 結果が4を超える場合、1を減算してB#を削除します。
  5. 結果が7より大きい場合、1を減算してE#を削除します。
  6. 結果の2つのノートインデックスをモジュラー減算し、1を加算します。

1
["F#","B"]6である必要があります。
Weijun周

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

説明:cサブルーチン内の置換#は、音名で+1bで置き換えられ-1ます。これは大文字と小文字を区別しないため、にBbなり-1-1ます。したがって、C... A(大文字と小文字を区別しない)の変数は、から適切な半音の数になるように選択されますB=-1。次に、結果の文字列が評価され、値から結果を減算する@xnorのトリックは、互いにノート値を減算するという望ましい効果をもたらします。編集:最後に、13からモジュロを減算する@Arnauldのトリックを使用して、目的の答えを達成し、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])

オンラインでお試しください!

user71546のおかげで-14バイト


-8バイトをord(q[0])-65置き換えて"ABCDEFG".find(q[0]);)
浅本しえる

ああ、(g(b)+~g(a))%12+2置き換えてさらに-6バイト1+((g(b)-g(a))%12or 12)
浅本シエル

@ user71546ああクール、ありがとう!
ハイパーニュートリノ

1

ゼリー、28 バイト

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

文字の2つのリストのリストを受け入れ、整数を返すモナドリンク。

オンラインでお試しください!または、考えられるすべてのケースを参照してください。

どうやって?

入力文字の序数に対して奇妙な算術演算を実行して、音符を0から12の整数にマッピングし、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バイトで...

xnorのPython 2回答の(それほど直接ではない)ポート...

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

考えられるすべてのケースを試す


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.