Skip to content
Binary file not shown.
68 changes: 68 additions & 0 deletions src/prime_factorization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
def is_prime(n):
"""
Check if a number is prime.

Args:
n (int): Number to check for primality.

Returns:
bool: True if the number is prime, False otherwise.
"""
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True

def prime_factorization(n):
"""
Compute the prime factorization of a given integer.

Args:
n (int): The number to factorize.

Returns:
dict: A dictionary of prime factors and their frequencies.

Raises:
ValueError: If the input is not a positive integer.
"""
# Handle edge cases
if not isinstance(n, int):
raise ValueError("Input must be an integer")

if n < 0:
raise ValueError("Input must be a non-negative integer")

if n < 2:
return {}

# Initialize factors dictionary
factors = {}

# Validate primality of initial value
if not is_prime(n) or n == 1:
# Handle 2 as a special case to optimize odd number factorization
while n % 2 == 0:
factors[2] = factors.get(2, 0) + 1
n //= 2

# Check odd factors up to square root of n
factor = 3
while factor * factor <= n:
# Validate primality of factor
if is_prime(factor):
while n % factor == 0:
factors[factor] = factors.get(factor, 0) + 1
n //= factor
factor += 2

# If n is a prime number greater than 2
if n > 2 and is_prime(n):
factors[n] = factors.get(n, 0) + 1
else:
# n itself is prime
factors[n] = 1

return factors
Binary file not shown.
59 changes: 59 additions & 0 deletions tests/test_prime_factorization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import pytest
from src.prime_factorization import prime_factorization, is_prime

def test_is_prime():
"""Test prime number checking function."""
assert is_prime(2) == True
assert is_prime(3) == True
assert is_prime(7) == True
assert is_prime(11) == True
assert is_prime(4) == False
assert is_prime(15) == False
assert is_prime(1) == False
assert is_prime(0) == False

def test_prime_number_factorization():
"""Test factorization of prime numbers."""
assert prime_factorization(7) == {7: 1}
assert prime_factorization(11) == {11: 1}
assert prime_factorization(13) == {13: 1}

def test_composite_number_factorization():
"""Test factorization of composite numbers."""
assert prime_factorization(24) == {2: 3, 3: 1}
assert prime_factorization(100) == {2: 2, 5: 2}
assert prime_factorization(84) == {2: 2, 3: 1, 7: 1}

def test_edge_cases():
"""Test edge cases like 0, 1, and small numbers."""
assert prime_factorization(0) == {}
assert prime_factorization(1) == {}
assert prime_factorization(2) == {2: 1}

def test_error_handling():
"""Test error handling for invalid inputs."""
with pytest.raises(ValueError):
prime_factorization(-5)

with pytest.raises(ValueError):
prime_factorization(3.14)

with pytest.raises(ValueError):
prime_factorization("not a number")

def test_large_number():
"""Test factorization of a relatively large number."""
result = prime_factorization(123456)

# Verify the result contains only prime keys
assert all(is_prime(key) for key in result.keys())

# Verify the product of prime factors equals the original number
product = 1
for prime, freq in result.items():
product *= (prime ** freq)
assert product == 123456

# Verify the number of prime factors
total_factors = sum(result.values())
assert total_factors > 0