오일러는 다음과 같은 멋진 2차식을 제시했습니다.
n2 + n + 41
이 식의 n에다 0부터 39 사이의 숫자를 넣으면, 그 결과는 모두 소수가 됩니다.
하지만 n = 40일 때의 값 402 + 40 + 41 은 40×(40 + 1) + 41 이므로 41로 나누어지고, n = 41일 때 역시 412 + 41 + 41 이므로 소수가 아닙니다.
컴퓨터의 발전에 힘입어 n2 − 79n + 1601 이라는 엄청난 2차식이 발견되었는데, 이것은 n이 0에서 79 사이일 때 모두 80개의 소수를 만들어냅니다. 이 식의 계수의 곱은 -79 × 1601 = -126479가 됩니다.
아래와 같은 모양의 2차식이 있다고 가정했을 때,
n2 + an + b (단 | a | < 1000, | b | < 1000)
0부터 시작하는 연속된 n에 대해 가장 많은 소수를 만들어내는 2차식을 찾아서, 그 계수 a와 b의 곱을 구하세요.
위 식을 사용하면
b가 소수, a+b+1이 소수여야 한다는 사실을 알 수 있다.
이를 활용하여 brute-force..
Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def isPrime(n): | |
# http://www.daniweb.com/software-development/python/code/216880 | |
'''check if integer n is a prime''' | |
# make sure n is a positive integer | |
n = abs(int(n)) | |
# 0 and 1 are not primes | |
if n < 2: | |
return False | |
# 2 is the only even prime number | |
if n == 2: | |
return True | |
# all other even numbers are not primes | |
if not n & 1: | |
return False | |
# range starts with 3 and only needs to go up the squareroot of n | |
# for all odd numbers | |
for x in range(3, int(n**0.5)+1, 2): | |
if n % x == 0: | |
return False | |
return True | |
def getResult(a,b,n): | |
r = n**2 + (a*n) + b | |
return r | |
max_n = 0 | |
max_a = 0 | |
max_b = 0 | |
for a in range(-999, 1000): | |
for b in range(-999, 1000): | |
n = 0 | |
while True: | |
if isPrime(a+b+1) and isPrime(b): | |
r = getResult(a,b,n) | |
if isPrime(r): | |
n+=1 | |
else: | |
break | |
else: | |
break | |
if n > max_n: | |
print ("a : {0}, b : {1}, n : {2}".format(a,b,n)) | |
max_n = n | |
max_a = a | |
max_b = b | |
print (max_a * max_b) |
Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'mathn' | |
def isPrime(n) | |
return n.prime? | |
end | |
def getResult(a,b,n) | |
r = n**2 + (a*n) + b | |
return r | |
end | |
max_n = 0 | |
max_a = 0 | |
max_b = 0 | |
(-999..999).each do | |
|a| | |
(-999..999).each do | |
|b| | |
n = 0 | |
while (true) | |
if (isPrime(a+b+1) and isPrime(b)) | |
r = getResult(a,b,n) | |
if (isPrime(r)) | |
n+=1 | |
else | |
break | |
end | |
else | |
break | |
end | |
end | |
if (n > max_n) | |
puts "a : #{a}, b : #{b}, n : #{n}" | |
max_n = n | |
max_a = a | |
max_b = b | |
end | |
end | |
end | |
puts max_a*max_b |
Allen님의 풀이와 코드.
n=0일 때를 고려하면, b는 1~1000구간의 소수여야함. b=2라면 n=2에서 전체가 2의 배수가 되므로 b != 2 b가2가아닌 소수라면 홀수이고, n=1에서 a가 홀수여야 전체가 홀수가 됨 따라서, 홀수인 a만 찾아보면 됨.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'mathn' | |
def prime_count(a,b) | |
n = 0 | |
n += 1 while (n*n + a*n + b).prime? | |
n | |
end | |
max,ma,mb = 1,nil,nil | |
Prime.each(1000) do |b| | |
(-999..999).step(2) do |a| | |
max,ma,mb = prime_count(a,b),a,b if prime_count(a,b) > max | |
end | |
end | |
puts ma*mb |
Perl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
sub isPrime | |
{ | |
my ($number) = @_; | |
$number = abs $number; | |
my $sqrt = sqrt $number; | |
my $d = 2; | |
while (1) | |
{ | |
return 0 if ( $number % $d == 0 ); | |
return 1 if ( $d > $sqrt ); | |
$d++; | |
} | |
} | |
my $max_a = 0; | |
my $max_n = 0; | |
my $max_b = 0; | |
foreach my $a ((-999..999)) { | |
foreach my $b ((-999..999)) { | |
my $n = 0; | |
while(1) { | |
my $r = ($n**2) + ($n*$a) + $b; | |
if(isPrime($r)) { | |
$n+=1; | |
} else { | |
last; | |
} | |
} | |
if( $n > $max_n) { | |
print "a : $a, b : $b, n : $n \n"; | |
$max_n = $n; | |
$max_a = $a; | |
$max_b = $b; | |
} | |
} | |
} | |
print "{($max_a*$max_b)}"; |