白い鍵盤上のピアノの和音


9

バックストーリー[これは真実ではありません]

ピアノは次のように設定されています。

![http://www.piano-lessons-made-simple.com/images/2-Octave-Labled.gif

しかし、私のピアノでは、黒い鍵がすべて壊れています!

それでも壊れたピアノでコードを弾きたいと思っています。

音楽では、コードは一緒に演奏されるノートのグループです。コードの入力を可能にするために、最初に半音とは何かを定義します。

半音とは何ですか?

半音は、西洋音楽で最も短い距離です。ピアノの上部を見ると、通常は黒鍵から白鍵に、またはその逆に移動できることがわかります。ただし、Band CEandの間Fには黒いキーはありません。

コードとは?

この課題の目的のために、コードを、特定の数の半音を間に挟んだ一連の音符と定義します。たとえば、4-3-3コードから始めてみましょうC(音楽の人にとって、これはFメジャーのV 7コードです)。から始めCます。私たちは4つの半音をカウントアップ:C#DD#E。次のノートがありE、我々はその後3つの半音をカウントアップ:FF#G。次のノートがありG、我々はその後3つの半音をカウントアップ:G#ABb。だから、私たちは得るC-E-G-Bb。わーい!しかし、待って... Bbは黒い鍵であり、それらは壊れています...しかし、から始めるとGG-B-D-F!わーい!

入力

入力は、適切な形式の整数のリストとして提供されます。これは、上記のコードを表します。

出力

出力は、白いキーを使用するだけで開始できるメモのリストになります。キー名はすべて1文字であるため、これは最大7つのノートすべての文字列にすることもできます。空の出力も処理できる必要があります。

テストケース

input -> output // comments
4 3 -> C F G // this is a major triad
3 4 -> D E A // this is a minor triad
4 3 3 -> G // this is the major-minor seventh chord
3 3 3 -> [empty output] // this is the diminished-diminished seventh chord. All of them use black keys
4 4 -> [empty output] // this is an augmented triad
3 3 -> B // this is a diminished triad
1 -> B E // this is just a minor second
11 -> C F // this is just a major seventh

その他のスペック

  • 標準の抜け穴は禁止されています
  • 入力に少なくとも1つの整数があると想定できます
  • すべての整数は負ではなく、12未満であると想定することができます(ピアノは12音ごとに繰り返すため)
  • 出力はどの順序でもかまいません

受賞基準

4月15日時点で有効な最短の提出物が受け入れられます。


「非負で12未満」を想定できますが、「正で12以下」ではないのでしょうか。
ジョナサンアラン

@JonathanAllan基本的に違いはありません。私の方法では、Perfect Unisonを使用できますが、Perfect Octaveは使用できません。あなたの逆も同様です。理論的には、あなたの制限の方が理にかなっているかもしれませんが、すでに回答があり、課題を根本的に変えることはないので、おそらく変更すべきではないと思います。
HyperNeutrino 2017

回答:


3

ゼリー、25 バイト

236ḃ2ṙЀ7+\€Ṭ
+\ịþ¢Ạ€TịØA

オンラインでお試しください!またはテストスイートを見る

どうやって?

236ḃ2ṙЀ7+\€Ṭ - Link 1, white-note-offsets: no arguments
236ḃ2         - 236 in bijective base 2 [2, 2, 1, 2, 2, 1, 2] - semitones G->A, A->B ...
     ṙЀ7     - rotate left by, mapped over [1,2,3,4,5,6,7] - i.e. as above for each
                    starting white key (1st one A->B,B->C,...; 2nd B->C,C->D,...; etc)
         +\€  - reduce €ach with addition - i.e. absolute number of semitones: [[2,3,5,7,8,10,12],[1,3,5,6,8,10,12],[2,4,5,7,9,11,12],[2,3,5,7,9,10,12],[1,3,5,7,8,10,12],[2,4,6,7,9,11,12],[2,4,5,7,9,10,12]]
            Ṭ - untruth (vectorises) - make lists with 1s at those indexes: [[0,1,1,0,1,0,1,1,0,1,0,1],[1,0,1,0,1,1,0,1,0,1,0,1],[0,1,0,1,1,0,1,0,1,0,1,1],[0,1,1,0,1,0,1,0,1,1,0,1],[1,0,1,0,1,0,1,1,0,1,0,1],[0,1,0,1,0,1,1,0,1,0,1,1],[0,1,0,1,1,0,1,0,1,1,0,1]]

+\ịþ¢Ạ€TịØA - Main link: list of semitone gap integers (even negatives will work)
+\          - reduce by addition - gets the absolute semitone offsets needed
    ¢       - last link (1) as a nilad
   þ        - outer product with:
  ị         -     index into - 7 lists, each with 1s for white and 0s for black keys hit
                      note that indexing is modular and all the lists are length 12
                      so any integer is a valid absolute offset, not just 0-11 inclusive
     Ạ€     - all truthy for €ach - for each get a 1 if all keys are white ones, else 0
       T    - truthy indexes - get the valid starting white keys as numbers from 1 to 7
        ị   - index into:
         ØA -     the uppercase alphabet

6

MATL、31バイト

修正してくれたJonathan Allanに感謝します。

'BAGFEDC'"GYs12X\110BQX@YSYsm?@

オンラインでお試しください!または、すべてのテストケースを確認します

説明

パターン2 2 1 2 2 2 1は、連続する白いキーの間隔を指定します。プログラムは、すべての循環シフトをこの基本パターンに適用するループを使用して、各コードを入力コードの潜在的な最低音としてテストします。各シフトについて、パターンの累積合計が取得されます。たとえば、B潜在的な最低音として、パターンはにシフトされて1 2 2 1 2 2 2おり、その累積合計は1 3 5 6 8 10 12です。

次に、これが4 3 3コードをサポートできるかどうかを確認するために、コード間隔の累積合計を計算し4 7 10ます。12を法とする1ベースのモジュロを介してそれを削減します(の間隔は14を与えるでしょう2); そして、それらの数値がすべて許容値のメンバーであるかどうかを確認します1 3 5 6 8 10 12。この例ではそうではありません。それが事実なら、手紙を出力しBます。

循環シフトと出力文字の対応は、文字列によって定義されます'BAGFEDC'。これは、'B'(最初の文字)がによる循環シフトに対応することを示し1ます。'A'(2番目の文字)は、2などによる循環シフトに対応します。

'BAGFEDC'  % Push this string
"          % For each character from the string
  G        %   Push input array
  Ys       %   Cumulative sum
  12X\     %   1-based modulo 12, element-wise (1,12,13,14 respectively give 1,12,1,2)
  110BQ    %   Push 110, convert to binary, add 1 element-wise: gives [2 2 1 2 2 2 1]
  X@       %   Push current iteration index, starting at 1
  YS       %   Cyclic shift to the right by that amount
  Ys       %   Cumulative sum
  m        %   Ismember. Gives an array of true of false entries
  ?        %   If all true
    @      %     Push current character
           %   End (implicit)
           % End (implicit)
           % Display (implicit)

5

Mathematica、110バイト(ISO 8859-1エンコーディング)

±i_:=#&@@@Select["A#BC#D#EF#G#"~StringTake~{Mod[#,12,1]}&/@#&/@(Accumulate[i~Prepend~#]&/@Range@12),FreeQ@"#"]

±入力として整数のリストを受け取る単項関数を定義し(実際にはサイズや整数の符号に制限はありません)、1文字の文字列のリストを返します。たとえば、を±{3,4}返します{"A","D","E"}

"A#BC#D#EF#G#"~StringTake~{Mod[#,12,1]}&/@#整数のリストを対応するノート名に変換する関数です#。ただし、黒色のキーを表します。これは、各要素に適用されるAccumulate[i~Prepend~#]&/@Range@12我々が含むすべてのそのようなノート名リスト除外1から12までそれぞれの可能な音符で始まる、音符間隔のリスト入力リストから音符値のリストを構築し、"#"使用しSelect[...,FreeQ@"#"]、次いでを使用して、残りの各リストの最初のノートを返し#&@@@ます。


いい提出!
HyperNeutrino 2017

質問:Mathematicaは独自のバイトシステムを使用していますか?これは110文字ですが、UTF-8では+/-記号のために111バイトです。
HyperNeutrino 2017

割り当てを完全に取り除き、関数を「暗黙的に返す」ことができます。
wizzwizz4

@ wizzwizz4:私は変数に名前を付けAccumulate[i~Prepend~#]&なければならないことに気づきました。ただし、回避策を見つけてください。
グレッグマーティン

@HyperNeutrino:UTF-8が標準のエンコーディングであることは正しいですが、MathematicaはISO 8859-1エンコーディングでも(通常)機能します。私はそのことを記事で述べました。
グレッグマーティン

3

Python 2、159 155バイト

(これより短い有効な提出物があることを確認してからこれを投稿してください)

import numpy
s='C.D.EF.G.A.B'
def k(y):return lambda x:s[(x+y)%12]
for i in range(12):
    if s[i]!='.'and'.'not in map(k(i),numpy.cumsum(input())):print s[i]

ほんのささいな解決策です。整数のリストとして入力し、個々の行に各文字を出力します。

不要な変数を削除して-4バイト


3

JavaScript(ES6)、72 71 68バイト

a=>[..."C1D1EF1G1A1B"].filter((c,i,b)=>!+c>a.some(e=>+b[i+=e,i%12]))

黒のキーを省略して各キーをループし、半音の累積合計が黒のキーに到達しないことを確認します。

編集:@Arnauldのおかげで3バイト節約されました。


4
読みやすさ?!あなたはあなたが正しいサイトにいると確信していますか?:-)
wizzwizz4
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.