Project Euler Problem 043

http://projecteuler.net/index.php?section=problems&id=43
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2043

数1406357289は0から9のPandigital数である (0から9が1度ずつ現れるので).
この数は部分語が面白い性質を持っている.

d1を1桁目, d2を2桁目の数とし, 以下順にdnを定義する. この記法を用いると次のことが分かる.

d2d3d4=406は2で割り切れる
d3d4d5=063は3で割り切れる
d4d5d6=635は5で割り切れる
d5d6d7=357は7で割り切れる
d6d7d8=572は11で割り切れる
d7d8d9=728は13で割り切れる
d8d9d10=289は17で割り切れる

このような性質をもつ0から9のPandigital数の総和を求めよ.

import math
import itertools
import datetime

def nlen(n):
    if n == 1: return 1
    return int(math.ceil(math.log(n)/math.log(10)))


def d(n, i):
    return n / int(math.pow(10, nlen(n) - i)) % 10


def condition(n):
    for i, j in enumerate([ 13, 17 ]):
        x = reduce(lambda a,b: a * 10 + d(n, i+b+7), xrange(3), 0)
        if x % j != 0:
            return False
    return True


def euler043():
    result = 0
    for l in itertools.permutations(range(10)):
        if l[0] == 0: continue
        
        if l[3] % 2 != 0: continue
        if l[5] != 0 and l[5] != 5: continue
        if (l[2]+l[3]+l[4]) % 3 != 0: continue
        if ((l[4]*10+l[5])-(l[6]*2)) % 7 != 0: continue
        if (l[6]*10+l[7]+l[5]) % 11 != 0: continue
        
        val = reduce(lambda a,b: a * 10 + b, l)
        
        if condition(val):
            print '', val
            result += val
        
    print result
    

begin = datetime.datetime.now()
euler043()
end = datetime.datetime.now()
print end - begin

答え: 16695334890
実行時間: 2.169671秒くらい