Pythonによるlistの数値⇄文字列変換,組み合わせ,順列 競技プログラミング用

# タイトル通りです。

ただの備忘録なので、内容が飛び飛びだぉ。
競技プログラミングをやるときに使ったりすると便利って事で残しておく。

# 数値 ⇄ 文字列 変換

その前に、この2つの型の判定をする関数を作成。
手法として、要素の一番最初を取り出し、それによってintかstrに分けるという処理としている。
get_dataはlist型である。

``` Python3

def judge(get_data):

    if isinstance(get_data[0], int):

        return True

    elif isinstance(get_data[0], str):

        return False

```

まぁこんな感じで実装できますかね。
んで、次に実際の変換の処理。

```Python3

def is_change(get_data):

    # intならTrue,strならFalseとする
    res = judge(get_data)
    
    # res == Trueと同じ,int→str変換
        if res:

        s_data = [str(i) for i in get_data]

        return s_data
    
    # res == Falseと同じ,str→int変換
    elif not res:

        i_data = [int(i) for i in get_data]
        print('strを通ったよ')

        return i_data
```

って感じ。書き方はお好みでどうぞ。2つの型判定しかしない場合だとif-elseで分岐した方がいいね、うん。
型を少し増やしたいとき用にそうしたかったんだ。。。
まぁ、ならなぜboolで管理してるのかって話だけど、ただの忘備録なので御愛嬌。

上二つの処理をまとめた関数も書いておく~

```Python3
# 返り値はlist型
def is_change2(get_data):

    # intならTrue,strならFalseとする
    res = false

    if isinstance(get_data[0], int):
        
        res = True

    elif isinstance(get_data[0], str):
    
        res = False

    # int→str変換
    
        if res:

        s_data = [str(i) for i in get_data]

        return s_data
    
    # str→int変換
    elif not res:

        i_data = [int(i) for i in get_data]
        print('strを通ったよ')

        return i_data
```

まぁ、態々二つにわけるまでもなかったね。
ただ、分けた方がis_changeが見やすくなるからってだけ。
拡張して、全部の型どれでも対応させるのなら意味あったけど。
まぁ忘備録で見て思い出せればいいから。。。
って言い訳。
気が向いたらjudgeも拡張しておく。

# 部分集合の求め方

``` python3
['a', 'b', 'c']
```

からなる集合を考える。これは2の3乗で8通りの部分集合を持つ。
3bitで表せるだとか、難しい話は他の詳しい方の記事を参考にして頂きたい。
https://docs.python.org/ja/3/library/itertools.html
より、

```Python3
combinations('ABCD', 2) --> AB AC AD BC BD CD
combinations(range(4), 3) --> 012 013 023 123
```

のような使い方がされる。
なお、これをそのままコピーして動かないとか言われても困るので、一応書いておく...

```python3
hoge = combinations('ABCD',2)
hogehoge = conbinarions(range(4),3)
```

後はこれをfor文なりで展開してくれ。

今回は、任意の桁で全ての部分集合を取得したいので、for文で回してあげる。
外側のループは、回す回数である。
combinations(任意のリスト,何文字から構成されているか)というようになっている。
ここで、空集合から、全てを含んだ部分集合と、全ての集合が必要だとすると、要素数ga
3の場合、0~3まで回してあげる必要がある。よって、+1としてあげることで、全ての部分集合を取得できる。
内側のループは、要素数の選択である。

```Python3
from itertools import combinations

def length(items):

    get_pettern = []

    for i in range(len(items) + 1):

        for j in combinations(items, i):

            get_pettern.append(j)

    return get_pettern

```

以上で、全ての組み合わせ(部分集合を求めることができた。)

ちなみに、
```python3
combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
```
のようにすることで、重複を許して選ぶこともできる。
これは、カードを戻してから引き直す。数学の重複を許す組み合わせってことですね、
ちなみに、重複を許さない組み合わせは、くじ引きなどをして、箱に戻さない場合に利用できそうですね♩

んで、次に今度は順列を求めてみる
まずは重複無しのパターン

```python3

def permutation(items):

    pattern = []

    for i in range(len(items)):

        for j in itertools.permutations(items, i):

            pattern.append(j)

    return pattern
```

説明は面倒なので端折ります。
まぁ上の組み合わせの説明と変わらないからね。

次に重複ありパターン

```python3

pattern = []

    for i in range(len(items)):

        for j in itertools.product(items, repeat=i):
            pattern.append(j)

    return pattern

```

はい、これが重複あり順列。
以上をまとめて僕はこうやって実装した

```python3

# 順列を返す関数 0と1により,重複ありと重複無しを選ぶ、0なら重複無し
# 欲しい方に応じてselectに数値を投げ入れる

def permutation(select, items):

    if select == 0:

        pattern = []

        for i in range(len(items)):

            for j in itertools.permutations(items, i):

                pattern.append(j)

        return pattern

    elif select == 1:

        pattern = []

        for i in range(len(items)):

            for j in itertools.product(items, repeat=i):
                pattern.append(j)

        return pattern

# 組み合わせを返す関数 selectが0なら重複無し

def combination(select, items):

    if select == 0:

        pattern = []

        for i in range(len(items)):

            for j in itertools.combinations(items, i):

                pattern.append(j)

        return pattern

    else:

        pattern = []

        for i in range(len(items)):

            for j in combinations_with_replacement(items, i):
                pattern.append(j)
        
        return pattern

```

って感じです。長くなったなぁ。
もし使いたいという人が居たなら勝手に使ってどうぞ〜
以上！