Pythonで解く素数の並べ替え問題:素数を素数インデックスに配置する順列の数
この記事では、1からnまでの数字を使った順列のうち、「素数が素数のインデックス位置(1始まり)に配置されている」ものの総数を求める問題を扱います。答えは非常に大きくなる可能性があるため、109 + 7で割った余りを返します。
例えば n = 5 の場合、答えは12通りになります。有効な順列の一例は [1, 2, 5, 4, 3] です。一方、[5, 2, 3, 4, 1] は無効です。これは、素数である5がインデックス1(素数ではない)に置かれているためです。
解法のアプローチ
まず、getNum という補助メソッドを定義して n 以下の素数の個数を数えます。その後、素数の個数 x と非素数の個数 n − x それぞれについて階乗を計算し、掛け合わせることで答えを求めます。
- getNum メソッド: 2から100までの素数リストを用意し、リストを先頭から走査します。n より大きい素数が出現した時点でのカウント(= n 以下の素数の個数)を返します。
- メイン処理: x = getNum(n)、p = 1、m = 109 + 7 とします。まず i を x から 1 まで減らしながら p *= i、p %= m を繰り返します。続いて i を n − x から 1 まで減らしながら同じ計算を行い、最終的な p を返します。
なぜこの方法で正しいのか
n 以下に素数が x 個あるとき、x 個の素数を x 個の素数インデックスへ配置する方法は x! 通りあります。同様に、残りの n − x 個の数(1と合成数)を n − x 個の非素数インデックスへ配置する方法は (n − x)! 通りあります。この2つの配置は互いに独立しているため、答えは x! × (n − x)! となります。毎回の剰余演算によって値の肥大化を防ぎ、オーバーフローなしに計算できます。
実装例
以下のPythonコードで実際の動作を確認できます。
class Solution(object):
def getNum(self,n):
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]
i = 0
while i < len(primes):
if primes[i]>n:
return i
i+=1
return len(primes)
def numPrimeArrangements(self, n):
"""
:type n: int
:rtype: int
"""
x = self.getNum(n)
p = 1
m = 1000000000+7
for i in range(x,0,-1):
p*=i
p%=m
for i in range(n-x,0,-1):
p*=i
p%=m
return p
ob1 = Solution()
print(ob1.numPrimeArrangements(100))
入力
100
出力
682289015
n = 100 の場合、100以下の素数は25個存在するため、答えは 25! × 75! を 109 + 7 で割った余りである 682289015 となります。
-
Pythonで数値の一意な素因数の積を求める方法
この記事では、以下の問題文に対する解決策について学びます。問題文数値 n が与えられたとき、その数値が持つすべての一意な素因数の積を求めて返します。例入力: num = 11 出力: 積は 11説明ここでは、入力された数値は 11 であり、素因数は 11 のみです。したがって、その積は 11 となります。アプローチ1:総当たり法i = 2 から n+1 までの for ループを使用し、i が n の因数であるかどうかを確認します。因数であれば、さらに i 自体が素数かどうかを判定し、素数であれば product 変数に積を格納します。この処理を i が n になるまで繰り返します。コード例de
-
【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説
はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが