[英]Smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
What is wrong with my code?我的代码有什么问题? When i run the program nothing is printed.
当我运行程序时,没有打印任何内容。 I want to print the smallest 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
Brute forcing this is WAY too slow.强制执行此操作太慢了。 You need to find out what the prime factors of each number below 20 are, and then construct the smallest number that includes the same, and it will be the answer.
你需要找出每个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
Brute force:蛮力:
from itertools import count
for i in count(20):
if all(map(lambda x: i % x == 0, range(1, 21))):
print i
break
Non-brute-force:非蛮力:
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)
However, you don't have to check all numbers 1..20.但是,您不必检查所有数字 1..20。 If a number is divisible by 20, it is divisible by 2, 5, 10. Extending this, it would be sufficient to check only divisors from 11..20.
如果一个数能被 20 整除,它也能被 2、5、10 整除。扩展这个,只检查 11..20 的除数就足够了。 Another simple thing would be to increase the candidate solutions by 20 (
number += 20
) instead of 1, since any other number would not be divisible by 20.另一件简单的事情是将候选解增加 20(
number += 20
)而不是 1,因为任何其他数字都不能被 20 整除。
however, you are essentially looking for the least common multiple of the numbers from 1 to 20, and this can be done using prime factorization: You write each number in [1, 20] as multiple of primes, you take the largest exponential for each prime and then you multiply the results (try it manually to understand it).但是,您实际上是在寻找从 1 到 20 的数字的最小公倍数,这可以使用素数分解来完成:您将 [1, 20] 中的每个数字都写为素数的倍数,您对每个数取最大的指数素数,然后将结果相乘(手动尝试以了解它)。 In this way, the number you are looking for is 2^4 *3^2 * 5 * 7 * 11 * 13 * 17 * 19
这样你要找的数就是2^4 *3^2 * 5 * 7 * 11 * 13 * 17 * 19
My take (though I love @ondra solution for its elegancy):我的看法(尽管我喜欢 @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
Another clean and quick thing in Ruby 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 tried this method and it was more easier to understand我试过这个方法,比较容易理解
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)
But this can be done in milliseconds by finding the prime factors from 11 to 20 and multiplying them.但这可以通过找到 11 到 20 之间的质因数并将它们相乘,以毫秒为单位完成。
So it is Euler's problem #5.所以这是欧拉问题#5。 I've got that one:
我有那个:
#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.
And it is my first post/comment on StackOverflow.这是我在 StackOverflow 上的第一篇文章/评论。
if you think carefully the answer is LCM of the numbers from 1 to n.如果您仔细考虑,答案是从 1 到 n 的数字的 LCM。 here is the code in C++.
这是 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;
}
Simplest Solution using Python:使用 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.