Xmas Contest 2017

A - Compressor

問題

  • どっちがコンプレッサーかけた音でしょう?(15問)

所感

これを1問目にぶち込んでくるセンスよ。面白いなあ。

耳で聴いたら10/15だった。意外といけるな(自分に対するハードルが低い)

ここまで巫山戯た問題なら、解答側も Brute force で自動Submit する人とかいそうだけど、連投制限あるんだっけ。

解法

wavを読み込んでサンプリングされた数値を得ても、コンプレッサー前後の数値的特徴がどんなところに現れるか、というセンスが無いとどうしようもない。

今回の問題では、「尖度」を計算することでぴたりと答えに当てはまるとのこと。

import wave
from scipy import fromstring, int16
from scipy.stats import variation, kurtosis

src_tpl = 'C:\\path\\to\\data\\input\\{:02d}_{}.wav'


def kurt(wav_path):
    with wave.open(wav_path, 'rb') as wr:
        data = wr.readframes(wr.getnframes())
    nums = fromstring(data, dtype=int16)
    return variation(nums), kurtosis(nums)


v_ans, k_ans = [], []

for i in range(1, 16):
    va, ka = kurt(src_tpl.format(i, 'A'))
    vb, kb = kurt(src_tpl.format(i, 'B'))
    v_ans.append('A' if va < vb else 'B')
    k_ans.append('A' if ka < kb else 'B')

print(''.join(v_ans))  # 分散
print(''.join(k_ans))  # 尖度

# 分散: BBABBBBABABBAAB
# 尖度: AABAAAABABABBAB
# 答え: AABAAAABABABBAB

サンプリング数値の絶対値の大きさは、大まかには音量を表す。

コンプレッサーは、ざっくり言うと以下の処理を行う。

  • 音量の大きい所を小さくする
  • 小さくした分、全体的に音量をわずかに上げる

これらが、サンプリング数値に及ぼす影響は、以下になる。

  • サンプリング数値が閾値以上のものが、一定の割合で小さくなる
  • 全てのサンプリング数値が、一定の割合で大きくなる

(厳密には、自然に聞こえるように、圧縮されるサンプルの前後では割合が緩やかに変化するため、単純では無い)

大きい音から小さい音までとっ散らかった音量がコンプレッサーで圧縮されるので、直感的には分散が減りそう……と思ったが、その後で全体の音量を上げるので、かけた後の方が(平均ー個々のサンプル)が多くのサンプルで僅かずつ大きくなり、結果として分散が増えるようだ。ただしそれも圧縮されたサンプル数と量に依るので、正しかったり正しくなかったりする。

尖度なら、平均より外れたデータが分散よりさらに重大に評価されるので、よく当てはまったということか。

programming_algorithm/contest_history/atcoder/2017/1224_xmascon.txt · 最終更新: 2018/07/25 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0