python - 生成广义汉明数 Python
问题描述
这是我在给定限制下生成所有汉明数(又名 5-smooth-Numbers)的代码。https://en.wikipedia.org/wiki/Smooth_number
在数论中,光滑(或易碎)数是一个整数,它完全分解为小素数。例如,7 平滑数是质因数最多为 7 的数,因此 49 = 7^2 和 15750 = 2 × 32 × 53 × 7 都是 7 平滑数,而 11 和 702 = 2 × 33 × 13 不是
我知道生成数字的其他方法,但是我首先提出的功能对我来说很有意义,并且想知道如何将其扩展到 7-smooth、11-smooth、...、n-smooth-numbers。有没有更简单的方法来更改我的函数以循环低于限制的素数而不添加非常相似的代码行?
import math
def HammingFiveUnder(limit):
hammings = []
exp2 = int(math.log(limit, 2))
exp3 = int(math.log(limit, 3))
exp5 = int(math.log(limit, 5))
for i in range(0, exp2+1):
for j in range(0, exp3+1):
for k in range(0, exp5+1):
poss_ham = 2**i * 3**j * 5**k
if poss_ham <= limit:
hammings.append(poss_ham)
return sorted(hammings)
print(HammingFiveUnder(100))
解决方案
使用笛卡尔积itertool.product
函数的稍微不同的解决方案:
大致相当于生成器表达式中的嵌套 for 循环。例如,product(A, B) 返回与 ((x,y) for x in A for y in B) 相同的结果。
n_primes
是要按顺序排列的主要因素的数量。
from itertools import product as cartesianproduct # Cartesian product of input iterables.
from functools import reduce
import math
def prod(list_of_numbers):
''' Compute the product of the given numbers '''
return reduce(lambda x,y: x*y, list_of_numbers)
def smoothnumbers(n_primes=3, limit=100):
# List of the primes numbers:
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41]
# Compute the possible exponent ranges given the limit:
max_exponents = [math.floor(math.log(limit, prime))
for prime in primes[:n_primes]]
exponents_ranges = [range(max_exp+1) for max_exp in max_exponents]
# loop
smoothnumbers = []
for exponents in cartesianproduct(*exponents_ranges):
n = prod( factor**exp for factor, exp in zip(primes, exponents) )
# print(exponents, n)
if n <= limit:
smoothnumbers.append(n)
return sorted(smoothnumbers)
这使:
print( smoothnumbers(n_primes=2, limit=100) )
# [1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96]
print( smoothnumbers(n_primes=3, limit=100) )
# [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36,
# 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100]
print( smoothnumbers(n_primes=5, limit=100) )
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25,
# 27, 28, 30, 32, 33, 35, 36, 40, 42, 44, 45, 48, 49, 50, 54, 55, 56, 60, 63,
# 64, 66, 70, 72, 75, 77, 80, 81, 84, 88, 90, 96, 98, 99, 100]
推荐阅读
- typescript - Webpack 是原始模块大小的三倍多
- c++ - 有没有办法在 dlib 中反转一个复杂的矩阵?
- javascript - 数组 React 中的不同数据
- html - 将 FontAwesome 图标水平居中
- javascript - 在 Eventlisteners 中访问变量 - Vanilla JavaScript
- java - 在微调器中创建用于快速输入的搜索框
- firebase - Flutter 在两个类之间传递值
- r - 将 Rmd 文件编织为 pdf 时,bookdown 书籍链接中的主题标签将转换为 %23 并且不起作用
- sql - 通过 PostgreSQL 中的 json 列表求和
- node.js - 集成前端代码 (Netlify) 和后端代码 (heroku) (CORS) 的问题