Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find the kth factor of n using Python
Finding the kth factor of a number efficiently requires a smart approach. Instead of finding all factors, we can find factors up to the square root and use mathematical properties to determine the kth factor without generating the complete list.
Algorithm Approach
The key insight is that factors come in pairs. For a number n, if i is a factor, then n/i is also a factor. We only need to find factors up to ?n and use this pairing property.
Step-by-Step Solution
Here's how the algorithm works ?
from math import floor
def solve(n, k):
if k == 1:
return 1
# Find factors up to square root
factors = [1]
for i in range(2, 1 + floor(pow(n, 0.5))):
if n % i == 0:
factors.append(i)
m = len(factors)
# Check if kth factor exists
if k > 2 * m or (k == 2 * m and n == factors[-1] ** 2):
return -1
# Return factor from first half
if k <= m:
return factors[k - 1]
# Return corresponding factor from second half
pair_factor = factors[2 * m - k]
return n // pair_factor
# Test the function
n = 28
k = 4
result = solve(n, k)
print(f"The {k}th factor of {n} is: {result}")
The 4th factor of 28 is: 7
How It Works
Let's trace through the example with n = 28 and k = 4 ?
def solve_with_trace(n, k):
print(f"Finding {k}th factor of {n}")
if k == 1:
return 1
# Find factors up to square root
factors = [1]
sqrt_n = floor(pow(n, 0.5))
print(f"Checking divisors up to ?{n} = {sqrt_n}")
for i in range(2, sqrt_n + 1):
if n % i == 0:
factors.append(i)
print(f"Found factor: {i}")
print(f"Factors up to ?n: {factors}")
# All factors would be: factors + [n//f for f in reversed(factors) if f != sqrt_n or n != f*f]
all_factors = []
for f in factors:
all_factors.append(f)
for f in reversed(factors):
complement = n // f
if complement != f: # Avoid duplicate for perfect squares
all_factors.append(complement)
print(f"All factors: {all_factors}")
m = len(factors)
# Check if kth factor exists
if k > 2 * m or (k == 2 * m and n == factors[-1] ** 2):
return -1
# Return factor from first half
if k <= m:
return factors[k - 1]
# Return corresponding factor from second half
pair_factor = factors[2 * m - k]
return n // pair_factor
result = solve_with_trace(28, 4)
print(f"Result: {result}")
Finding 4th factor of 28 Checking divisors up to ?28 = 5 Found factor: 2 Found factor: 4 Factors up to ?n: [1, 2, 4] All factors: [1, 2, 4, 28, 14, 7] Result: 7
Edge Cases
The algorithm handles several edge cases ?
# Test edge cases
test_cases = [
(12, 1), # First factor
(12, 6), # Last factor
(12, 7), # More factors than available
(16, 5), # Perfect square
]
for n, k in test_cases:
result = solve(n, k)
print(f"n={n}, k={k} ? {result}")
n=12, k=1 ? 1 n=12, k=6 ? 12 n=12, k=7 ? -1 n=16, k=5 ? 16
Time Complexity
This approach has O(?n) time complexity instead of O(n) for finding all factors, making it much more efficient for large numbers.
Conclusion
This algorithm efficiently finds the kth factor by leveraging the pairing property of divisors. It only computes factors up to ?n and uses mathematical relationships to determine the result, making it optimal for large inputs.
