问题描述:
A *Hamming number* is a positive integer of the form 2i3j5k, for some non-negative integers i, j, and k.
Write a function that computes the nth smallest Hamming number.
Specifically:
- The first smallest Hamming number is 1 = 203050
- The second smallest Hamming number is 2 = 213050
- The third smallest Hamming number is 3 = 203150
- The fourth smallest Hamming number is 4 = 223050
- The fifth smallest Hamming number is 5 = 203051
The 20 smallest Hamming numbers are given in example test fixture.
Your code should be able to compute all of the smallest 5,000 (Clojure: 2000) Hamming numbers without timing out.
代码实现:
#codewars第二十题(超时)
def hamming(n):
if n <= 6: return n
my_res = [1,2,3,4,5,6]
for i in range(6,n):
j = my_res[i-1] + 1
now_j = j
while j > 0:
if (j/2 == 1) or (j/3 == 1) or (j/5 == 1):
my_res.append(now_j)
break
elif j/2 != 1 and (j/2).is_integer():
j = j/2
elif j/3 != 1 and (j/3).is_integer():
j = j/3
elif j/5 != 1 and (j/5).is_integer():
j = j/5
else:
now_j += 1
j = now_j
return now_j
#另解
def hamming(limit):
h = [1] * limit
x2 = 2
x3 = 3
x5 = 5
i = j = k = 0
for n in range(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]
#另解
def hamming(n):
bases = [2, 3, 5]
expos = [0, 0, 0]
hamms = [1]
for _ in range(1, n):
next_hamms = [bases[i] * hamms[expos[i]] for i in range(3)]
next_hamm = min(next_hamms)
hamms.append(next_hamm)
for i in range(3):
expos[i] += int(next_hamms[i] == next_hamm)
return hamms[-1]
#判断浮点数是否为整数(两种方法)
(3/2).is_integer()
(2/2) - (int(2/2)) == 0
hamming(18)