Skip to content

Commit

Permalink
Solve p3 in C++
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Sep 5, 2024
1 parent 2178244 commit c1f3345
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Olivia's Project Euler Solutions
| | C11+ in: |msvc| [1]_ | | |CodeQL| |br| |
| | |br| Browser [2]_ | | |C-lint| |
+------------+----------------------------+--------+-------------------+
| C++ | C++98+ in: |br| |clang|, & | 19 | |Cpi| |br| |
| C++ | C++98+ in: |br| |clang|, & | 20 | |Cpi| |br| |
| | |gcc| |br| | | |Cp-Cov| |br| |
| | C++14+ in: |msvc| [1]_ | | |CodeQL| |br| |
| | |br| Browser [3]_ | | |Cp-lint| |
Expand Down
1 change: 1 addition & 0 deletions cplusplus/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ Problems Solved

- ☒ `1 <./src/p0001.cpp>`__
- ☒ `2 <./src/p0002.cpp>`__
- ☒ `3 <./src/p0003.cpp>`__
- ☒ `4 <./src/p0004.cpp>`__
- ☒ `6 <./src/p0006.cpp>`__
- ☒ `7 <./src/p0007.cpp>`__
Expand Down
40 changes: 39 additions & 1 deletion cplusplus/src/include/primes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <vector>
#include <map>
#include <limits>
#include <stdexcept>

template<typename T>
class PrimeGenerator {
Expand All @@ -17,7 +18,7 @@ class PrimeGenerator {
T next() {
if (has_limit && prime >= limit) {
sieve.clear();
return T(-1);
throw new std::runtime_error("Tried to exceed given limit (or limit of data type).");
}
prime = next_prime(candidate);
candidate = prime + T(1);
Expand Down Expand Up @@ -71,3 +72,40 @@ template<typename T>
PrimeGenerator<T> primes_until(T x) {
return PrimeGenerator<T>(x);
}

template<typename T>
class PrimeFactors {
public:
PrimeFactors(T target)
: target(target), last_prime(T(std::numeric_limits<T>::max(), prime_gen(primes<T>()))) {}

T next() {
if (!has_next())
throw new std::runtime_error("No more factors available.");
if (std::numeric_limits<T>::min() < 0 && target < 0) {
target = -target;
return T(-1);
}
while (true) {
if (target % last_prime == 0) {
target /= last_prime;
return last_prime;
}
last_prime = prime_gen.next();
}
}

bool has_next() const {
return target != 1 && target != 0;
}

private:
T target;
T last_prime;
PrimeGenerator<T> prime_gen;
};

template<typename T>
PrimeFactors<T> prime_factors(T target) {
return PrimeFactors<T>(target);
}
30 changes: 30 additions & 0 deletions cplusplus/src/p0003.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Project Euler Problem 3
More lazy functions this time.
Problem:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
*/

#ifndef EULER_P0003
#define EULER_P0003
#include <stdint.h>
#include <iostream>
#include "include/macros.hpp"
#include "include/primes.hpp"

uint16_t EMSCRIPTEN_KEEPALIVE p0003() {
uint16_t answer = 0;
PrimeFactors<uint64_t> pfs = prime_factors<uint64_t>(600851475143);
while (pfs.has_next())
answer = (uint16_t) pfs.next();
return answer;
}


PROGRAM_TAIL(p0003)
#endif
4 changes: 2 additions & 2 deletions cplusplus/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <inttypes.h>
#include "src/p0001.cpp"
#include "src/p0002.cpp"
// #include "src/p0003.cpp"
#include "src/p0003.cpp"
#include "src/p0004.cpp"
// #include "src/p0005.cpp"
#include "src/p0006.cpp"
Expand Down Expand Up @@ -37,7 +37,7 @@ typedef struct {
ProblemRef answers[] = {
{ 1, (void *(*)())p0001 },
{ 2, (void *(*)())p0002 },
// { 3, (void *(*)())p0003 },
{ 3, (void *(*)())p0003 },
{ 4, (void *(*)())p0004 },
// { 5, (void *(*)())p0005 },
{ 6, (void *(*)())p0006 },
Expand Down
4 changes: 1 addition & 3 deletions cplusplus/test_euler.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@

answers = {
x: get_answer(x) for x in (
1,
2,
4,
*range(1, 5),
*range(6, 10),
11,
*range(13, 18),
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Problems Solved
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`002`|:c-d:`0002` |:cp-d:`0002`|:cs-d:`0002`|:ja-d:`0002`|:js-d:`0002`|:py-d:`0002`|:rs-d:`0002`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`003`|:c-d:`0003` | |:cs-d:`0003`| |:js-d:`0003`|:py-d:`0003`|:rs-d:`0003`|
|:prob:`003`|:c-d:`0003` |:cp-d:`0003`|:cs-d:`0003`| |:js-d:`0003`|:py-d:`0003`|:rs-d:`0003`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
|:prob:`004`|:c-d:`0004` |:cp-d:`0004`|:cs-d:`0004`|:ja-d:`0004`|:js-d:`0004`|:py-d:`0004`|:rs-d:`0004`|
+-----------+------------+------------+------------+------------+------------+------------+------------+
Expand Down
22 changes: 19 additions & 3 deletions docs/src/cplusplus/lib/primes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ Includes
- :external:cpp:type:`vector`
- :external:cpp:type:`map`
- :external:cpp:type:`limits`
- :external:cpp:type:`stdexcept`

.. cpp:namespace-push:: primes

.. cpp:class:: PrimeGenerator

.. cpp:function:: PrimeGenerator<T> PrimeGenerator<T>()
Expand All @@ -26,9 +27,24 @@ Includes

These constructors will return a finite generator of prime numbers, going to ``upper_limit``.

.. cpp:function:: bool next()
.. cpp:function:: T next()

Returns the next prime, or ``0`` if it is above the defined limit.

.. cpp:function:: bool has_next()

Returns ``true`` if there is a next value to generate.

.. cpp:class:: PrimeFactors

.. cpp:function:: PrimeFactors<T> PrimeFactors<T>(T upper_limit)
.. cpp:function:: PrimeFactors<T> prime_factors<T>(T upper_limit)

These constructors will return a finite generator of prime factors of ``target``.

.. cpp:function:: T next()

Returns the next prime, or ``-1`` if it is above the defined limit.
Returns the next prime factor, or ``0`` if it is above the defined limit.

.. cpp:function:: bool has_next()

Expand Down
30 changes: 30 additions & 0 deletions docs/src/cplusplus/p0003.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
C++ Implementation of Problem 3
===============================

View source code :source:`cplusplus/src/p0003.cpp`

Includes
--------

- `"primes.hpp" <./lib/primes.html>`__
- :external:c:type:`stdint`
- :external:cpp:type:`iostream`

Solution
--------

.. cpp:namespace-push:: p0003

.. cpp:function:: uint16_t p0003()

.. 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/p0003.cpp
:language: C++
:linenos:

.. tags:: fibonacci-number, divisibility

0 comments on commit c1f3345

Please sign in to comment.