Two solutions for Goldbach's conjecture and their complexity.
This commit is contained in:
@@ -3,68 +3,94 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
using namespace std;
|
/*
|
||||||
|
Given an even number ( greater than 2 ), return two prime numbers whose
|
||||||
|
sum will be equal to given number.
|
||||||
|
|
||||||
static std::vector<int> GetPrimes(const size_t n) {
|
NOTE A solution will always exist. read Goldbach’s conjecture
|
||||||
std::vector<int> primes;
|
|
||||||
std::vector<int> lp(n + 1, 0);
|
|
||||||
|
|
||||||
for (auto i = 2u; i <= n; ++i) {
|
Example:
|
||||||
if (lp[i] == 0) {
|
|
||||||
lp[i] = i;
|
|
||||||
primes.push_back(i);
|
Input : 4
|
||||||
|
Output: 2 + 2 = 4
|
||||||
|
|
||||||
|
If there are more than one solutions possible, return the lexicographically
|
||||||
|
smaller solution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* My understanding is:
|
||||||
|
* The first solution time complexity is O(n^2/log_n) + O(n) memory complexity.
|
||||||
|
* The second solution id O(n^2) complexity + O(0) memory complexity.
|
||||||
|
*/
|
||||||
|
#define SOLUTION 1
|
||||||
|
|
||||||
|
#if SOLUTION == 1
|
||||||
|
|
||||||
|
std::vector<size_t> primes;
|
||||||
|
std::unordered_set<size_t> primes_set;
|
||||||
|
|
||||||
|
void init_primes(const size_t n)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<bool> prime_table(n/2+1, true); // Only odd numbers.
|
||||||
|
primes.push_back(2);
|
||||||
|
|
||||||
|
for (auto p = 3; p <= n; p+=2) {
|
||||||
|
if ( prime_table[p/2] ) {
|
||||||
|
primes.push_back(p);
|
||||||
|
for ( int j = p*3; j <= n; j+=p*2 ) {
|
||||||
|
prime_table[j/2] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (auto j = 0u; j < primes.size() && primes[j] <= lp[i] && i * primes[j] <= n; ++j)
|
|
||||||
lp[i * primes[j]] = primes[j];
|
|
||||||
}
|
|
||||||
return primes;
|
|
||||||
|
|
||||||
|
primes_set.insert(primes.begin(), primes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_prime( int n, const vector<int>& primes ){
|
std::vector<int> primesum(int A)
|
||||||
int sqrt_n = floor(sqrt(double(n)));
|
{
|
||||||
for ( int i = 0; i < primes.size() && primes[i] <= sqrt_n; ++i ){
|
for ( int p : primes ){
|
||||||
if ( n % primes[i] == 0 ) {
|
if ( primes_set.find(A-p) != primes_set.end() ) {
|
||||||
|
return {p, A-p};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif SOLUTION == 2
|
||||||
|
|
||||||
|
bool is_prime(int a)
|
||||||
|
{
|
||||||
|
if ( a <2 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int end = std::floor(std::sqrt(a));
|
||||||
|
for ( int i = 2; i <= end; ++i ){
|
||||||
|
if ( a % i == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<int> primesum(int A) {
|
std::vector<int> primesum(int A)
|
||||||
|
{
|
||||||
|
|
||||||
vector<int> primes;
|
for ( int i = 2; i < A; ++i) {
|
||||||
|
if ( is_prime(i) && is_prime(A-i) ){
|
||||||
#if 0
|
return {i,A-i};
|
||||||
for ( int i = 2; i < A; ++i){
|
|
||||||
if ( is_prime(i,primes) ){
|
|
||||||
primes.push_back(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
primes = GetPrimes(A);
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
unordered_set<int> primes_set(primes.begin(),primes.end());
|
|
||||||
for ( int i = 0; i < primes.size(); ++i ){
|
|
||||||
if ( primes_set.find(A-primes[i]) != primes_set.end() ) {
|
|
||||||
return {primes[i], A-primes[i]};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for ( int i = 0; i < primes.size(); ++i ) {
|
|
||||||
auto it = std::lower_bound(primes.begin(), primes.end(), A - primes[i]);
|
|
||||||
if ( it != primes.end() && *it == A-primes[i] ) {
|
|
||||||
return {primes[i], A-primes[i]};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void solve_and_print(int A){
|
void solve_and_print(int A){
|
||||||
auto r = primesum(A);
|
auto r = primesum(A);
|
||||||
std::cout << r[0] << ' ' << r[1] << std::endl;
|
std::cout << r[0] << ' ' << r[1] << std::endl;
|
||||||
@@ -72,8 +98,23 @@ void solve_and_print(int A){
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
auto begin = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
#if SOLUTION == 1
|
||||||
|
init_primes(16777218);
|
||||||
|
#endif
|
||||||
|
|
||||||
solve_and_print(4);
|
solve_and_print(4);
|
||||||
solve_and_print(10);
|
solve_and_print(10);
|
||||||
|
|
||||||
solve_and_print(16777214);
|
solve_and_print(16777214);
|
||||||
|
solve_and_print(16777218);
|
||||||
|
|
||||||
|
for ( int i = 4; i < 1000000; i+=2 ){
|
||||||
|
primesum(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
|
std::chrono::duration<double> seconds = end - begin;
|
||||||
|
std::cout << "Time: " << seconds.count() << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user