Skip to content

Instantly share code, notes, and snippets.

@macabeus
Last active November 13, 2019 00:01
Show Gist options
  • Save macabeus/ae1b513e0c3e2791b5d25d29f63c3c87 to your computer and use it in GitHub Desktop.
Save macabeus/ae1b513e0c3e2791b5d25d29f63c3c87 to your computer and use it in GitHub Desktop.
This algorithm returns the biggest sequence from an array that repeats at least two times.
/**
* This algorithm returns the biggest sequence from an array that repeats at least two times.
*
* Example:
* - [1, 1, 2, 2, 1, 1] -> ['1,1', 2]
* - [1, 1, 1, 1, 1, 1, 1, 1] -> ['1,1,1,1,1,1,1', 2]
* - [1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 4, 5, 5, 5] -> ['1,1,1,2', 2]
*
* The idea is very simple:
* - firstly, we should split the array on all subsequences with at least two elements;
* - so, we should to aggregate on a map the frequence for each sequence;
* - and finally, we should find which sequence is the biggest and most frequent.
*
* Hey, just for simplify, this code only works for numeric array and with numbers between 0 and 9.
*/
const listSequences = (array) => {
const sequences = []
const nextStep = (initialIndex, lastIndex) => {
if (initialIndex === array.length - 1) {
return 'finish'
}
if (lastIndex + 1 > array.length) {
return 'reset'
}
return 'grow'
}
const splitArray = (currentInitialIndex, currentLastIndex) => {
sequences.push(
array.slice(currentInitialIndex, currentLastIndex)
)
switch (nextStep(currentInitialIndex, currentLastIndex)) {
case 'finish':
return
case 'reset':
const nextInitialIndex = currentInitialIndex + 1
const nextLastIndex = nextInitialIndex + 2
splitArray(nextInitialIndex, nextLastIndex)
return
case 'grow':
splitArray(currentInitialIndex, currentLastIndex + 1)
return
}
}
splitArray(0, 2)
return sequences
}
const calcSequenceFrequence = sequences => sequences.reduce((acc, i) => {
if (acc[`${i}`] === undefined) {
acc[`${i}`] = 0
}
acc[`${i}`] += 1
return acc
}, {})
const getMostFrequentSequence = frequences => Object.entries(frequences).reduce(
([maxSequence, maxAmount], [sequence, amount]) => {
if (amount < 2) {
return [maxSequence, maxAmount]
}
if (sequence.length > maxSequence.length) {
return [sequence, amount]
}
if (
(sequence.length === maxSequence.length) &&
(amount > maxAmount)
) {
return [sequence, amount]
}
return [maxSequence, maxAmount]
},
['', 0]
)
///////////
const array = [2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 2, 4, 5, 2, 2]
const sequences = listSequences(array)
const sequencesFrequences = calcSequenceFrequence(sequences)
const mostFrequentSequence = getMostFrequentSequence(sequencesFrequences)
console.log(mostFrequentSequence)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment