Problem 34
しばらく時間かかるんだよなぁ.けどこの問題に気合を入れる気合が….
def factorial(n): if n < 0:return None if n == 0:return 1 return n*factorial(n-1) def sumfacto(a): return sum([factorial(int(x)) for x in str(a)]) print sum([x for x in xrange(10**5/2) if sumfacto(x) == x]) - 3
フォーラムにワンライナーがあった.
print sum([int(reduce(lambda x, y: int(x) + int(y), [str(reduce(lambda x, y: x * y, range(1, int(i) + 1) + [1])) for i in str(j)])) for j in range(100000) if (j == int(reduce(lambda x, y: int(x) + int(y), [str(reduce(lambda x, y: x * y, range(1, int(i) + 1) + [1])) for i in str(j)])))])-3
無駄に長くしている印象を受けたので短くした.
print sum([j for j in range(5*10**4) if j == sum([(reduce(lambda x, y: x * y, range(1, int(i) + 1) + [1])) for i in str(j)])])-3
reduceってこう使うのかーって思ったけど,python3.0からは無くなっていると聞いた.勿体無いなぁ.reduce無し(import無し)だとYコンビネーターを使えばワンライナー無理やり出来そうだったけどあまりに複雑になるのでやめました.
追記
ワンライナーの方をもう少し綺麗にした.というかジェネレータに置き換えて,
operatorを使ってみた.importは邪道?
import operator as t; print sum(j for j in xrange(5*10**4) if j == sum((reduce(t.mul, xrange(1, int(i) + 1) or [1])) for i in str(j)))-3
実行速度の比較
import timeit ori = timeit.Timer(stmt = "sum([int(reduce(lambda x, y: int(x) + int(y), [str(reduce(lambda x, y: x * y, range(1, int(i) + 1) + [1])) for i in str(j)])) for j in range(100000) if (j == int(reduce(lambda x, y: int(x) + int(y), [str(reduce(lambda x, y: x * y, range(1, int(i) + 1) + [1])) for i in str(j)])))])-3") change = timeit.Timer(stmt = "sum([j for j in range(5*10**4) if j == sum([(reduce(lambda x, y: x * y, range(1, int(i) + 1) + [1])) for i in str(j)])])-3") lamb = timeit.Timer(stmt = "sum(j for j in xrange(5*10**4) if j == sum((reduce(lambda x,y:x * y, xrange(1, int(i) + 1) or [1])) for i in str(j)))-3") final = timeit.Timer(setup = "import operator as t", stmt = "sum(j for j in xrange(5*10**4) if j == sum((reduce(t.mul, xrange(1, int(i) + 1) or [1])) for i in str(j)))-3") print "orginal",ori.timeit(number = 10) print "changed",change.timeit(number = 10) print "lamb",lamb.timeit(number = 10) print "final",final.timeit(number = 10)
実行結果
orginal 38.4732050896
changed 13.8680729866
lambda 8.99447011948
final 7.6372821331
一番早かったのでよしとする.