From 6eef1de6f9ffd4b41f4194cc61798c6454369a77 Mon Sep 17 00:00:00 2001 From: pikatech Date: Wed, 10 May 2017 18:42:25 +0200 Subject: [PATCH 1/6] Create euler87.cpp C++-Version mit optimiertem Sieb. --- 87/euler87.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 87/euler87.cpp diff --git a/87/euler87.cpp b/87/euler87.cpp new file mode 100644 index 0000000..c2fd22d --- /dev/null +++ b/87/euler87.cpp @@ -0,0 +1,83 @@ +// C++-Lösung auf der Basis der C-Variante von Jörg Sommer +// Beinhaltet verbessertes Primzahlsieb + +#include +#include +#include +#include +#include + +/** + prime: Vektor zum Speichern der Primzahlen + limit: Obere Grenze des Bereichs in dem berechnet wird + + Implementiert eine optimierte Version des Sieb des Eratosthenes. + Prüft nicht, ob die Grenze kleiner als 5 ist. +*/ +static void sieve(std::vector& prime, unsigned const limit) { + prime.push_back(2u); + prime.push_back(3u); + + for (unsigned num = 5; num <= limit; num += 2) { + unsigned sqrtnum = (unsigned) std::sqrt(num); + bool isPrime = true; + for (auto primeIt = ++prime.begin(); primeIt != prime.end() && *primeIt <= sqrtnum; ++primeIt) { + if (num % *primeIt == 0) { + isPrime = false; + break; + } + } + if (isPrime) { + prime.push_back(num); + } + } + +} + +int main(void) { + constexpr unsigned LIMIT = 50000000; + constexpr unsigned PRIMELIMIT = (unsigned) std::sqrt(LIMIT); + std::vector primes; + primes.reserve(PRIMELIMIT / std::log(PRIMELIMIT)); // schätze Primzahldichte + + sieve(primes, PRIMELIMIT); + std::cout << "Es wurden " << primes.size() << " Primzahlen gefunden" << std::endl; + + std::vector numbers; + for (auto p4 = primes.begin(); p4 != primes.end(); ++p4) { + unsigned pow4 = *p4 * *p4; + pow4 *= pow4; + if (pow4 >= LIMIT) + break; + + for (auto p3 = primes.begin(); p3 != primes.end(); ++p3) { + unsigned sum = pow4 + *p3 * *p3 * *p3; + if (sum >= LIMIT) + break; + + for (auto p2 = primes.begin(); p2 != primes.end(); ++p2) { + unsigned pow2 = *p2 * *p2; + + unsigned sum2 = sum + pow2; + if (sum2 >= LIMIT) { + break; + } + + numbers.push_back(sum2); + } + } + } + + //Zähle vorkommende Elemente + unsigned count = 1; + std::sort(numbers.begin(), numbers.end()); + for (auto n = ++numbers.begin(); n != numbers.end(); ++n) { + if (*(n - 1) != *n) { + ++count; + } + } + + std::cout << "Ergebnis: " << count << std::endl; + + return EXIT_SUCCESS; +} From b13d9fd45364cfe884ea8a7b5dd304b4e7d80087 Mon Sep 17 00:00:00 2001 From: pikatech Date: Wed, 10 May 2017 18:47:45 +0200 Subject: [PATCH 2/6] Add files via upload Two solutions. One simple and one faster. --- 87/euler87.R | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 87/euler87.R diff --git a/87/euler87.R b/87/euler87.R new file mode 100644 index 0000000..d10153d --- /dev/null +++ b/87/euler87.R @@ -0,0 +1,48 @@ +library(numbers) +library(microbenchmark) + +#### +# limit: Obere Grenze für die Summe der Primzahltripel +# +# Gibt die Anzahl der einmaligen Primzahltripel +# bis zu einer oberen Grenze zurück. +#### +simple87 <- function(limit) { + primes <- Primes(1, ceiling(limit^(1/2))) + + x2 <- primes^2 + x3 <- primes^3 + x4 <- primes^4 + x2 <- x2[x2 < limit] + x3 <- x3[x3 < limit] + x4 <- x4[x4 < limit] + + x <- expand.grid(x2, x3, x4) + xSums <- rowSums(x) + length(unique(xSums[xSums < limit])) +} + +# Wir erzeugen die Kombinationen selbst und +# generieren eine Matrix über cbind() +# Dadurch spart man sich die matrix <-> data.frame Konvertierung +faster87<-function(limit) { + primes <- Primes(1, ceiling(sqrt(limit))) + + x2 <- primes^2 + x3 <- primes^3 + x4 <- primes^4 + x2 <- x2[x2 < limit] + x3 <- x3[x3 < limit] + x4 <- x4[x4 < limit] + + x <- cbind(rep(x2, each=length(x3)*length(x4)), + rep(x3, times=length(x2)*length(x4)), + rep(x4, times=length(x2)*length(x3)) + ) + + xSums <- rowSums(x) + length(unique(xSums[xSums < limit])) +} + +ress <- microbenchmark(simple87(5e7), faster87(5e7), times=500L) + From e7ee3570a1fd6701ce2d158003c224458e152437 Mon Sep 17 00:00:00 2001 From: pikatech Date: Mon, 22 May 2017 20:39:38 +0200 Subject: [PATCH 3/6] C++ solution of problem 35. --- 35/euler35.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 35/euler35.cpp diff --git a/35/euler35.cpp b/35/euler35.cpp new file mode 100644 index 0000000..2057961 --- /dev/null +++ b/35/euler35.cpp @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +void sieve(std::vector& primes, int const limit) { + if (limit < 2) { + return; + } else if (limit < 3) { + primes.push_back(2); + return; + } + primes.push_back(2); + primes.push_back(3); + + for (int num = 5; num <= limit; num += 2) { + int sqrtnum = (int) std::sqrt(num); + bool isPrime = true; + for (auto primeIt = ++primes.begin(); primeIt != primes.end() && *primeIt <= sqrtnum; ++primeIt) { + if (num % *primeIt == 0) { + isPrime = false; + break; + } + } + if (isPrime) { + primes.push_back(num); + } + } +} + +int main(void) { + constexpr int limit = 1000000; + constexpr int PRIMELIMIT = limit - 1; + std::vector primes; + sieve(primes, PRIMELIMIT); + + std::vector circular; + auto primeIt = primes.begin(); + while (*primeIt < 10) { + circular.push_back(*primeIt); + ++primeIt; + } + int tens = 10; + int nextTens = 100; + int rotations = 2; + + while (primeIt != primes.end()) { + if (*primeIt >= nextTens) { + tens *= 10; + nextTens *= 10; + ++rotations; + } + + bool isCircular = true; + int prime = *primeIt; + for (int i = 1; i < rotations; ++i) { + prime = prime / 10 + (prime % 10) * tens; + isCircular = std::binary_search(primes.begin(), primes.end(), prime)? true: false; + if (!isCircular) { + break; + } + } + if (isCircular) { + circular.push_back(*primeIt); + } + ++primeIt; + } + + std::cout << circular.size() << std::endl; +} From 2700d8cae9fa8541e492d6c4b28d7208cf1f7863 Mon Sep 17 00:00:00 2001 From: pikatech Date: Mon, 22 May 2017 20:54:10 +0200 Subject: [PATCH 4/6] Almost a one-liner as solution. --- 10/euler10.R | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 10/euler10.R diff --git a/10/euler10.R b/10/euler10.R new file mode 100644 index 0000000..d2a85b1 --- /dev/null +++ b/10/euler10.R @@ -0,0 +1,2 @@ +library(numbers) +sum(as.numeric(Primes(1L, 2000000L))) From a7fb4daffccbf7576674e7755675d6069148ad31 Mon Sep 17 00:00:00 2001 From: pikatech Date: Mon, 22 May 2017 20:57:36 +0200 Subject: [PATCH 5/6] Short C++ solution thanks to Bignum library support. --- 10/euler10.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 10/euler10.cpp diff --git a/10/euler10.cpp b/10/euler10.cpp new file mode 100644 index 0000000..5d9f076 --- /dev/null +++ b/10/euler10.cpp @@ -0,0 +1,48 @@ +// This solution needs the GNU MP Bignum library +// g++ euler10.cpp -o euler10 -lgmpxx -lgmp + +#include +#include +#include +#include + +void sieve(std::vector& primes, int const limit) { + if (limit < 2) { + return; + } else if (limit < 3) { + primes.push_back(2); + return; + } + primes.push_back(2); + primes.push_back(3); + + for (int num = 5; num <= limit; num += 2) { + int sqrtnum = (int) std::sqrt(num); + bool isPrime = true; + for (auto primeIt = ++primes.begin(); primeIt != primes.end() && *primeIt <= sqrtnum; ++primeIt) { + if (num % *primeIt == 0) { + isPrime = false; + break; + } + } + if (isPrime) { + primes.push_back(num); + } + } +} + +int main(void) { + constexpr int limit = 2000000; + constexpr int PRIMELIMIT = limit - 1; + std::vector primes; + sieve(primes, PRIMELIMIT); + + mpz_class sum = 0; + + for (auto primeIt = primes.begin(); primeIt != primes.end(); ++primeIt) { + sum += *primeIt; + } + + std::cout << sum << std::endl; + return EXIT_SUCCESS; +} From 6c26f6f8f4b9e439b5c3467baa5f92cb90a786e1 Mon Sep 17 00:00:00 2001 From: pikatech Date: Mon, 22 May 2017 21:19:59 +0200 Subject: [PATCH 6/6] Another solution using Bignum support. --- 16/euler16.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 16/euler16.cpp diff --git a/16/euler16.cpp b/16/euler16.cpp new file mode 100644 index 0000000..6860db0 --- /dev/null +++ b/16/euler16.cpp @@ -0,0 +1,26 @@ +// This solution needs the GNU MP Bignum library +// g++ euler16.cpp -o euler16 -lgmpxx -lgmp + +#include +#include +#include +#include + +int main(void) { + mpz_class power = 1; + mpz_class modulo = 0; + mpz_class tens = 10; + mpz_class digitsum = 0; + + for (int i = 1; i <= 1000; ++i) { + power *= 2; + } + + while (power != 0) { + digitsum = digitsum + power % tens; + power = power / 10; + } + + std::cout << digitsum << std::endl; + return EXIT_SUCCESS; +}