作者: Naomasa Numajiri
日時: 2002/5/13(19:06)
こんにちは、


| お題:
|     任意の値の異なる1桁の数値4つが与えられたとき、
|     四則演算(+、−、×、÷)を使用して計算結果を
|     10にする。
| 
| 機能が不十分ですが、pythonでのサンプル
| # 以下、不十分な点:
| # * 「×、÷」が「+、−」より優先されていない。
| # * 4つの数値が与えられた時の順番を維持したまま計算している。

* [TSabc:151]
    真似してevalを使いました。
* [TSabc:153]
    「1/4+2+8=10」の問題は、一旦float()で変換することで対処しました。
    そのために表示が変わっています。perlは「1/4」は「0.25」と処理
    されるようです。

ticket1.py -- 最初と同じ動作仕様でコードを書き直したもの。
ticket2.py -- 順番を並べ替えたものも確認
ticket3.py -- "交換の法則(?)"で同一になるものを除く
    * 同じ式で2箇所「交換法則」が適用できる可能性などが未チェック

--^
def result(expr):
    if 10 == eval(' '.join(expr)):
        return 1
    else:
        return 0
def generate(list):
    expr = [['+',list[0]]]
    for number in list[1:]:
        tmp = []
        for op in ('*','/','+','-'):
            tmp = tmp +[e+[op,number] for e in expr]
        expr = tmp
    return expr
def main(list):
    list = map(float,list)
    list = map(str,list)
    for expr in filter(result,generate(list)):
        print '10 = '+' '.join(expr[1:])

if __name__ == '__main__':
    n = [8,4,2,1]
    main(n)
--$

--^
def result(expr):
    if 10 == eval(' '.join(expr)):
        return 1
    else:
        return 0
def generate(list):
    expr = [['+',list[0]]]
    for number in list[1:]:
        tmp = []
        for op in ('*','/','+','-'):
            tmp = tmp + [e+[op,number] for e in expr]
        expr = tmp
    return expr
def main(rest,list=[]):
    if len(rest) > 0:
        for i in range(len(rest)):
            main(rest[:i]+rest[i+1:],list+[str(float(rest[i]))])
    else:
        for expr in filter(result,generate(list)):
            print '10 = '+' '.join(expr[1:])
    

if __name__ == '__main__':
    n = [8,4,2,1]
    main(n)
--$

--^ ticket3.py
_chk = {}
def parse(expr):
    expr = tuple(expr)
    if _chk.has_key(expr): return 0
    for i in (0,2,4):
        op0,nm0,op1,nm1,op2 = expr[i:i+5]
        if op0 in ('+','-') and op1 in ('+','-') and op2 in ('+','-'):
            _chk[expr[:i]+(op0,nm0,op1,nm1)+expr[i+4:]] = 1
            _chk[expr[:i]+(op1,nm1,op0,nm0)+expr[i+4:]] = 1
        if op0 in ('+','-') and op1 == '*':
            _chk[expr[:i]+(op0,nm0,op1,nm1)+expr[i+4:]] = 1
            _chk[expr[:i]+(op0,nm1,op1,nm0)+expr[i+4:]] = 1
        if op0 in ('*','/') and op1 in ('*','/'):
            _chk[expr[:i]+(op0,nm0,op1,nm1)+expr[i+4:]] = 1
            _chk[expr[:i]+(op1,nm1,op0,nm0)+expr[i+4:]] = 1
    return 1
def result(expr):
    if parse(expr+['+']) and 10 == eval(' '.join(expr)):
        return 1
    else:
        return 0
def generate(list):
    expr = [['+',list[0]]]
    for number in list[1:]:
        tmp = []
        for op in ('*','/','+','-'):
            tmp = tmp + [e+[op,number] for e in expr]
        expr = tmp
    return expr
def main(rest,list=[]):
    if len(rest) > 0:
        for i in range(len(rest)):
            main(rest[:i]+rest[i+1:],list+[str(float(rest[i]))])
    else:
        for expr in filter(result,generate(list)):
            print '10 = '+' '.join(expr[1:])
    

if __name__ == '__main__':
    n = [8,4,2,1]
    main(n)
--$