2018年11月20日火曜日

開発環境

問題解決のPythonプログラミング ―数学パズルで鍛えるアルゴリズム的思考 (Srini Devadas (著)、黒川 利明 (翻訳)、オライリージャパン)の5章(水晶をどうぞ壊してください)、練習問題(問題1)を取り組んでみる。

コード(Emacs)

Python 3

#!/usr/bin/env python3
def convert_to_decimal(r, d, rep):
    '''
    >>> convert_to_decimal(4, 4, [0, 0, 0, 0])
    0
    >>> convert_to_decimal(4, 4, [1, 2, 3, 3])
    111
    >>> convert_to_decimal(4, 4, [2, 0, 0, 0])
    128
    >>> convert_to_decimal(4, 5, [1, 0, 0, 1, 4]) # 誤植?
    65
    >>> convert_to_decimal(4, 5, [1, 3, 3, 3, 4]) # 誤植?
    127
    >>> convert_to_decimal(4, 4, [1, 0, 0, 1]) # 修正
    65
    >>> convert_to_decimal(4, 4, [1, 3, 3, 3]) # 修正
    127
    >>> convert_to_decimal(4, 4, [1, 2, 0, 1])
    97
    >>> convert_to_decimal(4, 4, [1, 2, 3, 3])
    111
    '''
    return sum([rep[i] * r ** (d - (i + 1)) for i in range(d)])


def how_hard_is_the_crystal(n, d, did_break=None):
    r = 1
    while r ** d <= n:
        r += 1
    print(f'Radix chosen is {r}')

    k = 1
    num_drops = 0
    floor_no_break = [0] * d
    for i in range(d):
        for j in range(r - 1):
            floor_no_break[i] += 1
            floor = convert_to_decimal(r, d, floor_no_break)
            if floor > n:
                floor_no_break[i] -= 1
                break
            print(f'Drop ball {k} from floor {floor}')
            # did_break = input('Did the ball break (yes/no)?: ')
            num_drops += 1
            # if did_break == 'yes':
            if did_break[i] == 'yes':
                floor_no_break[i] -= 1
                k += 1
                break
    hardness = convert_to_decimal(r, d, floor_no_break)
    return hardness, num_drops


if __name__ == '__main__':
    import doctest
    doctest.testmod()

    def yes_no(n):
        if n % 2 == 0:
            return 'yes'
        return 'no'
    for did_break in [['no'] * 6,
                      ['yes'] * 6,
                      [yes_no(i) for i in range(6)],
                      [yes_no(i + 1) for i in range(6)]]:
        print(how_hard_is_the_crystal(128, 6, did_break))

入出力結果(Terminal, Jupyter(IPython))

Trying:
    convert_to_decimal(4, 4, [0, 0, 0, 0])
Expecting:
    0
ok
Trying:
    convert_to_decimal(4, 4, [1, 2, 3, 3])
Expecting:
    111
ok
Trying:
    convert_to_decimal(4, 4, [2, 0, 0, 0])
Expecting:
    128
ok
Trying:
    convert_to_decimal(4, 5, [1, 0, 0, 1, 4]) # 誤植?
Expecting:
    65
**********************************************************************
File "./sample1.py", line 10, in __main__.convert_to_decimal
Failed example:
    convert_to_decimal(4, 5, [1, 0, 0, 1, 4]) # 誤植?
Expected:
    65
Got:
    264
Trying:
    convert_to_decimal(4, 5, [1, 3, 3, 3, 4]) # 誤植?
Expecting:
    127
**********************************************************************
File "./sample1.py", line 12, in __main__.convert_to_decimal
Failed example:
    convert_to_decimal(4, 5, [1, 3, 3, 3, 4]) # 誤植?
Expected:
    127
Got:
    512
Trying:
    convert_to_decimal(4, 4, [1, 0, 0, 1]) # 修正
Expecting:
    65
ok
Trying:
    convert_to_decimal(4, 4, [1, 3, 3, 3]) # 修正
Expecting:
    127
ok
Trying:
    convert_to_decimal(4, 4, [1, 2, 0, 1])
Expecting:
    97
ok
Trying:
    convert_to_decimal(4, 4, [1, 2, 3, 3])
Expecting:
    111
ok
2 items had no tests:
    __main__
    __main__.how_hard_is_the_crystal
**********************************************************************
1 items had failures:
   2 of   9 in __main__.convert_to_decimal
9 tests in 3 items.
7 passed and 2 failed.
***Test Failed*** 2 failures.
Radix chosen is 3
Drop ball 1 from floor 81
Drop ball 1 from floor 108
Drop ball 1 from floor 117
Drop ball 1 from floor 126
Drop ball 1 from floor 127
Drop ball 1 from floor 128
(128, 6)
Radix chosen is 3
Drop ball 1 from floor 81
Drop ball 2 from floor 27
Drop ball 3 from floor 9
Drop ball 4 from floor 3
Drop ball 5 from floor 1
(0, 5)
Radix chosen is 3
Drop ball 1 from floor 81
Drop ball 1 from floor 108
Drop ball 2 from floor 90
Drop ball 2 from floor 99
Drop ball 2 from floor 102
Drop ball 3 from floor 100
Drop ball 3 from floor 101
(101, 7)
Radix chosen is 3
Drop ball 1 from floor 81
Drop ball 2 from floor 27
Drop ball 2 from floor 54
Drop ball 2 from floor 63
Drop ball 3 from floor 57
Drop ball 3 from floor 60
Drop ball 3 from floor 61
(60, 7)
$

0 コメント:

コメントを投稿