dp
dp[n] = number of prime arrangements with [1.2,3,4,5,6,7,8,...,n]\n\nif n is prime\ndp[n] = (number of primes <= n) * dp[n-1]\n\nif n is not prime\ndp[n] = (num
dp[n] = number of prime arrangements with [1.2,3,4,5,6,7,8,...,n]\n\nif n is prime\ndp[n] = (number of primes <= n) * dp[n-1]\n\nif n is not prime\ndp[n] = (number of non primes <= n) * dp[n-1]\n\navoid using memory O(n) and made it O(1) in memory\n\n\n\n```\nclass Solution(object):\n    def numPrimeArrangements(self, n):\n        p = 0 # number of primes\n        np = 1 # number of non primes  \n        og = 1 # on going number of prime arrangements \n        mod = 10 ** 9 + 7\n        for i in range(2,n + 1):\n            if self.isprime(i):\n                p += 1\n                og = (og * p) % mod\n            else:\n                np += 1\n                og = (og * np) % mod\n        return og\n                \n    def isprime(self,n):\n        return n > 1 and all([n % ii != 0 for ii in range(2,min(n,int(n ** 0.5) + 1))])\n```
[]