Skip to content

Commit

Permalink
Convert rust prime generator to C++, solve p7 (untested)
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Sep 3, 2024
1 parent 28940dd commit 0e7edeb
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 13 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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| |
Expand Down
2 changes: 1 addition & 1 deletion c/src/p0025.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ uint64_t EMSCRIPTEN_KEEPALIVE p0025() {
iadd_bcd(&a, b);
swap(a, b);
answer++;
} while (b.decimal_digits < 1000)
} while (b.decimal_digits < 1000);
free_BCD_int(a);
free_BCD_int(b);
return answer;
Expand Down
1 change: 1 addition & 0 deletions cplusplus/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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>`__
Expand Down
73 changes: 73 additions & 0 deletions cplusplus/src/include/primes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#pragma once

#include <iostream>
#include <vector>
#include <map>
#include <limits>

template<typename T>
class PrimeGenerator {
public:
PrimeGenerator()
: prime(T(0)), candidate(T(1) + T(1)), has_limit(false), limit(std::numeric_limits<T>::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<T, std::vector<T> > sieve;
T prime;
T candidate;
bool has_limit;
T limit;

T next_prime(T candidate) {
typename std::map<T, std::vector<T> >::iterator it = sieve.find(candidate);
if (it != sieve.end()) {
const std::vector<T>& numbers = it->second;
for (typename std::vector<T>::const_iterator num = numbers.begin(); num != numbers.end(); ++num) {
const T num_val = *num;
typename std::map<T, std::vector<T> >::iterator entry_it = sieve.find(candidate + num_val);
if (entry_it != sieve.end())
entry_it->second.push_back(num_val);
else {
std::vector<T> 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<T> vec;
vec.push_back(candidate);
sieve[candidate * candidate] = vec;
return candidate;
}
}
};

template<typename T>
PrimeGenerator<T> primes() {
return PrimeGenerator<T>();
}

template<typename T>
PrimeGenerator<T> primes_until(T x) {
return PrimeGenerator<T>(x);
}
16 changes: 10 additions & 6 deletions cplusplus/src/p0002.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ four million, find the sum of the even-valued terms.
uint64_t EMSCRIPTEN_KEEPALIVE p0002() {
uint64_t answer = 0,
a = 1, b = 2, t;
do {
while (b < 4000000) {
// odd (1, 3, 13, 55, ...)
// odd (1, 5, 21, 89, ...)
// even (2, 8, 34, 144, ...)
answer += b;
// see python fibonacci file for proof this works
t = b;
b = a + b * 4;
a = t;
} while (b < 4000000);
for (uint8_t z = 0; z < 3; z++) {
t = b;
b = a + b;
a = t;
}
}
return answer;
}

Expand Down
37 changes: 37 additions & 0 deletions cplusplus/src/p0007.cpp
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>
#include <iostream>
#include "include/macros.hpp"
#include "include/primes.hpp"

uint32_t EMSCRIPTEN_KEEPALIVE p0007() {
uint32_t answer, count = 0;
PrimeGenerator<uint32_t> 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
4 changes: 1 addition & 3 deletions cplusplus/test_euler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
1,
2,
4,
6,
8,
9,
*range(6, 10),
11,
*range(13, 18),
*range(19, 21),
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
Expand Down
43 changes: 43 additions & 0 deletions docs/src/cplusplus/lib/primes.rst
Original file line number Diff line number Diff line change
@@ -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<T> PrimeGenerator<T>()
.. cpp:function:: PrimeGenerator<T> primes<T>()

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<T> PrimeGenerator<T>(T upper_limit)
.. cpp:function:: PrimeGenerator<T> primes_until<T>(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
31 changes: 31 additions & 0 deletions docs/src/cplusplus/p0007.rst
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fn test_primes() -> Result<(), String> {
#[test]
fn test_prime_factors() -> Result<(), String> {
for v in primes::primes_until::<u32>(256).combinations(2) {
let &[p, s] = &v[..];
let &[p, s] = &v[..] else { panic!() };
assert!(primes::is_prime(p));
assert!(primes::is_prime(s));
assert!(primes::is_composite(p * s) != 0);
Expand Down

0 comments on commit 0e7edeb

Please sign in to comment.