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...
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 Foundation
Theorem (Fundamental Theorem of Arithmetic, applied to smooth numbers). Every 100-smooth number can be uniquely written as where and are the 25 primes not exceeding 100. The set of 100-smooth numbers up to is therefore in bijection with the set of 25-tuples satisfying .
Proof. This follows directly from the Fundamental Theorem of Arithmetic. A positive integer is 100-smooth iff all its prime factors lie in . The uniqueness of prime factorization establishes the bijection.
Theorem (Recursive Counting). Define as the number of positive integers whose prime factors all lie in . Then:
with base case for all , and for . The total count of 100-smooth numbers is .
Proof. We partition the smooth numbers by the exponent of prime . For a fixed , the number where is a positive integer with all prime factors in . The count of such is . Summing over valid (from 0 to ) gives the recurrence. The base case holds because with no primes left, the only valid number is .
Lemma (Exponent Bounds). For each prime , the maximum exponent satisfying is . In particular: , , , , .
Proof. Direct computation: , , etc. For : .
Editorial
Count 100-smooth numbers up to 10^9. We first generate the primes required by the search, then enumerate the admissible combinations and retain only the values that satisfy the final test.
Pseudocode
Input: N = 10^9, primes = [2, 3, 5, 7, 11, ..., 97] (25 primes)
Output: count of 100-smooth numbers <= N
Complexity Analysis
- Time: Each recursive call corresponds to a distinct 100-smooth number (the leaves of the recursion tree), plus internal nodes. The total number of calls is , the answer itself, which is approximately .
- Space: for the recursion stack (depth equals the number of primes).
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#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;
}
"""
Problem 204: Generalised Hamming Numbers
Count 100-smooth numbers up to 10^9.
"""
def primes_up_to(n):
sieve = [True] * (n + 1)
sieve[0] = sieve[1] = False
for i in range(2, int(n**0.5) + 1):
if sieve[i]:
for j in range(i*i, n + 1, i):
sieve[j] = False
return [i for i in range(2, n + 1) if sieve[i]]
def count_smooth(primes, limit):
"""Count B-smooth numbers up to limit by recursive DFS."""
def dfs(idx, cur):
if idx == len(primes):
return 1
count = 0
p = primes[idx]
power = 1
while cur * power <= limit:
count += dfs(idx + 1, cur * power)
power *= p
return count
return dfs(0, 1)
def count_smooth_brute(B, limit):
"""Brute force: check each number for B-smoothness."""
count = 0
for n in range(1, limit + 1):
temp = n
for p in primes_up_to(B):
while temp % p == 0:
temp //= p
if temp == 1:
count += 1
return count
# Cross-check
p100 = primes_up_to(100)
assert len(p100) == 25
assert count_smooth_brute(5, 100) == count_smooth(primes_up_to(5), 100)
answer = count_smooth(p100, 10**9)
assert answer == 2944730, f"Expected 2944730, got {answer}"
print(answer)