英語ではHighly composite numberです。これより小さい数は全て、約数の個数が自分のそれより小さい自然数です。なぜこれが重要なのかは知りません。
これはProblem 110のコードを少し改変するだけで得られます。1分以内に約数の個数が1012以内の高度合成数な数を求められました。1を含めると750個です。
グラフを書いてみましょう。まずは、何番目の高度合成数がどれくらいの大きさか見ます。
k番目の高度合成数をHCN(k)と書くと、
HCN(n) 〜 Cen0.8
くらいになるようです。ここから0.8よりは小さくなるようですが。
もう一つ、高度合成数と約数の個数を見てみます。
nの約数の個数をd(n)と書くと、
d(n) 〜 Cen0.7
くらいになるようです。
from itertools import * from Queue import PriorityQueue from math import log import sys import time def gen_sorted(init, nexts): pq = PriorityQueue() pq.put(init) while not pq.empty(): e = pq.get() yield e for e1 in nexts(e): pq.put(e1) def is_prime(n): return all(n % p != 0 for p in xrange(2, n)) def gen_primes(M): for p in (n for n in count(2) if is_prime(n)): yield p if M == 0: break M /= 2 def gen_possible_to_add(es): yield 0 e0 = es[0] for k in xrange(1, len(es)): if es[k] < e0 - 1: break yield k def is_possible_to_add(es): # e + 3 <= 3 * (e + 1 - q) # 2e >= 3q p_next = primes[len(es)] return any(es[k] * 2 < 3 * qs[len(es)][k] for k in gen_possible_to_add(es)) def nexts((n, es, m)): e0 = es[0] if e0 == 1: es1 = es + (1,) yield (n * primes[len(es)], es1, m * 2) else: if not is_possible_to_add(es): return for k in xrange(1, len(es)): if es[k] == e0 - 1: es1 = es[:k] + es[:1] + es[k+1:] yield (n * primes[k], es1, m / e0 * (e0 + 1)) break elif es[k] < e0 - 1: break es2 = (e0 + 1,) + es[1:] yield (n * 2, es2, m / (e0 + 1) * (e0 + 2)) t0 = time.clock() E = 12 N = 10 ** E primes = list(gen_primes(N)) L = len(primes) qs = [ [ int(log(primes[l]) / log(primes[k]) + 1) for k in xrange(L) ] for l in xrange(L) ] prev_m = 1 for n, es, m in takewhile(lambda x: x[2] < N, gen_sorted((2, (1,), 2), nexts)): if m > prev_m: print n, m prev_m = m print >>sys.stderr, time.clock() - t0