「自作Python100本ノック」15日目（やっと最終日：96本〜100本目）

「自作Python100本ノック」15日目です。

ついに、**自作Python100本ノック最終日**になりました！

まあ、最初に書いた通り、別に日に日に問題のレベルが高まる制度ではないので、
いつも通りぬるくやっていきます。
正直80問目あたりから本気で問題に不足してて、問題の質は2の次になってきます。
(だって、もうだいたい解き方のパターン一緒なんだもん。。。)
（かといって、AtCoderContestとか漁ってもほぼほぼ難しくて解けないんだもん。。。）


さて、いよいよラストですが
「自作Python100本ノック」とはそもそも何ぞや？
どの程度のレベル感なのか？
どのように進めて行くのか？
など気になる方は詳しくは[こちら](https://qiita.com/ahpjop/items/373f807d68044cda1c9b#%E8%87%AA%E4%BD%9Cpython100%E6%9C%AC%E3%83%8E%E3%83%83%E3%82%AF1%E6%9C%AC5%E6%9C%AC%E7%9B%AE)に整理してありますのでまずはそちらを確認するようお願いします。
それでは始めていきます！

##Q96:完全数
問題：
高橋君は完全なものが大好きです。

自然数には、完全数というものがあります。 完全数というのは、自分以外の約数の総和が自分と等しくなる自然数のことです。 例えば 6 の場合 1+2+3=6となるので完全数です。 それに対して、自分以外の約数の総和が自分より小さくなる場合は不足数と言い、大きくなる場合は過剰数と言います。

高橋君には今気になっている自然数があります。高橋君のために、それが完全数なのか不足数なのか過剰数なのか判定してください。

```q96.py
def perfect_number(n):
    y_num = []
    for i in range(2, n):
        if n % i == 0:
            y_num.append(i)
            m = n // i
            y_num.append(m)
    y_num.append(1)
    y_num = set(y_num)
    sum_y = sum(y_num)
    if sum_y == n:
        print("完全数です")
    else:
        print("完全数ではありません")
       
perfect_number(6)            
```
[出典][AtCoder Regular Contest 026](https://arc026.contest.atcoder.jp/tasks/arc026_2)

##Q97:　ハミング距離
問題：
２つの整数が与えられます。
これらを２進法に直した時の「ハミング距離」を測りなさい。

ハミング距離とは、２つの数字のうち、異なっている箇所の個数のことです。
いやいやまだよくわかんねえよって方は、これ以上自分には説明できないので本家の問題文の方を確認ください！

今回は、2進数のハミング距離なので、XORをして、「１」を数えているだけですね。
2進数にする`format() `、XORをする`n ^ m`そして、`count()`といった関数がすでにあるので組み合わせるだけですね。

```q97.py
def hamming_distance(n, m):
    return format(n ^ m, 'b').count('1')

hamming_distance(17, 117)
```
[出典][CheckiO: Elementary](https://py.checkio.org/ja/mission/hamming-distance2/)


##Q98:Numbers Factory
問題：
2桁の整数が与えられる。 その整数の約数を出力しなさい。 
条件： 約数は全て１桁であること。 
　　　答えが複数存在する場合は、約数の個数が１番少なくなる方を出力すること。

```q98.py
# 正しい方
def checkio(number):
    ret = []
    for i in range(9, 1, -1):
        while not number % i:
            number /= i
            ret.append(i)
            if number == 1:
                return int(''.join(map(str, sorted(ret))))
    return 0
```
ちなみにこれ私解けませんでした。
↓ちなみに私の答え

```
#　自分のやつ
def checkio(n):
    list_n =[1,2,3,4,5,6,7,8,9]
    if n < 10:
        return n

    factors = []
    for d in range(9,1, -1):
        if n >= 10 and n % d == 0 and  d != 1:
            factors.append(d)
            n = n / d
        else:
            continue
    if n in list_n:
        factors.append(n)
    else:
        return 0
    if len(factors) == 1:
        return 0
    else:
        factors = ['{:.0f}'.format(n) for n in factors]
        factors.sort()
        s = ''.join([str(n) for n in factors])
        print(s)
        return int(float(s))
    
    

checkio(20)
```
[出典][CheckiO: Simple](https://py.checkio.org/ja/mission/number-factory/)

##Q99:Number Base
問題：
ある進数（radix）で記された数字(str_number)が与えられます。
この数字を10進法に直して表示しなさい。

条件
そもそも与えられた数字が、与えられた進法で表すことができないもの出会った場合は"-1"と表示

例：
convert_10("AF", 16) == 175
convert_10("101", 2) == 5
convert_10("Z", 36) == 35
convert_10("AB", 10) == -1


```q99.py
def convert_10(str_number, radix):
    try:
        return int(str_number, radix)
    except ValueError:
        return -1

convert_10(3C5,16)
```
[出典][Number Base](https://py.checkio.org/ja/mission/number-radix/)

##Q100:Double Substring
問題：
あるテキストが与えられます。
そのテキストの内、ある文字列が２回登場した場合、その文字列の文字数を表示してください。

例：
double_substring('aaaa') ==> 2
double_substring('abc') ==> 0
double_substring('aghtfghkofgh') ==> 3 # fgh

```q100.py
def double_substring(line):

    s = []
    for i in range(len(line)-1) :
        for j in range(i+1,len(line)+1) :
            if line[i:j] in line[j:] :
                s.append(len(line[i:j]))
    
    if len(s)>0 :
        return max(s)
    else :
        return 0
```
[出典][Double Substring](https://py.checkio.org/ja/mission/double-substring/)


##感想
最後は、AtCoderのコンテスト問題とCheckiOに頼りまくりました。
ただ、やっていてひしひしと感じるのは

**「確かに実力が上がっている！」**

と言うことです。

最初なんかCheckiOが解けねええええって悩んでいたのに、
今では、問題選ぶ時問題文読んで「これは流石に簡単すぎるしなあ」と言っているレベルにまでいきました。
（逆に今度はAtCoderのC問題解けねえええええとなっていますが）

さて、今回でとりあえず「自作Python100本ノック」終えることができました。
時間があれば、問題のレベルや種類に合わせて並び替えて行こうかとも思っています。

とりあえず、**自分と同じような悩みを持っていた人たちに役立ったら良いなと思います。**
これからも自分は「そこそこの学生エンジニア」を目指し自分はPythonをガンガン勉強していくので、
フォロー等してもらえればなと思います。

[Twitter](https://twitter.com/ahpjop)では現在Pythonの啓蒙活動に勤しんでいるのでそちらの方も見てもらえればと思います！

それでは！

##完走者（Twitterで完走したと報告してもらえれば順次載せます！）
１人目：@thipot 
完走コメント：
 「終わったー(≧∀≦)
中々難しかったー、分からなかった問題もあったから忘れた頃にもう一度解き直してリベンジしたいぜよ」
　　
2人目：@ks_mocchaso
完走コメント：
「回を追うごとにPythonの知識が少しずつ増えていき、楽しさも増していきました。
解くのに時間がかかるときでも、辛抱強く取り組めたのは良かったです。
この演習での経験を活かして卒業研究のクオリティを上げられたらと思います！」

3人目：@tettsu_ 
感想コメント： 
2ヶ月ほど細々と続けながら完走させて頂きました。
とにかく写経⇒中身理解⇒アレンジ、みたいに進めてきて、大変勉強になりました。
javaしかロクに触れたことがなくpythonワカラナイから始めたのですが、文字処理の強さを実感できました。
単純なスライスでも深いですし、itertoolsを始めとする強力なライブラリの充実さに驚きました。
真偽判定になんでも突っ込めてしまうのは、最初ルールを理解するまで戸惑いました。
とにかくありがとうございました！