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
Prime Arrangements in Python
We need to find the number of permutations of numbers 1 to n where prime numbers are placed at prime indices (1-indexed). Since the result can be large, we return it modulo 10^9 + 7.
For example, if n = 5, the output is 12. One valid permutation is [1,2,5,4,3], while [5,2,3,4,1] is invalid because 5 (prime) is at index 1 (not prime).
Algorithm
The key insight is that we need to arrange prime numbers in prime positions and non-prime numbers in non-prime positions separately ?
- Count how many prime numbers exist from 1 to n
- Count how many prime indices exist from 1 to n
- Calculate factorial of prime count × factorial of non-prime count
- Apply modulo 10^9 + 7 to prevent overflow
Implementation
class Solution:
def getNum(self, n):
# List of prime numbers up to 100
primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
count = 0
for prime in primes:
if prime > n:
break
count += 1
return count
def numPrimeArrangements(self, n):
# Count prime numbers from 1 to n
prime_count = self.getNum(n)
# Count non-prime numbers from 1 to n
non_prime_count = n - prime_count
MOD = 10**9 + 7
result = 1
# Calculate factorial of prime_count
for i in range(1, prime_count + 1):
result = (result * i) % MOD
# Calculate factorial of non_prime_count
for i in range(1, non_prime_count + 1):
result = (result * i) % MOD
return result
# Test the solution
solution = Solution()
print(solution.numPrimeArrangements(5))
print(solution.numPrimeArrangements(100))
12 682289015
How It Works
For n = 5 ?
- Prime numbers: 2, 3, 5 (count = 3)
- Non-prime numbers: 1, 4 (count = 2)
- Prime positions: 2, 3, 5 (count = 3)
- Non-prime positions: 1, 4 (count = 2)
- Result: 3! × 2! = 6 × 2 = 12
Alternative Approach Using Sieve
For larger values, we can generate primes dynamically using the Sieve of Eratosthenes ?
class Solution:
def sieve_of_eratosthenes(self, n):
"""Generate all prime numbers up to n using sieve"""
if n < 2:
return []
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
for j in range(i*i, n + 1, i):
is_prime[j] = False
return [i for i in range(2, n + 1) if is_prime[i]]
def numPrimeArrangements(self, n):
primes = self.sieve_of_eratosthenes(n)
prime_count = len(primes)
non_prime_count = n - prime_count
MOD = 10**9 + 7
result = 1
# Calculate prime_count! × non_prime_count!
for i in range(1, prime_count + 1):
result = (result * i) % MOD
for i in range(1, non_prime_count + 1):
result = (result * i) % MOD
return result
# Test with both approaches
solution = Solution()
print(solution.numPrimeArrangements(10))
17280
Conclusion
The solution works by counting prime numbers up to n and calculating the factorial of both prime count and non-prime count. This ensures prime numbers can only be arranged in prime positions and vice versa.
