Skip to content

Commit

Permalink
Solve p3 in js; fix linting
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Aug 8, 2024
1 parent 44c11d3 commit e90b085
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 22 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Olivia's Project Euler Solutions
| | | | |CodeQL| |br| |
| | | | |C#-lint| |
+------------+--------------------------+--------+-------------------+
| JavaScript | Node 12+ |br| | 17 | |JavaScript| |br| |
| JavaScript | Node 12+ |br| | 18 | |JavaScript| |br| |
| | Bun 1.0+ |br| | | |Js-Cov| |br| |
| | Firefox [2]_ |br| | | |CodeQL| |br| |
| | Chrome [2]_ | | |ESLint| |
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Problems Solved
+-----------+------------+------------+------------+------------+------------+------------+
|:prob:`2` |:c-d:`0002` |:cp-d:`0002`|:cs-d:`0002`|:js-d:`0002`|:py-d:`0002`|:rs-d:`0002`|
+-----------+------------+------------+------------+------------+------------+------------+
|:prob:`3` |:c-d:`0003` | | | |:py-d:`0003`|:rs-d:`0003`|
|:prob:`3` |:c-d:`0003` | | |:js-d:`0003`|:py-d:`0003`|:rs-d:`0003`|
+-----------+------------+------------+------------+------------+------------+------------+
|:prob:`4` |:c-d:`0004` |:cp-d:`0004`|:cs-d:`0004`|:js-d:`0004`|:py-d:`0004`|:rs-d:`0004`|
+-----------+------------+------------+------------+------------+------------+------------+
Expand Down
18 changes: 18 additions & 0 deletions docs/javascript/p0003.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
JavaScript Implementation of Problem 3
======================================

View source code :source:`javascript/src/p0003.js`

Includes
--------

- `primes <./primes.html>`_

Problem Solution
----------------

.. js:autofunction:: p0003

.. literalinclude:: ../../javascript/src/p0003.js
:language: javascript
:linenos:
8 changes: 8 additions & 0 deletions docs/javascript/p0007.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ JavaScript Implementation of Problem 7

View source code :source:`javascript/src/p0007.js`

Includes
--------

- `primes <./primes.html>`_

Problem Solution
----------------

.. js:autofunction:: p0007

.. literalinclude:: ../../javascript/src/p0007.js
Expand Down
4 changes: 4 additions & 0 deletions docs/javascript/primes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ primes.js

View source code :source:`javascript/src/lib/primes.js`

.. js:autofunction:: primes.primes

.. js:autofunction:: primes.modifiedEratosthenes

.. js:autofunction:: primes.primeFactors

.. literalinclude:: ../../javascript/src/lib/primes.js
:language: javascript
:linenos:
1 change: 1 addition & 0 deletions javascript/euler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('Mathematics', ()=>{
const answers = {
1: [require('./src/p0001.js'), false],
2: [require('./src/p0002.js'), false],
3: [require('./src/p0003.js'), false],
4: [require('./src/p0004.js'), false],
6: [require('./src/p0006.js'), false],
7: [require('./src/p0007.js'), false],
Expand Down
115 changes: 98 additions & 17 deletions javascript/src/lib/primes.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
const cache = [2, 3, 5, 7];
let lastCached = 7;

/**
* Iterates over the prime numbers up to an (optional) limit, with caching.
*
* This iterator leverages the :js:func:`primes.modifiedEratosthenes` iterator, but adds
* additional features. The biggest is a ``stop`` argument, which will prevent it
* from yielding any numbers larger than that. The next is caching of any yielded
* prime numbers.
* @param {number | null} stop
* @yield {number}
*/
function* primes(stop = null) {
if (stop === null) {
for (p of cache) {
yield p;
}
} else {
for (p of cache) {
if (p < stop) {
yield p;
} else {
break;
}
}
}
if (stop !== null && lastCached > stop) {
return;
}
for (p of modifiedEratosthenes()) {
if (p <= lastCached) {
continue;
}
if (stop !== null && p > stop) {
break;
}
cache.push(p);
lastCached = p;
yield p;
}
}
exports.primes = primes;


/**
* Iterates over prime numbers using the Sieve of Eratosthenes.
*
Expand All @@ -6,44 +51,80 @@
* the principle of the sieve.
*
* .. image:: https://upload.wikimedia.org/wikipedia/commons/9/94/Animation_Sieve_of_Eratosth.gif
* :alt: Any animated example of the Sieve of Eratosthenes"""
* @param {number} n
* @return {number}
* :alt: Any animated example of the Sieve of Eratosthenes
* @yield {number}
*/
exports.modifiedEratosthenes = function * modifiedEratosthenes(n) {
function* modifiedEratosthenes() {
yield 2;
yield 3;
yield 5;
yield 7;
const sieve = new Map();
const recurse = modifiedEratosthenes();
const recurse = primes();
recurse.next();
let prime = recurse.next().value;
if (prime !== 3) {
throw new Error();
}
let prime_squared = prime * prime;
let primeSquared = prime * prime;
let step = 2;
for (let candidate = 9; ; candidate += 2) {
if (sieve.has(candidate)) { // if c is a multiple of some base prime, or
if (sieve.has(candidate)) { // if c is a multiple of some base prime, or
step = sieve.get(candidate);
sieve.delete(candidate);
}
else if (candidate < prime_squared) { // prime, or
} else if (candidate < primeSquared) { // prime, or
yield candidate;
continue;
}
else { // the next base prime's square
// if candidate != prime_squared:
} else { // the next base prime's square
// if candidate != primeSquared:
// raise ValueError()
step = prime * 2;
prime = recurse.next().value;
prime_squared = prime * prime;
primeSquared = prime * prime;
}
let tc = candidate
let tc = candidate;
do {
tc += step; // the next multiple
} while (sieve.has(tc)) // make sure to not overwrite another sieve entry
tc += step; // the next multiple
} while (sieve.has(tc)); // make sure to not overwrite another sieve entry
sieve.set(tc, step);
}
};
}
exports.modifiedEratosthenes = modifiedEratosthenes;


/**
* Iterates over the prime factors of a number.
*
* @param {number} num
* @yield {number}
*/
function* primeFactors(num) {
if (num < 0) {
yield -1;
num = -num;
}
if (num === 0) {
yield 0;
} else {
let root = Math.ceil(Math.sqrt(num));
for (factor of primes()) {
let modulo = num % factor;
if (modulo == 0) {
while (modulo == 0) { // double-check to call sqrt once
yield factor;
num /= factor;
modulo = num % factor;
}
root = Math.ceil(Math.sqrt(num));
}
if (num <= 1) {
break;
}
if (factor > root) {
yield num;
break;
}
}
}
}
exports.primeFactors = primeFactors;
19 changes: 19 additions & 0 deletions javascript/src/p0003.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Project Euler Problem 3
*
* Finally ported prime factor generator to js
*
* Problem:
*
* The prime factors of 13195 are 5, 7, 13 and 29.
*
* What is the largest prime factor of the number 600851475143 ?
*
* @return {number}
*/
exports.p0003 = function() {
return Math.max(...primes.primeFactors(600851475143));
};

const primes = require('./lib/primes.js');

5 changes: 2 additions & 3 deletions javascript/src/p0007.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
* @return {number}
*/
exports.p0007 = function() {
let pgen = primes.modifiedEratosthenes();
const pgen = primes.modifiedEratosthenes();
for (let idx = 1; ; idx++) {
let num = pgen.next().value;
const num = pgen.next().value;
if (idx === 10001) {
return num;
}
}
return -1;
};

const primes = require('./lib/primes.js');
Expand Down

0 comments on commit e90b085

Please sign in to comment.