大小二分法


15

和音のリス​​トが与えられた場合、それらを「メジャー」または「マイナー」としてラベル付けします。

入力

入力は、スペースで区切られた3つのノートで構成されるコードのリストで、1行に1つです。各音符は、大文字の音符名(A- G)とオプションの臨時記号(#またはb)で構成されます。コードは、任意の反転である場合があります(つまり、ノートは任意の順序である場合があります)。

出力

コードがメジャーの場合、「メジャー」を出力します。コードがマイナーの場合、「マイナー」を出力します。コードがメジャーでもマイナーでもない場合は、空白行を出力します。

入力

C E G
F Ab C
C Eb Gb
E G B
Db F Ab
Bb G D
D A Gb

出力

Major
Minor

Minor
Major
Minor
Major

テストスクリプト

過去の質問のいくつかと同様に、JoeyVenteroが元々作成したいくつかのテストスクリプトをもう一度処理して、この質問のテストケースを提供しました。

使用法: ./test [your program and its arguments]

報酬

仕様を満たしていることが確認でき、テストに合格し、明らかにゴルフの試みを行った各エントリは、私から賛成票を受け取ります(そのため、使用方法を回答してください)。2012年10月13日までの最短のソリューションが勝者として受け入れられます。

ちょっとした理論

音楽理論の知識をお持ちでない方は、ここで十分な情報を入手して競争してください。

メジャーまたはマイナーコードは、特定の半音パターンで区切られた3つの音で構成されます。コードのルート(ボトムノート)を0と見なす場合、メジャーコードはパターン0-4-7で、マイナーコードはパターン0-3-7です。一部の音符が半音離れていて、一部の音符が離れているという事実によって、事態はより厄介になります。Ab- からの半音の広がりはG#次のとおりです。

G#/Ab A A#/Bb B/Cb B#/C C#/Db D D#/Eb E/Fb E#/F F#/Gb G G#/Ab
  0   1   2    3     4    5   6   7    8     9    10  11  12

G#/AbG#は、と同じ音であることを意味しAbます。このことから、コードAb C Ebはメジャーコードであり、Ab Cb Ebマイナーコードであることがわかります。

さらに複雑な問題に、弦がEb Cb Ab同じであると考えられAb Cb EbCb Eb AbおよびCb Ab Eb等々 。これらのバリエーションはどれもまだマイナーなコードです。


2
あなたのbashテスターに​​は入力と期待される答えを交換する必要があると思います。
flodel

@flodelはい、その通りです。申し訳ありませんが、今修正しました。Powershellテストスクリプトにも同じ問題がないことを確認する必要があります。
ガレス

回答:


3

GolfScript、83文字

n%{' '%{1\{'A#BC D EF G'?+}/.}%$(+2/{~- 12%}%.(+.(+]$0=.$]10,7>?'MMaijnoorr

'>2%}%

これは簡単な最初のソリューションです。これはさらにゴルフができると確信しています。コメントでflodelが指摘したバグを修正した後、bashテストスイートに合格します。

編集1:標準化されたメジャーおよびマイナーコードパターンを認識するための短い方法で5文字を保存しました。

編集2: grcのソリューションに触発された、よりコンパクトな出力エンコーディングでさらに2文字を保存しました。(ありがとう!)副作用として、コードは出力後に余分な空白行を出力するようになりましたが、テストハーネスはそれを受け入れるように見えるので、大丈夫だと思います。:)

仕組みは次のとおりです。

  • 外側のループn%{ }%n*は入力を行に分割し、各行の中括弧内でコードを実行し、結果を改行で結合します。

  • ' '%各行をノートの配列に分割します。それらのメモのそれぞれについて1\{'A#BC D EF G'?+}/、文字列内の各文字を検索'A#BC D EF G'して位置を加算することにより、そのメモを半音数に変換します(文字列内で見つからない文字、特にを含む場合は-1になりますb)。(このトリックを以前に使用したことは確かです。)最後に、.各番号が重複しているため、ループの終わりで、たとえば入力F Ab Cがになってい[9 9 0 0 4 4]ます。

  • 次にノートを$でソートし、最初のノートをで最後に移動し(+、配列をでペアに分割して、2/例えばのようになり[[9 0] [0 4] [4 9]]ます。次に{~- 12%}%、ノートの各ペアを12を法とする差分にマッピングし、サンプルの配列をに変換し[9 8 7]ます。

  • 次に、.(+配列のコピーを作成し、その要素を1つ左に回転させます。これを2回行い、コピーを配列に集めます。]その結果、例は次のようになり[[9 8 7] [8 7 9] [7 9 8]]ます。

  • 次に、この配列の配列をで並べ替え$、最初の要素(この場合[7 9 8])を使用し0=ます。次に、この配列のコピーを作成し(.)、並べ替え($)、未並べ替えと未並べ替えの両方の配列を別の配列の配列に収集し(])、最初に出現する配列を検索します(2つの文字を保存する[7 8 9]よう10,7>に記述されています) ) 初期化。

  • これにより、0(ソートされていない配列がであった[7 8 9]ためコードがメジャーである1場合)、(ソートされていない配列がの順列であった場合、[7 8 9]最初の要素が最小でなければならない場合[7 9 8]、コードをマイナーにすることができます)または-1(ソートされた配列でさえ等しくない場合[7 8 9])。

  • この番号は文字列の開始インデックスとして使用され"MMaijnoorr\n\n"\nsはコード内の実際の改行として与えられます)、そこからその文字と1秒おきに出力として取得されます。インデックスが-1の場合、文字列の最後の文字から始まります。これは単なる改行です。


いい説明。私はいつもGolfScriptで持っているように見える同じ難しさを持っています-テストするために一度に行を呼び出すことができますecho "G# B# Eb" | ruby golfscript.rb ilmari.gsが、どのようにテストスクリプトを実行しますか?試しました./test ruby golfscript.rb ilmari.gsが、それは何もありませんでした。(これは明らかに動作しますので、私はすでにあなたに+1を与えてくれたが、私はちょうど好奇心が強い)
ガレス

1
@Gareth:それはbashテストスクリプトのバグのようです。複数の引数を正しく処理しません。それを修正するには、交換するargs="$@"args=("$@")してgot=$("$cmd" "$args")got=$("$cmd" "${args[@]}")。(または単にgolfscript.rb実行可能ファイルを作成して実行します./test ./golfscript.rb chords.gs。)
Ilmari Karonen

4

Python、160

f='A#BC D EF G3453543'.find
try:
 while 1:x,y,z=sorted(map(lambda x:f(x[0])+f(x[1:])+1,raw_input().split()));print'MMianjoorrr'[f(`y-x`+`z-y`)/14:-1:2]
except:0
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.