From 71c92f4c5379fdf15423f556c6adc2e7b66a2d14 Mon Sep 17 00:00:00 2001 From: Olivia Appleton Date: Tue, 3 Sep 2024 18:16:46 -0500 Subject: [PATCH] Convert rust prime generator to C++, solve p7 (untested) --- README.rst | 2 +- cplusplus/README.rst | 1 + cplusplus/src/include/primes.cpp | 73 +++++++++++++++++++++++++++++++ cplusplus/src/p0007.cpp | 37 ++++++++++++++++ docs/index.rst | 2 +- docs/src/cplusplus/lib/primes.rst | 43 ++++++++++++++++++ docs/src/cplusplus/p0007.rst | 31 +++++++++++++ 7 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 cplusplus/src/include/primes.cpp create mode 100644 cplusplus/src/p0007.cpp create mode 100644 docs/src/cplusplus/lib/primes.rst create mode 100644 docs/src/cplusplus/p0007.rst diff --git a/README.rst b/README.rst index 161ca84b..2d3ed959 100644 --- a/README.rst +++ b/README.rst @@ -63,7 +63,7 @@ Olivia's Project Euler Solutions | | C11+ in: |msvc| [1]_ | | |CodeQL| |br| | | | |br| Browser [2]_ | | |C-lint| | +------------+----------------------------+--------+-------------------+ -| C++ | C++98+ in: |br| |clang|, & | 18 | |Cpi| |br| | +| C++ | C++98+ in: |br| |clang|, & | 19 | |Cpi| |br| | | | |gcc| |br| | | |Cp-Cov| |br| | | | C++14+ in: |msvc| [1]_ | | |CodeQL| |br| | | | |br| Browser [3]_ | | |Cp-lint| | diff --git a/cplusplus/README.rst b/cplusplus/README.rst index 6a2013c5..7776f70d 100644 --- a/cplusplus/README.rst +++ b/cplusplus/README.rst @@ -169,6 +169,7 @@ Problems Solved - ☒ `2 <./src/p0002.cpp>`__ - ☒ `4 <./src/p0004.cpp>`__ - ☒ `6 <./src/p0006.cpp>`__ +- ☒ `7 <./src/p0007.cpp>`__ - ☒ `8 <./src/p0008.cpp>`__ - ☒ `9 <./src/p0009.cpp>`__ - ☒ `11 <./src/p0011.cpp>`__ diff --git a/cplusplus/src/include/primes.cpp b/cplusplus/src/include/primes.cpp new file mode 100644 index 00000000..80ee11c7 --- /dev/null +++ b/cplusplus/src/include/primes.cpp @@ -0,0 +1,73 @@ +#pragma once + +#include +#include +#include +#include + +template +class PrimeGenerator { +public: + PrimeGenerator() + : prime(T(0)), candidate(T(1) + T(1)), has_limit(false), limit(std::numeric_limits::max()) {} + + PrimeGenerator(T upper_limit) + : prime(T(0)), candidate(T(1) + T(1)), has_limit(true), limit(upper_limit) {} + + T next() { + if (has_limit && prime >= limit) { + map.clear(); + return T(-1); + } + prime = next_prime(candidate); + candidate = prime + T(1); + return prime; + } + + bool has_next() const { + return !has_limit || prime < limit; + } + +private: + std::map > sieve; + T prime; + T candidate; + bool has_limit; + T limit; + + T next_prime(T candidate) { + typename std::map >::iterator it = sieve.find(candidate); + if (it != sieve.end()) { + const std::vector& numbers = it->second; + for (typename std::vector::const_iterator num = numbers.begin(); num != numbers.end(); ++num) { + const T num_val = *num; + typename std::map >::iterator entry_it = sieve.find(candidate + num_val); + if (entry_it != sieve.end()) + entry_it->second.push_back(num_val); + else { + std::vector new_vec; + new_vec.push_back(num_val); + sieve[candidate + num_val] = new_vec; + } + } + sieve.erase(candidate); + return next_prime(candidate + T(1)); + } + else { + std::vector vec; + vec.push_back(candidate); + sieve[candidate * candidate] = vec; + return candidate; + } + } +}; + +template +PrimeGenerator primes() { + return PrimeGenerator(); +} + +template +PrimeGenerator primes_until(T x) { + return PrimeGenerator(x); +} diff --git a/cplusplus/src/p0007.cpp b/cplusplus/src/p0007.cpp new file mode 100644 index 00000000..dd2a0db4 --- /dev/null +++ b/cplusplus/src/p0007.cpp @@ -0,0 +1,37 @@ +/* +Project Euler Problem 7 + +The prime number infrastructure paid off here + +Problem: + +By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. + +What is the 10 001st prime number? +*/ + +#ifndef EULER_P0007 +#define EULER_P0007 +#include +#include +#include "include/macros.hpp" +#include "include/primes.hpp" + +uint32_t EMSCRIPTEN_KEEPALIVE p0007() { + uint32_t answer, count = 0; + PrimeGenerator ps = primes(); + while (true) { + answer = ps.next(); + if (++count == 10001) + break; + } + return answer; +} + +#ifndef UNITY_END +int main(int argc, char const *argv[]) { + std::cout << p0007() << std::endl; + return 0; +} +#endif +#endif diff --git a/docs/index.rst b/docs/index.rst index 1a663fa9..6f04c473 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -88,7 +88,7 @@ Problems Solved +-----------+------------+------------+------------+------------+------------+------------+------------+ |:prob:`6` |:c-d:`0006` |:cp-d:`0006`|:cs-d:`0006`|:ja-d:`0006`|:js-d:`0006`|:py-d:`0006`|:rs-d:`0006`| +-----------+------------+------------+------------+------------+------------+------------+------------+ -|:prob:`7` |:c-d:`0007` | |:cs-d:`0007`| |:js-d:`0007`|:py-d:`0007`|:rs-d:`0007`| +|:prob:`7` |:c-d:`0007` |:cp-d:`0007`|:cs-d:`0007`| |:js-d:`0007`|:py-d:`0007`|:rs-d:`0007`| +-----------+------------+------------+------------+------------+------------+------------+------------+ |:prob:`8` |:c-d:`0008` |:cp-d:`0008`|:cs-d:`0008`|:ja-d:`0008`|:js-d:`0008`|:py-d:`0008`|:rs-d:`0008`| +-----------+------------+------------+------------+------------+------------+------------+------------+ diff --git a/docs/src/cplusplus/lib/primes.rst b/docs/src/cplusplus/lib/primes.rst new file mode 100644 index 00000000..70624e01 --- /dev/null +++ b/docs/src/cplusplus/lib/primes.rst @@ -0,0 +1,43 @@ +primes.hpp +========== + +View source code :source:`cplusplus/src/include/primes.hpp` + +Includes +-------- + +- :external:cpp:type:`iostream` +- :external:cpp:type:`vector` +- :external:cpp:type:`map` +- :external:cpp:type:`limits` + +.. cpp:namespace-push:: primes + +.. cpp:class:: PrimeGenerator + + .. cpp:function:: PrimeGenerator PrimeGenerator() + .. cpp:function:: PrimeGenerator primes() + + These constructors will return an infinite generator of prime numbers. Note, however, that it does not guard + against overflow, so choose your type carefully. + + .. cpp:function:: PrimeGenerator PrimeGenerator(T upper_limit) + .. cpp:function:: PrimeGenerator primes_until(T upper_limit) + + These constructors will return a finite generator of prime numbers, going to ``upper_limit``. + + .. cpp:function:: bool next() + + Returns the next prime, or ``-1`` if it is above the defined limit. + + .. cpp:function:: bool has_next() + + Returns ``true`` if there is a next value to generate. + +.. cpp:namespace-pop:: + +.. literalinclude:: ../../../../cplusplus/src/include/primes.hpp + :language: C++ + :linenos: + +.. tags:: cpp-iterator, prime-number diff --git a/docs/src/cplusplus/p0007.rst b/docs/src/cplusplus/p0007.rst new file mode 100644 index 00000000..b046f2f1 --- /dev/null +++ b/docs/src/cplusplus/p0007.rst @@ -0,0 +1,31 @@ +C++ Implementation of Problem 7 +=============================== + +View source code :source:`cplusplus/src/p0007.cpp` + +Includes +-------- + +- `"macros.hpp" <./lib/macros.html>`__ +- `"primes.hpp" <./lib/primes.html>`__ +- :external:c:type:`stdint` +- :external:cpp:type:`iostream` + +Solution +-------- + +.. cpp:namespace-push:: p0007 + +.. cpp:function:: uint32_t p0007() + +.. cpp:function:: int main(int argc, char const *argv[]) + + .. note:: + + This function is only present in the Python test runner, or when compiling as a standalone program. + +.. literalinclude:: ../../../cplusplus/src/p0007.cpp + :language: C++ + :linenos: + +.. tags:: cpp-iterator, prime-number