From 12618477671c3f706b8ebe43c50f71dfc35f4167 Mon Sep 17 00:00:00 2001 From: Honey Ranjan 12219884 <119494046+honeyranjan1@users.noreply.github.com> Date: Thu, 27 Mar 2025 11:05:53 +0530 Subject: [PATCH] Update euler-0035.cpp Enhanced the logic for detecting circular primes by: - Using the Sieve of Eratosthenes for efficient prime number generation. - Optimized rotation handling with `std::rotate` for clarity and efficiency. - Simplified main loop to focus on checking circular primes. --- euler-0035.cpp | 115 ++++++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 64 deletions(-) diff --git a/euler-0035.cpp b/euler-0035.cpp index ea98019..17d2a3d 100644 --- a/euler-0035.cpp +++ b/euler-0035.cpp @@ -43,80 +43,67 @@ // We have to find the sum of all such prime numbers, not their count. #include +#include +#include #include +#include +#include // Include this header for std::rotate -int main() -{ - // highest number (1000000 in original problem) - unsigned int n; - std::cin >> n; +// Function to generate all primes up to n using Sieve of Eratosthenes +std::set generatePrimes(unsigned int n) { + std::vector isPrime(n + 1, true); + isPrime[0] = isPrime[1] = false; - // precomputation: find all prime numbers up to n - std::set primes; - primes.insert(2); - for (unsigned int i = 3; i <= n; i += 2) - { - bool isPrime = true; + for (unsigned int i = 2; i * i <= n; i++) { + if (isPrime[i]) { + for (unsigned int j = i * i; j <= n; j += i) { + isPrime[j] = false; + } + } + } + + std::set primes; + for (unsigned int i = 2; i <= n; i++) { + if (isPrime[i]) { + primes.insert(i); + } + } + return primes; +} - // test against all prime numbers we have so far (in ascending order) - for (auto x : primes) - { - // divisible => not prime - if (i % x == 0) - { - isPrime = false; - break; - } +// Function to check if all rotations of a number are prime +bool isCircularPrime(unsigned int num, const std::set& primes) { + std::string s = std::to_string(num); + unsigned int len = s.length(); - // prime is too large to be a divisor - if (x*x > i) - break; + for (unsigned int i = 0; i < len; i++) { + std::rotate(s.begin(), s.begin() + 1, s.end()); // Rotate the digits + if (primes.find(std::stoi(s)) == primes.end()) { + return false; // Rotation is not prime + } } + return true; +} - // yes, we have a prime - if (isPrime) - primes.insert(i); - } +int main() { + // Read the upper limit + unsigned int n; + std::cin >> n; - // now look at all primes - unsigned int sum = 0; - for (auto x : primes) - { - // move the right-most digit to the front of the number - // we need to know the "position" of the front-most digit: - // shift will be 1 for x = 1..9 - // shift will be 10 for x = 10..99 - // shift will be 100 for x = 100..999 and so on - unsigned int shift = 1; - while (x > shift * 10) - shift *= 10; + // Generate primes up to n + std::set primes = generatePrimes(n); - auto rotated = x; - do - { - // take right-most digit - auto digit = rotated % 10; - // remove it - rotated /= 10; - // and prepend it - rotated += digit * shift; + unsigned int sum = 0; - // rotated number not prime ? - if (primes.count(rotated) == 0) - break; - } while (rotated != x); // finished the circle ? (we have the initial number again) + // Check for circular primes + for (auto prime : primes) { + if (isCircularPrime(prime, primes)) { + sum += prime; + } + } - // all rotations succeeded ? -#define ORIGINAL -#ifdef ORIGINAL - if (rotated == x) - sum++; -#else - if (rotated == x) - sum += x; -#endif - } + // Output the sum of circular primes + std::cout << sum << std::endl; - std::cout << sum << std::endl; - return 0; + return 0; }