Empty

2013年4月から社会人になりました。

SONY GOF FOR IT ~4問目: 旋律に隠された特徴~

概要

今日も GO FOR IT を楽しんだ。

問題概要についてはエントリーの末尾に引用しております。

問題へのリンク -> 4) 旋律に隠された特徴

取り組んでみたが...

この問題について、1時間ほど取り組んだが旋律の特徴の定義が決まらずに悶々として、結局、他の人( id:kusano_k さん)の回答を見て納得->自己完結。

コード引用
# 特徴量の計算
def compute(s):
    # 譜面データ形式を、0:A, 1:A#, 2:B, 3:C, 4:C#, 5:D, 6:D#, 7:E, 8:F, 
    # 9:F#, 10:G, 11:G# に変換
    r = []
    # 付点の数
    d = 0
    for n in s.split(","):
        t = n.split(":")
        if t[0]!="":
            a = int(t[0])
            r += [(a+8)/7*12+[0,2,3,5,7,8,10][(a+1)%7]
                  +{"":0,"s":+1,"x":+2,"b":-1,"d":-2}[t[2]]]
        if t[1][-1]==".":
            d += 1
    # 差の絶対値の和+付点の個数%2を特徴量とする
    return sum(abs(r[i+1]-r[i]) for i in range(len(r)-1)) + d%2

A = "-3:4:,-2:4:,-1:4:,0:4:b,-1:4:,-2:4:,-3:4:,:4:,-1:4:,0:4:b,1:4:," \
    "2:4:,1:4:,0:4:b,-1:4:,:4:"
B = "3:4:,2:4:,1:4:,0:4:b,1:4:,2:4:,3:4:,:4:,1:4:,0:4:b,-1:4:,-2:4:," \
    "-1:4:,0:4:b,1:4:,:4:"
C = "3:4:,2:4:,1:4:,0:4:,1:4:,2:4:,3:4:,:4:,1:8:,0:4.:,-1:4:,-2:4:,:" \
    "8:,-1:4.:,0:8:,1:8:"
D = "-6:8:,-6:8:,-6:8:,-4:8:,-2:8:,-2:8:,-2:8:,:8:,-5:8:,-5:8:,-5:8:" \
    ",-3:8:,-2:8:,-2:8:,-2:8:,:8:,:8:,-2:8:,-2:8:,-1:8:b,-1:8:,-1:8:" \
    ",-1:8:,-1:8:b,-2:4:,0:4:,1:4:,:4:"
E = "-6:8.:,-7:16:,-6:8:,-5:8:,-4:8:,-4:8:,-4:4:,-3:8.:,-4:16:,-5:8:" \
    ",-6:8:,-5:4:,:4:,-3:8:,-5:4:,-5:8:,-4:8:,-4:8:,-3:8:,-3:8:,-4:8" \
    ":,-4:8:,-5:8:,-5:8:,-6:4:,:4:"
F = "-6:2:,-5:4:,-6:8:,-5:8:,-4:4:,-2:4:,-4:4:,:4:,-5:4:,-5:4:,-6:4:" \
    ",-5:4:,-4:2.:,:4:"
G = "-2:8.:,-1:16:,-2:8.:,-1:16:,-2:4:,-4:4:,-4:8.:,-3:16:,-4:8.:,-3" \
    ":16:,-4:4:,-6:4:,-4:8:,:8:,-6:8.:,-5:16:,-4:8:,:8:,-6:8.:,-5:16" \
    ":,-4:8.:,-4:16:,-2:8.:,-2:16:,-5:8.:,-4:16:,-5:4:"

# 各旋律の特徴量
print "A",compute(A)
print "B",compute(B)
print "C",compute(C)
print "D",compute(D)
print "E",compute(E)
print "F",compute(F)
print "G",compute(G)

# 作曲
def compose():
    # 音を譜面データ形式に変換
    def f(n):
        return "%s:%s:%s"%(
            [-1,-1,0,1,1,2,2,3,4,4,5,5][n%12]+n/12*7-7,
            4,
            ["","s","","","s","","s","","","s","","s"][n%12])
    
    # Gの特徴量
    Gf = compute(G)
    s = []
    s += [f(10),f(10+Gf/2),f(10)]
    # 特徴量が奇数なら付点で補正
    if Gf%2!=0:
        s += [":8.:",":16:"]
    # 旋律の長さを全音符4つ分にする
    s += [":4:"]*(16-len(s))
    
    return ",".join(s)

print compose()
http://d.hatena.ne.jp/kusano_k/20120207/1328644379

とてもわかりやすいコードで大変勉強になりました。ありがとうございます。それにしても、id:kusano_k さんは、一日に第四問までサクッと解かれているみたいで、かっこいいです。CODE VSも決勝3位の好成績を残されているすごい人みたいです。(参考: CODE VS-kusano_kの日記) 以後、ブログ等購読させていただきます。

コード読ませていただいた

"#"とか、"♭"とかの意味合いを考慮した上で、各音符は12音階のどこに位置するのか?変換してあげる必要があったみたい。(ちなみに僕は他次元として扱うていで、むにゃむにゃと書いていたので、泥沼の方向性に進んでいたことに早く気付けてよかったんじゃないかなと...)


結果、そのような秀逸な処理をすることで、音階と長さの実数の2次元データの入力となり、

音階の差の絶対値の和+付点の個数%2を特徴量とする

といったように、割と単純に特徴量の算出モデルが特定できる。

えっ思いつくかよっ!?と疑問を抱いたことは忘れたいと思います。

背景知識の欠如という壁により断念

そもそも、"音階"、"符点"って何?かつ、ダブルシャープ、ダブルフラットって初耳なんですけどというレベルの人だったので、この問題については背景知識(一般教養)がない僕にとっては、とてもつらい問題だったんじゃないかと、言い訳。


コードを見て、なんとなく把握できたが、詳しく理解しようと音楽の基礎知識について勉強しなおそうと思ったが、すぐ心が折れた。

参考

心が折れてしまったことに対しては、以後反省します。

また明日か明後日

今日のことは忘れて、明日か明後日に第5問解きますよ。第5問は事前に偏った知識を必要としない問題みたいだから、ここいらで本気出さないと、まずい気がするので頑張りたい。第3問も放置しているので、そのうち...


問題の引用

4) 旋律に隠された特徴
ある旋律演算器を考えてみましょう。この演算器は、単音から構成される旋律を入力すると、ある特徴量を算出し、出力することができます。
この演算器に、以下の3つの譜面を入力してみました。
f:id:Kshi_Kshi:20120206223340j:plain
すると、
・A)の特徴量と B)の特徴量は、異なっていました。
・A)の特徴量と C)の特徴量は、同じでした。


以下の【譜面データ形式】を用いて、以下の課題の解を求めてください。
i)上記仕様を満たすこの演算器を設計し、コーディングしてください。
ヒント) 隣り合う音符同士の関係に注目してください。

ii)以下の三つの旋律 D)、E)、F)を設計した演算器に入力した際、B)と同じ特徴量が出力されるものを回答してください。
f:id:Kshi_Kshi:20120206223339j:plain

iii)以下の条件を満たす出力を行う旋律生産器(すなわち作曲器)を設計し、コーディングしてください。求められた旋律をi)で設計した演算器に入力できる文字列として回答してください。
・以下の旋律 G)と同じ特徴量を持ちます。
・譜面上の位置 -2 で与えられるGの音ではじまり、同じ音で終わります。
・旋律の長さは、全音符3つ分よりも長く、高々全音符4つ分までとします。
f:id:Kshi_Kshi:20120206223337j:plain

http://www.sony.co.jp/SonyInfo/Jobs/newgrads/sus/q04.html
譜面データ形式

演算器に旋律を入力するには、譜面を以下の規則に従って文字列に変換する必要があります。
1. 1つの音符は3つの属性
「楽譜上の位置(高さ)、音符の種類(長さ)、臨時記号(高さの補正情報)」 を持ちます。
2. 属性と属性は”:”で区切られます。
3. 音符と音符は”,”で区切られます。
旋律の最後には”,”を必要としません。文字列の終端を以て旋律の終端とします。
4. 楽譜上の位置は第三線を原点(0)とし、第三間を+1,第四線を+2……、第二間を-1、第二線を-2……、というように正負の値で表現されます。
高低の範囲は、一般的なピアノの鍵盤上に存在する音(7オクターブ+短三度)に限るものとします。
5. 音符の種類は{全/二分/四分/八分/十六分/三十二分}音符を{1/2/4/8/16/32}で表します。
符点がついた場合は”.”を添えるものとします{1./2./4./8./16./32.}。
6. 臨時記号は、“s” シャープ、“x” ダブルシャープ、“b” フラット、d” ダブルフラットで表します。
この属性を持たない場合、その音符はナチュラルがついているものとします。
7. 休符については、高さが無いものとし、長さは音符と同様に表します。
8. 以上の規約で言及されない(下記変換例の楽譜に登場しない)楽譜上の記号、表現については、ここでは入力の対象外とします。すなわち、この問いにおいて考慮する必要はありません。
例)

= 0:1:,1:2:s,2:4.:x,1:8:,:8:,-1:16.:b,-2:32:d
設問中の各譜面を表す文字列は、上記の規則に従い次のようになります。
A) -3:4:,-2:4:,-1:4:,0:4:b,-1:4:,-2:4:,-3:4:,:4:,-1:4:,0:4:b,1:4:,2:4:,1:4:,0:4:b,-1:4:,:4:
B) 3:4:,2:4:,1:4:,0:4:b,1:4:,2:4:,3:4:,:4:,1:4:,0:4:b,-1:4:,-2:4:,-1:4:,0:4:b,1:4:,:4:
C) 3:4:,2:4:,1:4:,0:4:,1:4:,2:4:,3:4:,:4:,1:8:,0:4.:,-1:4:,-2:4:,:8:,-1:4.:,0:8:,1:8:
D) -6:8:,-6:8:,-6:8:,-4:8:,-2:8:,-2:8:,-2:8:,:8:,-5:8:,-5:8:,-5:8:,-3:8:,-2:8:,-2:8:,-2:8:,:8:,:8:,-2:8:,-2:8:,-1:8:b,-1:8:,-1:8:,-1:8:,-1:8:b,-2:4:,0:4:,1:4:,:4:
E) -6:8.:,-7:16:,-6:8:,-5:8:,-4:8:,-4:8:,-4:4:,-3:8.:,-4:16:,-5:8:,-6:8:,-5:4:,:4:,-3:8:,-5:4:,-5:8:,-4:8:,-4:8:,-3:8:,-3:8:,-4:8:,-4:8:,-5:8:,-5:8:,-6:4:,:4:
F) -6:2:,-5:4:,-6:8:,-5:8:,-4:4:,-2:4:,-4:4:,:4:,-5:4:,-5:4:,-6:4:,-5:4:,-4:2.:,:4:
G) -2:8.:,-1:16:,-2:8.:,-1:16:,-2:4:,-4:4:,-4:8.:,-3:16:,-4:8.:,-3:16:,-4:4:,-6:4:,-4:8:,:8:,-6:8.:,-5:16:,-4:8:,:8:,-6:8.:,-5:16:,-4:8.:,-4:16:,-2:8.:,-2:16:,-5:8.:,-4:16:,-5:4:

http://www.sony.co.jp/SonyInfo/Jobs/newgrads/sus/q04-1.html