Skip to content

Instantly share code, notes, and snippets.

@arekmaz
Last active April 8, 2020 17:39
Show Gist options
  • Save arekmaz/4a8063693ba7f337d11189c999aaa6df to your computer and use it in GitHub Desktop.
Save arekmaz/4a8063693ba7f337d11189c999aaa6df to your computer and use it in GitHub Desktop.
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