In this week’s challenge, I was tasked with building out a function that would find every factor for a passed in number (for example, the number 6 has factor pairs of 1 & 6 and 2 & 3) and take a second number that returns the factor at that location in the list when sorted. To paint a picture, the sorted list of factors for the previous example would be 1, 2, 3, 6. If the second number passed into the function was 4, the function would return the 4th number in the array, which would be 6.
Thinking about the structure of the function, I knew before I started that I’d have to create an empty array to push the factors into. I’d also have to create a for loop to check every possible number to see if it’s a viable factor of the passed in number n. On top of that, the instructions listed an edge case that if the passed in search number was higher than the total number of factors, the function would return 0. The returned value for a valid search number would be the passed in value p reduced by 1, since the array would be 0-indexed.
Inside the loop, I’d have to use the modulo operator to check if the remainder of the passed in number n divided by the current iteration i would be 0, which would make the current iteration a factor to be pushed into the array.
This is a working function! But was there a way to make the function a little more efficient? While I was researching how to find the functions of a specific number, I found a website that allowed you to input a number and it would return the factors of that number. On that page, the creators explained the math behind the website (https://www.calculatorsoup.com/calculators/math/factors.php). The math used in the website took the user input, found the square root, and used that number to find the factors. This method would half the time my function would take in those incredibly large edge cases.
Now, I need to change what happens inside my iteration. I wanted to create three separate variables, one to save the remainder when the number n is divided by the current iteration i, then a variable of the current value of i, followed by a variable that’s the number n divided by the current value of i.
Now inside this loop, I only want to do something when the saved factor variable is 0, since a number without a remainder indicates that number as a factor. To find the upper pairing for that factor, you would simply divide the value n by the value i, so both variables f1 and f2 would be pushed into the array.
This solution gave me two specific problems. First, since the numbers were being passed in by their pairs instead of in numerical order, I’d have to sort the array after the loop finished. This is easily done by using the sort function. Second, this method presents a problem when you encounter the square root of a number. For example, let’s say you wanted to pass in the number 9. Since 3 squared is 9, there would be an iteration where 3 would be the value of f1 and f2. There’s also an easy solution to this problem, simply by checking if the two variables are of equal value. If they aren’t equal, the second value would be pushed into the array, but left out if they are.
So there you have it! While the first version of the function worked and was perfectly fine, you can always make steps towards making your code more efficient. By running the loop through the initial number’s square root, it’s possible to half the time the loop would take. While this isn’t exactly noteworthy in most cases, since the loop will run fast enough with smaller numbers that you wouldn’t necessarily notice a difference, it becomes significantly more important in those edge cases where the user inputs incredibly high numbers. For example, if the user inputs 1 million as their number, the loop will only have to run 500 thousand times instead of the full million. It’s not the most incredible efficiency change, but it’s one that makes the program run a little more smoothly.