Background
いらすとやの画像をドット絵にしたった。(part1)で色を4分割するときに
range_color = [0, 85, 170, 255]
(または[ i* int(255/3) for i in range(3)]
)と閾値を手動で設定していました。(実質は3分割にして4つの値の近似をとっていました。)
今回はちょうど割り切れたので問題なかったのですが、範囲と分割数が任意で違った値だったらどのようにアルゴリズムを設計すればいいかと思ったのでまとめてみました。
上記の例では範囲は255、分割数は3を指しています。
Method
きれいに割り切れずに余りが発生します。
その場合は最初の要素に+1を均等に足すようにします。
で、方法ですが、
- 範囲と分割数から商と余りを算出する
- 一時的な計算用に足し算リストを作成する
- 足し算リストをもとに要素(境界値)を計算してpushする。
の流れです。
Development
import sys
def main():
if len(sys.argv) != 3:
print("[USAGE] you give parameters this command.")
print("[EXAMPLE] python main.py [range number] [n-division number]")
print("[EXAMPLE] python main.py 255 4")
sys.exit()
r = int(sys.argv[1]) #範囲
d = int(sys.argv[2]) #n分割数
q, mod = divmod(r, d) #商、余りの計算
#足し算リスト
plus = [q + 1 if i < mod else q for i, d in enumerate(range(d - 1))]
print(plus)
#出力
dst = []
dst.append(plus[0])
for i in range(len(plus)):
dst.append(plus[0] + sum(plus[:1 + i]))
print(dst)
if __name__ == '__main__':
main()
Comment
\W $ python main2.py 255 6
[43, 43, 43, 42, 42]
[43, 86, 129, 172, 214, 256]
\W $ python main2.py 255 10
[26, 26, 26, 26, 26, 25, 25, 25, 25]
[26, 52, 78, 104, 130, 156, 181, 206, 231, 256]
「足し算リスト」と言っているのはそれぞれの要素の間隔の値をリスト化したものです。
このリストをもとにsum(plus[:1 + i])
で各要素を計算します。
例) 範囲 255、 分割数 10、7つめの要素を計算したい場合
初期値 26 + [26, 26, 26, 26, 26, 25] の合計値 = 181
高校数列で習った階差数列ですな。
テラナツい
a_n = a_1 + \sum_{k=1}^{n-1}b_k \quad (n \geqq 2 )
PostScript
何かコンテンツを作成していると小さなスケールでもアルゴリズムを少し考えることがあります。
開発者としてはqiitaのitemsが増えるので書くことに事欠かないです。
Reference
-
整数をできるだけ均等になるように n分割
-
[(x + i) // n for i in range(n)]
でできるのですね。こっちの方がシンプル。
-