How to resolve the algorithm Hamming numbers step by step in the Python programming language
How to resolve the algorithm Hamming numbers step by step in the Python programming language
Table of Contents
Problem Statement
Hamming numbers are numbers of the form Hamming numbers are also known as ugly numbers and also 5-smooth numbers (numbers whose prime divisors are less or equal to 5).
Generate the sequence of Hamming numbers, in increasing order. In particular:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Hamming numbers step by step in the Python programming language
The provided code contains several functions that generate Hamming numbers. Hamming numbers are defined as numbers that can be expressed as a product of powers of 2, 3, and 5.
hamming2() function:
- Uses a memoization technique to store previously calculated Hamming numbers.
- Maintains a list of multipliers (2, 3, 5) and corresponding indices into the memoization list.
- Generates Hamming numbers by finding the minimum value among the multiplied values of the current indices.
- Updates the indices and values as it generates new Hamming numbers.
hamming() function:
- Calculates Hamming numbers up to a specified limit by iteratively multiplying and checking for the minimum value.
- Uses a list to store the generated Hamming numbers.
h() function:
- Generates Hamming numbers using a heap.
- Initially, the heap contains a single value (1).
- It pops the smallest value from the heap and pushes its multiples of 2, 3, and 5 back into the heap.
- Duplicates are eliminated by popping all equal values from the heap before pushing new multiples.
raymonds_hamming() function:
- Uses a generator function to yield Hamming numbers.
- Creates three generator functions for multiples of 2, 3, and 5.
- Merges these generators and filters out duplicates to produce a sequence of Hamming numbers.
hamming_numbers() function:
- Generates Hamming numbers using tee() to create multiple iterators from the same generator.
- Merges three iterators that produce multiples of 2, 3, and 5.
hamming() function (different from the one above):
- Generates Hamming numbers using merge() and chain() from itertools.
- Defines helper functions to generate sequences of multiples of 2, 3, and 5.
- Merges these sequences and skips duplicates to produce a sequence of Hamming numbers.
All the functions produce sequences of Hamming numbers, and the code demonstrates how to generate the first 20 numbers, the 1691st number, and the 1 millionth number using different approaches.
Source code in the python programming language
from itertools import islice
def hamming2():
'''\
This version is based on a snippet from:
https://web.archive.org/web/20081219014725/http://dobbscodetalk.com:80
/index.php?option=com_content&task=view&id=913&Itemid=85
http://www.drdobbs.com/architecture-and-design/hamming-problem/228700538
Hamming problem
Written by Will Ness
December 07, 2008
When expressed in some imaginary pseudo-C with automatic
unlimited storage allocation and BIGNUM arithmetics, it can be
expressed as:
hamming = h where
array h;
n=0; h[0]=1; i=0; j=0; k=0;
x2=2*h[ i ]; x3=3*h[j]; x5=5*h[k];
repeat:
h[++n] = min(x2,x3,x5);
if (x2==h[n]) { x2=2*h[++i]; }
if (x3==h[n]) { x3=3*h[++j]; }
if (x5==h[n]) { x5=5*h[++k]; }
'''
h = 1
_h=[h] # memoized
multipliers = (2, 3, 5)
multindeces = [0 for i in multipliers] # index into _h for multipliers
multvalues = [x * _h[i] for x,i in zip(multipliers, multindeces)]
yield h
while True:
h = min(multvalues)
_h.append(h)
for (n,(v,x,i)) in enumerate(zip(multvalues, multipliers, multindeces)):
if v == h:
i += 1
multindeces[n] = i
multvalues[n] = x * _h[i]
# cap the memoization
mini = min(multindeces)
if mini >= 1000:
del _h[:mini]
multindeces = [i - mini for i in multindeces]
#
yield h
import psyco
def hamming(limit):
h = [1] * limit
x2, x3, x5 = 2, 3, 5
i = j = k = 0
for n in xrange(1, limit):
h[n] = min(x2, x3, x5)
if x2 == h[n]:
i += 1
x2 = 2 * h[i]
if x3 == h[n]:
j += 1
x3 = 3 * h[j]
if x5 == h[n]:
k += 1
x5 = 5 * h[k]
return h[-1]
psyco.bind(hamming)
print [hamming(i) for i in xrange(1, 21)]
print hamming(1691)
print hamming(1000000)
from heapq import heappush, heappop
from itertools import islice
def h():
heap = [1]
while True:
h = heappop(heap)
while heap and h==heap[0]:
heappop(heap)
for m in [2,3,5]:
heappush(heap, m*h)
yield h
print list(islice(h(), 20))
print list(islice(h(), 1690, 1691))
print list(islice(h(), 999999, 1000000)) # runtime 9.5 sec on i5-3570S
from itertools import tee, chain, groupby, islice
from heapq import merge
def raymonds_hamming():
# Generate "5-smooth" numbers, also called "Hamming numbers"
# or "Regular numbers". See: http://en.wikipedia.org/wiki/Regular_number
# Finds solutions to 2**i * 3**j * 5**k for some integers i, j, and k.
def deferred_output():
for i in output:
yield i
result, p2, p3, p5 = tee(deferred_output(), 4)
m2 = (2*x for x in p2) # multiples of 2
m3 = (3*x for x in p3) # multiples of 3
m5 = (5*x for x in p5) # multiples of 5
merged = merge(m2, m3, m5)
combined = chain([1], merged) # prepend a starting point
output = (k for k,g in groupby(combined)) # eliminate duplicates
return result
print list(islice(raymonds_hamming(), 20))
print islice(raymonds_hamming(), 1689, 1690).next()
print islice(raymonds_hamming(), 999999, 1000000).next()
from heapq import merge
from itertools import tee
def hamming_numbers():
last = 1
yield last
a,b,c = tee(hamming_numbers(), 3)
for n in merge((2*i for i in a), (3*i for i in b), (5*i for i in c)):
if n != last:
yield n
last = n
from itertools import islice, chain, tee
def merge(r, s):
# This is faster than heapq.merge.
rr = r.next()
ss = s.next()
while True:
if rr < ss:
yield rr
rr = r.next()
else:
yield ss
ss = s.next()
def p(n):
def gen():
x = n
while True:
yield x
x *= n
return gen()
def pp(n, s):
def gen():
for x in (merge(s, chain([n], (n * y for y in fb)))):
yield x
r, fb = tee(gen())
return r
def hamming(a, b = None):
if not b:
b = a + 1
seq = (chain([1], pp(5, pp(3, p(2)))))
return list(islice(seq, a - 1, b - 1))
print hamming(1, 21)
print hamming(1691)[0]
print hamming(1000000)[0]
You may also check:How to resolve the algorithm Bulls and cows step by step in the Scheme programming language
You may also check:How to resolve the algorithm Permutation test step by step in the FreeBASIC programming language
You may also check:How to resolve the algorithm Loops/Downward for step by step in the Lhogho programming language
You may also check:How to resolve the algorithm Empty program step by step in the Erlang programming language
You may also check:How to resolve the algorithm User input/Text step by step in the Plain English programming language