犬ぶよツールズ制作記録

Javaによる研究生活のためのパッケージ、犬ぶよツールズ。
その開発と保守のための備忘録

千反田さんpython版

2012-10-31 21:31:16 | about
このツイートで着想を得て
発表されたcoffeeスクリプトがあります。
これをpythonで実装してみました。

watashi_kininarimasu.py (Gist)
※scriptの埋め込みはできないようです。

実行してみると

ちゃんとできてますね。

ここで定義している関数toKanji()は「極」まで扱えます。
1から10の52乗-1までの整数に対応していることになります。


インタフェース IterableIntegerArray の実装5種

2012-10-31 00:48:50 | about
● 概要
インタフェース IterableIntegerArray
パッケージjp.inubuyo.brain.utilに配置した。
そして、その実装5種類をパッケージjp.inubuyo.brain.util.implに入れた。
これらは、多重ループとN進数(あるいは重複順列)、順列、組合せ、重複組合せの仮想コレクションである。
これらの使い方をjythonで示す。

● 多重ループ
クラスNLoop_IterableIntegerArrayにより多重ループが出来る。
1つ目の変数iをi0からi1まで、2つ目の変数jをj0からj1まで走らせる2重ループは
NLoop_IterableIntegerArray([i0, j0], [i1, j1])で初期化する。
for文の慣習に従い、i0, j0などはループに含み、i1, j1などはループに含まない。

コレクションの内容をjythonで表示させると次のようになる。


Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06)
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_37
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import jp.inubuyo.brain.util as util
>>> import jarray
>>> tray = jarray.array([0, 0], 'i')
>>> loop = util.impl.NLoop_IterableIntegerArray([0, 0], [2, 3])
>>> for x in loop.iterator(tray, 0, 2):
. . .    print x, tray
. . .
0 array('i', [0, 0])
1 array('i', [0, 1])
2 array('i', [0, 2])
3 array('i', [1, 0])
4 array('i', [1, 1])
5 array('i', [1, 2])
>>>


xがインタフェースIteratorのメソッドnext()の戻り値、trayが仮想コレクションのトレイである。
tray[0]が外側のループの変数、tray[1]が内側のループの変数になっている。

● N進数
RadixN_IterableIntegerArrayによりN進数を順に挙げることができる。

次の例は2桁の3進数を全て挙げる。

>>> import jp.inubuyo.brain.util as util
>>> import jarray
>>> tray = jarray.array([0, 0], 'i')
>>> loop = util.impl.RadixN_IterableIntegerArray(3)
>>> for x in loop.iterator(tray, 0, 2):
. . .    print x, tray
. . .
0 array('i', [0, 0])
1 array('i', [0, 1])
2 array('i', [0, 2])
3 array('i', [1, 0])
4 array('i', [1, 1])
5 array('i', [1, 2])
6 array('i', [2, 0])
7 array('i', [2, 1])
8 array('i', [2, 2])
>>>


桁数はメソッドiterator()の2番目と3番目の引数で決まる。
同じRadixN_IterableIntegerArrayのインスタンスから桁数の異なるIteratorを得ることが出来る。
上のコードに続けて下のようにすれば、3桁になる。

>>> tray = jarray.array([0, 0, 0], 'i')
>>> for x in loop.iterator(tray, 0, 3):
. . .    print x, tray
. . .
0 array('i', [0, 0, 0])
1 array('i', [0, 0, 1])
2 array('i', [0, 0, 2])
3 array('i', [0, 1, 0])
4 array('i', [0, 1, 1])
5 array('i', [0, 1, 2])
6 array('i', [0, 2, 0])
7 array('i', [0, 2, 1])
8 array('i', [0, 2, 2])
9 array('i', [1, 0, 0])
10 array('i', [1, 0, 1])
11 array('i', [1, 0, 2])
12 array('i', [1, 1, 0])
13 array('i', [1, 1, 1])
14 array('i', [1, 1, 2])
15 array('i', [1, 2, 0])
16 array('i', [1, 2, 1])
17 array('i', [1, 2, 2])
18 array('i', [2, 0, 0])
19 array('i', [2, 0, 1])
20 array('i', [2, 0, 2])
21 array('i', [2, 1, 0])
22 array('i', [2, 1, 1])
23 array('i', [2, 1, 2])
24 array('i', [2, 2, 0])
25 array('i', [2, 2, 1])
26 array('i', [2, 2, 2])
>>>


● 組合せ
n個の数からk個を選び出す組合せはCombination_IterableIntegerArray(0, n, k)で得られる。
Combination_IterableIntegerArray(a, n, k)とすれば、aに続くn個の数から選び出す。

0から3までの4個の数から2個を選び出す例。

>>> loop = util.impl.Combination_IterableIntegerArray(0, 4, 2)
>>> tray = jarray.array([0, 0], 'i')
>>> for x in loop.iterator(tray, 0, 2):
. . .    print x, tray
. . .
0 array('i', [0, 1])
1 array('i', [0, 2])
2 array('i', [0, 3])
3 array('i', [1, 2])
4 array('i', [1, 3])
5 array('i', [2, 3])
>>>



● 順列
n個の数からk個を並べる順列はPermutation_IterableIntegerArray(0, n, k)で得られる。
Permutation_IterableIntegerArray(a, n, k)とすれば、aに続くn個の数から取り出して並べる。

0から3までの4個の数から2個を並べる例。

>>> loop = util.impl.Permutation_IterableIntegerArray(0, 4, 2)
>>> tray = jarray.array([0, 0], 'i')
>>> for x in loop.iterator(tray, 0, 2):
. . .    print x, tray
. . .
0 array('i', [0, 1])
1 array('i', [0, 2])
2 array('i', [0, 3])
3 array('i', [1, 0])
4 array('i', [1, 2])
5 array('i', [1, 3])
6 array('i', [2, 0])
7 array('i', [2, 1])
8 array('i', [2, 3])
9 array('i', [3, 0])
10 array('i', [3, 1])
11 array('i', [3, 2])
>>>


● 重複組合せ
n個の数からk個を重複して取り出す重複組合せはMulticombination_IterableIntegerArray(0, n, k)で得られる。
Multicombination_IterableIntegerArray(a, n, k)とすれば、aに続くn個の数から取り出して並べる。

0から3までの4個の数から2個を重複して取り出す例。

>>> loop = util.impl.Multicombination_IterableIntegerArray(0, 4, 2)
>>> a = jarray.array([0, 0], 'i')
>>> for x in loop.iterator(a, 0, 2):
. . .    print x, tray
. . .
0 array('i', [0, 0])
1 array('i', [0, 1])
2 array('i', [0, 2])
3 array('i', [0, 3])
4 array('i', [1, 1])
5 array('i', [1, 2])
6 array('i', [1, 3])
7 array('i', [2, 2])
8 array('i', [2, 3])
9 array('i', [3, 3])
>>>


● 重複順列
n個の数からk個を重複して並べた重複順列は、k桁のn進数と1対1に対応する。
つまりRadixN_IterableIntegerArray(0, n, k)で得られる。

0から3までの4個の数から2個を重複して並べる例。

>>> loop = util.impl.RadixN_IterableIntegerArray(4)
>>> a = jarray.array([0, 0], 'i')
>>> for x in loop.iterator(a, 0, 2):
. . .    print x, tray
. . .
0 array('i', [0, 0])
1 array('i', [0, 1])
2 array('i', [0, 2])
3 array('i', [0, 3])
4 array('i', [1, 0])
5 array('i', [1, 1])
6 array('i', [1, 2])
7 array('i', [1, 3])
8 array('i', [2, 0])
9 array('i', [2, 1])
10 array('i', [2, 2])
11 array('i', [2, 3])
12 array('i', [3, 0])
13 array('i', [3, 1])
14 array('i', [3, 2])
15 array('i', [3, 3])
>>>


● 応用
以上のクラスは数を並べたものを生成するだけだが、オブジェクトの配列を介せば、
任意のオブジェクトの集合について、部分集合や置換を取ることができる。

配列['neko', 'cat', 'gato']から2つの元を選んで並べる例。

>>> b = ['neko', 'cat', 'gato']
>>> loop = util.impl.Permutation_IterableIntegerArray(0, 3, 2)
>>> tray = jarray.array([0, 0], 'i')
>>> for x in loop.iterator(tray, 0, 2):
. . .    print x, b[tray[0]], b[tray[1]]
. . .
0 neko cat
1 neko gato
2 cat neko
3 cat gato
4 gato neko
5 gato cat
>>>


● まとめ
多重ループとN進数(あるいは重複順列)、順列、組合せ、重複組合せの仮想コレクションを作った。
これを使えば、任意のオブジェクトの集合について部分集合や置換を取ることができる。