All Euler problems
Project Euler

Generalised Hamming Numbers

A Hamming number is a positive integer which has no prime factor larger than 5. We define a type- t generalised Hamming number as a positive integer which has no prime factor larger than t. How man...

Source sync May 21, 2026
Problem #0204
Level Level 05
Solved By 8,215
Languages C++, Python
Answer 2944730
Length 319 words
number_theorysearchrecursion

Problem Statement

This archive keeps the full statement, math, and original media on the page.

A Hamming number is a positive number which has no prime factor larger than \(5\).

So the first few Hamming numbers are \(1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15\).

There are \(1105\) Hamming numbers not exceeding \(10^8\).

We will call a positive number a generalised Hamming number of type \(n\), if it has no prime factor larger than \(n\).

Hence the Hamming numbers are the generalised Hamming numbers of type \(5\).

How many generalised Hamming numbers of type \(100\) are there which don’t exceed \(10^9\)?

Problem 204: Generalised Hamming Numbers

Mathematical Development

Theorem (Fundamental Theorem of Arithmetic, applied to smooth numbers). Every 100-smooth number n≥1n \geq 1 can be written uniquely as

n=p1a1p2a2⋯p25a25,n = p_1^{a_1} p_2^{a_2} \cdots p_{25}^{a_{25}},

where ai≥0a_i \geq 0 and p1<p2<⋯<p25p_1 < p_2 < \cdots < p_{25} are the 25 primes not exceeding 100. Thus the 100-smooth numbers up to NN are in bijection with the exponent vectors (a1,…,a25)(a_1,\ldots,a_{25}) satisfying ∏piai≤N\prod p_i^{a_i} \leq N.

Proof. This is exactly the Fundamental Theorem of Arithmetic restricted to the prime set {2,3,5,…,97}\{2,3,5,\ldots,97\}. □\square

Theorem (Recursive Counting). Define Ψ(N,i)\Psi(N, i) as the number of positive integers ≤N\leq N whose prime factors all lie in {pi,pi+1,…,p25}\{p_i, p_{i+1}, \ldots, p_{25}\}. Then

Ψ(N,i)=∑a=0⌊log⁡piN⌋Ψ ⁣(⌊Npia⌋,i+1),\Psi(N, i) = \sum_{a=0}^{\lfloor \log_{p_i} N \rfloor} \Psi\!\left(\left\lfloor \frac{N}{p_i^a} \right\rfloor, i+1\right),

with base case Ψ(N,26)=1\Psi(N, 26) = 1 for all N≥1N \geq 1. The desired answer is Ψ(109,1)\Psi(10^9, 1).

Proof. Partition the valid numbers by the exponent of pip_i. For a fixed exponent aa, the remaining factor must be at most N/piaN / p_i^a and may only use later primes. Summing over all admissible aa gives the recurrence. □\square

Lemma (Exponent Bounds). For each prime pip_i, the maximum exponent satisfying pia≤109p_i^a \leq 10^9 is amax⁡(pi)=⌊log⁡pi109⌋a_{\max}(p_i) = \lfloor \log_{p_i} 10^9 \rfloor. In particular, amax⁡(2)=29a_{\max}(2) = 29, amax⁡(3)=18a_{\max}(3) = 18, amax⁡(5)=12a_{\max}(5) = 12, amax⁡(7)=10a_{\max}(7) = 10, and amax⁡(97)=4a_{\max}(97) = 4.

Proof. Direct comparison of powers with 10910^9. □\square

Editorial

Every type-100 Hamming number is assembled from the 25 primes at most 100, so the problem is really about choosing exponent vectors rather than testing integers one by one. Once the prime list is fixed, a depth-first search can decide the exponent of the current prime, shrink the remaining budget accordingly, and recurse to the next prime.

This visits only valid smooth numbers. Large primes have very small exponent ranges, so the recursion tree thins out quickly, and every leaf corresponds to one admissible product. That is much more efficient than scanning all numbers up to 10910^9 and factoring them.

Pseudocode

List all primes p_1, p_2, ..., p_25 not exceeding 100.

Define Count(index, current_product):
    If index = 25:
        return 1

    p = p_index
    total = 0
    power = 1

    While current_product * power <= 10^9:
        total += Count(index + 1, current_product * power)
        power *= p

    return total

Return Count(0, 1)

Complexity Analysis

  • Time: Proportional to the number of recursive states visited, which is on the order of the number of 100-smooth numbers up to 10910^9.
  • Space: O(25)O(25) for the recursion stack.

Answer

2944730\boxed{2944730}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_204/solution.cpp
#include <bits/stdc++.h>
using namespace std;
int primes[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
long long LIMIT = 1000000000LL;
int dfs(int idx, long long cur) {
    if (idx == 25) return 1;
    int count = 0;
    long long power = 1;
    while (cur * power <= LIMIT) {
        count += dfs(idx + 1, cur * power);
        power *= primes[idx];
    }
    return count;
}
int main() {
    int answer = dfs(0, 1);
    assert(answer == 2944730);
    cout << answer << endl;
    return 0;
}