Problem 52
125874という数とその倍の251748は同じ数字から成っていて違う順序である。
2x,3x,4x,5x,6xがxと同じ数字から成る最も小さいxを見つけよ。
http://projecteuler.net/index.php?section=problems&id=52
同じ数字から成る、は数字にリストにしてソートして再び数にする。この数が一致するかどうかで判定します。
from itertools import islice, ifilter, ifilterfalse, countdef gen_digits(n):
while n:
yield n % 10
n /= 10def normalize(n):
return reduce(lambda x, y: x * 10 + y, sorted(gen_digits(n)))# all True?
def all(f, a):
for e in ifilterfalse(f, a):
return False
return Truedef is_valid(n):
m = normalize(n)
return all(lambda k: normalize(n * k) == m, xrange(2, 7))for n in islice(ifilter(is_valid, count(1)), 1):
print n
よく考えると、6倍しても同じ桁数でなければなりません。だから6桁なら106/6より小さくなければなりません。また、6倍して同じ数字から成り立つということは、各桁の和が3の倍数ということになり、元の数も3の倍数ということになります。さらに、頭の桁は元が1なので、2倍、3倍とすると、頭の桁は変わっていくことになります。つまり最低でも6つ以上の異なる数字から成ることになります。ということは6桁以上でなければなりません。
# 残りは上と同じ
def gen_solution():
for m in count(N):
for n in xrange(10 ** (m - 1) + 2, 10 ** m / N, 3):
if is_valid(n):
yield nN = 6
for n in islice(gen_solution(), 1):
print n
このコードで10番目の解まで求めたところ、どうやらパターンがあるようです。そのパターンが常に解になることは分かったのですが、これ以外に本当に解が無いのでしょうか。