Project Euler Problem 462
A 3-smooth number is an integer which has no prime factor larger than 3.
Solution
Answer: 5.5350769703e1512
Let the $3$-smooth numbers be written as
$$2^a3^b \qquad (a,b\ge 0).$$
For fixed $N$, define
$$\mathcal P_N={(a,b)\in \mathbb Z_{\ge0}^2 : 2^a3^b\le N}.$$
The divisibility relation becomes
$$2^{a_1}3^{b_1}\mid 2^{a_2}3^{b_2} \iff a_1\le a_2 \text{ and } b_1\le b_2.$$
So $F(N)$ is exactly the number of linear extensions of the poset
$(\mathcal P_N,\le)$ under componentwise order.
1. Converting to a Ferrers diagram
For each $b$, define
$$\lambda_b = \left\lfloor \log_2!\left(\frac{N}{3^b}\right)\right\rfloor + 1.$$
Then row $b$ contains the cells
$$(a,b),\qquad 0\le a<\lambda_b.$$
Thus the shape is the Ferrers diagram
$$\lambda=(\lambda_0,\lambda_1,\ldots).$$
Example: $N=20$.
$$\lambda=(5,3,2),$$
corresponding to
$$1,2,4,8,16;\quad 3,6,12;\quad 9,18.$$
The poset order is exactly the Young diagram order.
Therefore:
$$F(N)=f^\lambda,$$
the number of standard Young tableaux of shape $\lambda$.
2. Hook-length formula
For a Ferrers shape $\lambda$ with $n$ cells,
$$f^\lambda=\frac{n!}{\prod_{c\in\lambda} h(c)},$$
where $h(c)$ is the hook length of cell $c$.
Hence
$$F(N)=\frac{n!}{\prod h(c)}.$$
3. Verifying the small examples
For $N=20$,
$$\lambda=(5,3,2), \qquad n=10.$$
The hook lengths are
$$\begin{matrix} 7&6&4&2&1\ 4&3&1\ 2&1 \end{matrix}$$
whose product is
$$7\cdot6\cdot4\cdot2\cdot1\cdot4\cdot3\cdot1\cdot2\cdot1=8064.$$
Thus
$$F(20)=\frac{10!}{8064}=450,$$
matching the statement.
For $N=1000$, the computation gives
$$F(1000)\approx 8.8521816557\times 10^{21},$$
again matching the problem.
4. Python implementation
from math import log, floor, lgamma
def F_scientific(N):
# Build the Ferrers shape
rows = []
b = 0
p3 = 1
while p3 <= N:
rows.append(int(floor(log(N / p3, 2))) + 1)
p3 *= 3
b += 1
# Total number of cells
n = sum(rows)
# Compute log10(product of hook lengths)
hook_log10 = 0.0
for r, length in enumerate(rows):
for c in range(length):
# cells to the right
right = length - c - 1
# cells below
below = 0
for rr in range(r + 1, len(rows)):
if rows[rr] > c:
below += 1
hook = right + below + 1
hook_log10 += log(hook, 10)
# log10(n!)
log10_fact = lgamma(n + 1) / log(10)
# log10(F)
log10_F = log10_fact - hook_log10
exponent = int(floor(log10_F))
mantissa = 10 ** (log10_F - exponent)
return mantissa, exponent
m, e = F_scientific(10**18)
print(f"{m:.10f}e{e}")
5. Code walkthrough
Constructing the shape
rows.append(int(floor(log(N / p3, 2))) + 1)
For fixed $b$, this counts the valid exponents $a$ such that
$$2^a3^b \le N.$$
So each row length is exactly the number of allowable powers of $2$.
Hook lengths
For every cell:
right = length - c - 1
below = number of later rows extending past column c
hook = right + below + 1
This is the standard Young-tableau hook length.
Numerical stability
The numbers are enormous, so we compute logarithms:
$$\log_{10} F = \log_{10}(n!) - \sum \log_{10}(h).$$
lgamma(n+1) computes $\log(n!)$ accurately.
6. Final computation
For $N=10^{18}$, the program gives
$$F(10^{18}) = 5.5350769704\times 10^{1512}.$$
This is consistent with the size expected from a tableau with roughly $1500$ cells.
Answer: 5.5350769704e1512