Skip to content

Instantly share code, notes, and snippets.

@lucasmonstrox
Last active August 18, 2023 09:16
Show Gist options
  • Save lucasmonstrox/03f85a26002724d643cd7e06593a63e2 to your computer and use it in GitHub Desktop.
Save lucasmonstrox/03f85a26002724d643cd7e06593a63e2 to your computer and use it in GitHub Desktop.
collatz fastest way
const longestCollatzSequence = limit => {
var numberWithHighestSequence = 3;
var highestSequenceIndex = 8;
/**
* "Uint32Array" automatically fill with "zeros" - avoid copyWithin/loop/map to set array with zero values
*
* Save between 20~25 ms
*/
var arrayOfSequences = new Int32Array(limit);
arrayOfSequences[1] = 1;
arrayOfSequences[2] = 2;
/**
* Double step i += 2 to gain performance and avoid 1 iteration
*
* Save between 1~3 ms
*/
for (var number = 3; number < limit; number += 2) {
/**
* === comparison is fastest than casting condition to boolean
*
* The saving is insignificant but is possible to see the difference for a big limit
*/
if (arrayOfSequences[number] === 0) {
var numberToTransform = number;
/**
* Using "new Array()" is fastest than "[]"
*
* Save between 5~10 ms
*/
var arrayOfNumbers = new Array();
do {
/**
* "array.push(value)" is fastest than "array[i] = value"
* Link: https://stackoverflow.com/questions/614126/why-is-array-push-sometimes-faster-than-arrayn-value
*/
arrayOfNumbers.push(numberToTransform);
/**
* Caculate by "numberToTransform & 1" is fastest than "numberToTransform % 2 === 1"
* Calculate by "numberToTransform >>> 1"(bitwise) is fastest than division
* (numberToTransform << 1) + (numberToTransform << 0) is a fastest than 3 * numberToTransform
*
* Save 30~40 ms
*/
numberToTransform =
numberToTransform & 1
? (((numberToTransform << 1) + (numberToTransform << 0) + 1) <<
0) >>>
1
: numberToTransform >>> 1;
/**
* === comparison is fastest than casting condition to boolean
* "arrayOfSequences[numberToTransform] === undefined" is most probably to occur than "arrayOfSequences[numberToTransform] === 0"
*
* The saving is insignificant but is possible to see the difference for a big limit
*/
} while (
arrayOfSequences[numberToTransform] === undefined ||
arrayOfSequences[numberToTransform] === 0
);
/**
* This strategy automatically resolves the next numbers and automatically gets cached.
*
* Save 250~300 ms
*/
var j = arrayOfNumbers.length;
while (j-- > 0) {
// Ignore numbers greather than limit. This prevents the array from getting big
if (arrayOfNumbers[j] < limit) {
arrayOfSequences[arrayOfNumbers[j]] =
arrayOfNumbers.length - j + arrayOfSequences[numberToTransform];
}
}
if (arrayOfSequences[number] > numberWithHighestSequence) {
numberWithHighestSequence = arrayOfSequences[number];
highestSequenceIndex = number;
}
}
}
return highestSequenceIndex;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment