Last active
April 8, 2020 17:39
-
-
Save arekmaz/4a8063693ba7f337d11189c999aaa6df to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { sqrt, floor } = Math | |
type Sequence<T> = T[] | |
/* | |
Get sequence of items from the first sequence in the | |
initial order excluding items which occur in the second | |
sequence prime number of times. | |
Implementation uses plain javascript arrays as sequences | |
and stores information about occurrence counts being prime numbers | |
in a Map for linear read time complexity. | |
The solution itself has linear time complexity | |
and is described by the "solve" function. | |
*/ | |
function solve( | |
sequenceA: Sequence<number>, | |
sequenceB: Sequence<number> | |
): Sequence<number> { | |
// map of how many times an item is present in a sequence | |
const presenceCounts = getPresenceCounts(sequenceB) | |
// map occurence count to whether it is a prime number | |
const itemPresencePrimeMap = getPresenceCountsPrime(presenceCounts) | |
// filter out the items which are present a prime number of times | |
return sequenceA.filter(num => { | |
const presenceIsPrime = itemPresencePrimeMap.get(num) | |
return !presenceIsPrime | |
}) | |
} | |
/* | |
construct a map describing if given item presence | |
count is a prime number | |
*/ | |
function getPresenceCountsPrime<T>(presenceCounts: Map<T, number>): Map<T, boolean> { | |
return transformValues(isPrime, presenceCounts) | |
} | |
// construct a new map with values transformed with a function | |
function transformValues<T, K, P>(transformer: (value: T) => K, input: Map<P, T>): Map<P, K> { | |
const transformedEntries = Array.from(input.entries()).map(([_, value]): [P, K] => { | |
return [_, transformer(value)] | |
}) | |
return new Map(transformedEntries) | |
} | |
/* | |
construct map of an array item and its occurrences | |
count in a sequence | |
*/ | |
function getPresenceCounts<T>(sequence: Sequence<T>): Map<T, number> { | |
return sequence.reduce((presenceMap, currentItem) => { | |
// for every occurence of an item increment the value under it | |
const currentCount = presenceMap.get(currentItem) || 0 | |
return presenceMap.set(currentItem, currentCount + 1) | |
}, new Map()) | |
} | |
function isPrime(num: number) { | |
/* | |
prime numbers must be integers | |
greater than 0 | |
*/ | |
if (!Number.isInteger(num) || num <= 0) { | |
return false | |
} | |
// 1 is not a prime number | |
if (num === 1) return false | |
// 2 is a prime number | |
if (num === 2) return true | |
/* | |
we can test the rest | |
by checking if number is dividable | |
by numbers up to its square root | |
*/ | |
const lowerRoot = floor(sqrt(num)) | |
/* | |
we test starting with 2 because | |
diviability by 1 doesn't determine | |
number to be prime | |
*/ | |
for (let i = 2; i <= lowerRoot; ++i) { | |
// num is dividable | |
if (num % i === 0) { | |
return false | |
} | |
} | |
return true | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment