Skip to content

Instantly share code, notes, and snippets.

@encap
Created February 2, 2021 14:54
Show Gist options
  • Save encap/908578b21464086d0c72b7999aeb0eb0 to your computer and use it in GitHub Desktop.
Save encap/908578b21464086d0c72b7999aeb0eb0 to your computer and use it in GitHub Desktop.
Algorithm that receives two sequences: A and B of integers and returns one sequence C. Sequence C should contain all elements from sequence A (maintaining the order) except those, that are present in sequence B p times, where p is a prime number.
// inputs
const A = [2,3,9,2,5,1,3,7,10]
const B = [2,1,3,4,3,10,6,6,1,7,10,10,10]
const P = 2;
// expected results for that inputs
// [2,9,2,5,7,10]
// test larger input arrays
// for (let i = 0; i < 100000; i += 1) {
// A.push(Math.floor(Math.random()*1000))
// B.push(Math.floor(Math.random()*1000))
// }
const isPrimeNumber = (num) => {
// 6k + 1 algorithm based on https://en.wikipedia.org/wiki/Primality_test
if (num <= 3) {
return num > 1;
}
if ((num % 2) === 0|| (num % 3) === 0) {
return false;
}
for (let i = 5; (i ** 2) <= num; i += 6) {
if (
(num % i) === 0
|| (num % (i + 2)) === 0
) {
return false;
}
return true
}
}
const solveAlgorithm = (p, seqA, seqB) => {
if (p > seqB.length) {
throw RangeError('First argument must be less or equal than seqB length');
} else if (!isPrimeNumber(p)) {
throw RangeError('First argument must be a prime number');
}
const cache = {
include: [],
exclude: [],
}
const checkCount = (numToCount) => {
// indexOf has fast C implemenation in JS engine
// but benefits of using it here cancel out 50% of a time with random values
// if (seqB.indexOf(numToCount) === -1) {
// return false;
// }
const count = seqB.reduce((acc, num) => num === numToCount ? acc += 1 : acc, 0);
if (count === p) {
cache.exclude.push(numToCount);
return true;
}
cache.include.push(numToCount);
return false;
}
const retSeq = seqA.filter((num) => {
if (cache.exclude.indexOf(num) !== -1) {
return false;
} else if (cache.include.indexOf(num) !== -1) {
return true;
} else {
return !checkCount(num);
}
})
return retSeq;
}
const t0 = Date.now();
const results = solveAlgorithm(P, A, B);
const t1 = Date.now();
console.log('*****END******');
console.log(`Results contain ${results.length} numbers, displaying first 20`)
console.log(results.slice(0, 20));
console.log(`TOOK ${t1 - t0}ms`);
/*
I don't have the exact time complexity in Big O notation
but here are the execution times in milliseconds
on Ryzen 3 2200G @3.7GHz
A = 1 000 random, B = 1 000 random, P = 97
without caching: 559
with caching: 15
A = 10 000 random, B = 10 000 random, P = 1229
with caching: 145
A = 100 000 random, B = 100 000 random, P = 64223
without caching: 12000
with caching: 1380
A = original, B = 1 000 000 random, P = 1229
with caching: 100
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment