![](/img/trans.png)
[英]Program to find the smallest number evenly divisible by all numbers from 1 to 20
[英]Smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
我的代码有什么问题? 当我运行程序时,没有打印任何内容。 我想打印可以被 1 到 20 的所有数字整除的最小数字。
found = False
i = 20
while found==False:
c = 0 # c checks if the number is the one im looking for
for x in range(1,21):
if i%x==0:
c = c + 1
if c==20: # if c = 20 then its the number im looking for
print i
found = True
i = i + 1
强制执行此操作太慢了。 你需要找出每个20以下的数的质因数是什么,然后构造包含相同数的最小数,这就是答案。
from collections import Counter
primes_below_20 = [2, 3, 5, 7, 11, 13, 17, 19]
def prime_factors(n):
# Assume n <= 20
if n == 1:
return []
for prime in primes_below_20:
if n % prime == 0:
return [prime] + prime_factors(n / prime)
primes_needed = Counter()
for n in range(2, 21):
primes = Counter(prime_factors(n))
primes_needed = primes_needed | primes # | gives the max of existing values
total = 1
for prime, amount in primes_needed.items():
total *= prime ** amount
print total
蛮力:
from itertools import count
for i in count(20):
if all(map(lambda x: i % x == 0, range(1, 21))):
print i
break
非蛮力:
from itertools import count, takewhile
def primes(n):
"Generate prime numbers up to n"
seen = list()
for i in xrange(2, n + 1):
if all(map(lambda prime: i % prime, seen)):
seen.append(i)
yield i
def smallest(n):
result = 1
for prime in primes(n):
bprime = max(takewhile(lambda x:x<=n, (prime ** c for c in count(1))))
# we could just take last instead of max()
result *= bprime
return result
print smallest(20)
def is_divisible(n):
for divisor in range(2, 21):
if n % divisor != 0:
return False
return True
number = 1
while not is_divisible(number):
number+=1
print(number)
但是,您不必检查所有数字 1..20。 如果一个数能被 20 整除,它也能被 2、5、10 整除。扩展这个,只检查 11..20 的除数就足够了。 另一件简单的事情是将候选解增加 20( number += 20
)而不是 1,因为任何其他数字都不能被 20 整除。
但是,您实际上是在寻找从 1 到 20 的数字的最小公倍数,这可以使用素数分解来完成:您将 [1, 20] 中的每个数字都写为素数的倍数,您对每个数取最大的指数素数,然后将结果相乘(手动尝试以了解它)。 这样你要找的数就是2^4 *3^2 * 5 * 7 * 11 * 13 * 17 * 19
我的看法(尽管我喜欢 @ondra 解决方案的优雅):
from collections import Counter, defaultdict
def primes(n):
return list(x for x in range(1,n+1)
if all(x%y for y in range(2,x)))
primes_20 = primes(20)
def prime_factors(n):
if n <= 0 or n < 20:
raise ValueError
factors = []
while n > 1:
for x in primes_20[1:]:
if not n % x:
n = n / x
factors.append(x)
break
return factors
max_count = defaultdict(int)
for i in range(2,21):
factors = prime_factors(i)
counts = Counter(factors)
for factor in counts:
max_count[factor] = max(max_count[factor], counts[factor])
total = 1
for factor, count in max_count.items():
total *= factor**count
assert any(total%x for x in range(2)) == False
print total
Ruby 中的另一个干净和快速的东西
def compute_lowest_dividing_number number
for i in 2..(number/2)
return i if number%i == 0
end
number
end
lcm = 1
n = 20
for i in 1..n
# look ahead appraoch
next_number = [i+1, n].min
lcm *= compute_lowest_dividing_number(next_number) if lcm % next_number != 0
end
puts lcm
我试过这个方法,比较容易理解
i=1
while True:
if i%11==0 and i%12==0 and i%13==0 and i%14==0 and i%15==0 and i%16==0 and i%17==0 and i%18==0 and i%19==0 and i%20==0:
break
else:
i+=1
print(i)
但这可以通过找到 11 到 20 之间的质因数并将它们相乘,以毫秒为单位完成。
所以这是欧拉问题#5。 我有那个:
#making loop for range of numbers
def rangeCount(number):
lst = [] #using lists to see divisions
for x in range(1, 21):
svalue = number % x
if svalue == 0:
lst.append(x)
else:
break #Need to break to minimize computation.
return lst
number = 2520 #is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. Minimazing compute
lstpst = [] #list pasted/returned from function
while len(lstpst) < 20:
lstpst = rangeCount(number)
print(f"With {number} we get {lstpst}")
number += 2 #even number must be the answer to the problem. Minimazing compute.
这是我在 StackOverflow 上的第一篇文章/评论。
如果您仔细考虑,答案是从 1 到 n 的数字的 LCM。 这是 C++ 中的代码。
#include <bits/stdc++.h>
#define IOS \
ios_base::sync_with_stdio(false); \
cin.tie(NULL);
#define ll long long int
using namespace std;
ll lcm(int n) {
ll ans = 1;
for (ll i = 1; i <= n; i++)
ans = (ans * i) / (__gcd(ans, i));
return ans;
}
int main() {
int i;
cin >> i;
cout << lcm(i);
return 0;
}
使用 Python 的最简单解决方案:
num = 21
while True:
div = 2
while num%div == 0 and div!=21:
div+=1
if div == 21:
print(num)
break
num+=1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.