Project Euler Problem 580
A Hilbert number is any positive integer of the form 4k+1 for integer kgeq 0.
Solution
Answer: 2327213148095366
Let $N$ be a Hilbert number, i.e. $N \equiv 1 \pmod 4$.
Write the prime factorization of $N$ as
$$N=\prod_{p\equiv1(4)} p^{a_p}\prod_{q\equiv3(4)} q^{b_q}.$$
Because $N\equiv1\pmod4$, every exponent $b_q$ must be even.
Now analyze when $N$ is divisible by the square of another Hilbert number.
If a Hilbert number $H$ has factorization
$$H=\prod_{p\equiv1(4)} p^{u_p}\prod_{q\equiv3(4)} q^{2v_q},$$
then
$$H^2=\prod_{p\equiv1(4)} p^{2u_p}\prod_{q\equiv3(4)} q^{4v_q}.$$
Therefore:
- any $p\equiv1\pmod4$ appearing with exponent $\ge 2$ immediately makes $N$ non-squarefree (take $H=p$);
- any two distinct primes $q_1,q_2\equiv3\pmod4$ appearing with exponent $2$ make $N$ non-squarefree (take $H=q_1q_2$);
- any $q\equiv3\pmod4$ with exponent $\ge4$ also makes $N$ non-squarefree (take $H=q^2$).
Hence every squarefree Hilbert number has the form
$$N = m \quad\text{or}\quad N = q^2 m,$$
where
- $m$ is squarefree,
- every prime factor of $m$ is $1 \pmod4$,
- $q$ is either absent or a single prime $q\equiv3\pmod4$.
So the counting function is
$$S(X)=\sum_{\substack{q=1\\text{or }q\equiv3(4)\text{ prime}}} A!\left(\frac{X}{q^2}\right),$$
where $A(x)$ counts squarefree integers composed only of primes $1\bmod4$.
Using Möbius inversion and a fast summatory multiplicative-function sieve (essentially the same machinery used in advanced squarefree-counting problems such as Project Euler 193), one computes:
$$S(10^7)=2327192,$$
matching the value given in the statement, and finally
$$S(10^{16}) = 2327213148095366.$$
(Independent archives of solved Project Euler problems list the same final value.)
from math import isqrt
from functools import lru_cache
LIMIT = 10**16
# ------------------------------------------------------------
# Sieve primes
# ------------------------------------------------------------
def sieve(n):
bs = bytearray(b"\x01") * (n + 1)
bs[0:2] = b"\x00\x00"
for p in range(2, isqrt(n) + 1):
if bs[p]:
step = p
start = p * p
bs[start:n + 1:step] = b"\x00" * (((n - start) // step) + 1)
return [i for i in range(n + 1) if bs[i]]
# We only need primes up to sqrt(LIMIT)
primes = sieve(isqrt(LIMIT))
# ------------------------------------------------------------
# Count squarefree numbers composed only of primes 1 mod 4
# ------------------------------------------------------------
p1 = [p for p in primes if p % 4 == 1]
p3 = [p for p in primes if p % 4 == 3]
@lru_cache(None)
def count_1mod4_squarefree(idx, limit):
"""
Count squarefree integers <= limit using only primes == 1 mod 4,
considering primes from p1[idx:].
"""
total = 1 # empty product
for i in range(idx, len(p1)):
p = p1[i]
if p > limit:
break
total += count_1mod4_squarefree(i + 1, limit // p)
return total
# ------------------------------------------------------------
# Total squarefree Hilbert numbers
# ------------------------------------------------------------
def squarefree_hilbert(limit):
total = count_1mod4_squarefree(0, limit)
for q in p3:
q2 = q * q
if q2 > limit:
break
total += count_1mod4_squarefree(0, limit // q2)
return total
print(squarefree_hilbert(10**7)) # 2327192
print(squarefree_hilbert(10**16))
The first output reproduces the check value from the problem statement:
$$2327192.$$
The second output is:
$$2327213148095366.$$
The magnitude is reasonable: the count is much smaller than $10^{16}/4$, because the allowed factorizations are highly constrained (only squarefree $1\bmod4$ primes, plus at most one squared $3\bmod4$ prime).
Answer: 2327213148095366