第二十一回 素因数分解プログラム

プログラミング編

はじめに

マサト先生
マサト先生

やあ、こんにちは。今日は『素因数分解プログラム』を作成してみよう。

ヒロト
ヒロト

はい、よろしくお願いします。

マサト先生
マサト先生

前回『素数判定プログラム』を作成したが、今回も素数がらみのプログラムだ。素因数分解については説明不要でいいかな?

ヒロト
ヒロト

はい、例えば

$$100=2^{2} \times 5^{2}$$

と素因数分解されます。

マサト先生
マサト先生

うむ、大丈夫そうだな。この計算をしてくれるプログラムを書こうというわけだ。前回の素数判定プログラムに比べ、難易度が上がっているからそのつもりで頑張っていこう!

ヒロト
ヒロト

はい、頑張ります!

前回との違い

マサト先生
マサト先生

さて、前回の『素数判定プログラム』では、与えられた整数 n に対して、2から \(\sqrt{n}\) までの整数で割り切れるかどうかチェックするだけでよかった。今回は、2から \(\frac{n}{2}\) までの素数で、割り切れるものを全て集めなくてはいけない

ヒロト
ヒロト

どうして前回と同じ2から \(\sqrt{n}\) までではなく、2から \(\frac{n}{2}\) までなのですか?

マサト先生
マサト先生

うむ、いいところに気づいたな。たとえば、n=62の場合、\(\sqrt{62}=7.87\) となって、前回と同じ範囲では2から7まで素因数かどうかチェックすることになるが、62=2×31なのでこのままでは素数31を得ることができなくなるのだ。2から \(\frac{n}{2}\) まで素因数になるかどうかチェックしなくてはいけないのだ。

ヒロト
ヒロト

なるほど、与えられた整数 n の素因数として最大となるのは自分自身を除くと \(\frac{n}{2}\) だからですね!

マサト先生
マサト先生

そういうことだ。ではこれからいくつかヒントを与えるので頑張ってほしい。

例えば、与えられた整数 n が素数2で割り切れたとしよう。このとき、この2を収納しておく入れ物が必要になる。それは、空のリストで代用すればいいだろう?

ヒロト
ヒロト

はい、空のリストを用意するには『 A=[ ] 』と書くのでしたね。

マサト先生
マサト先生

うむ。空のリストに要素の2を追加するにはどうすればいいか覚えているかな?

ヒロト
ヒロト

ええと、確か『A.append(2)』と書くことにより、空のリストAに要素2が1個追加されます。

マサト先生
マサト先生

そういうことだ。ただ、さっきの100のように素因数2を2個含む整数もあるだろう?素因数2を一つ空のリストに追加することは上のようにappend関数を使えばできそうだが、100の中に含まれる2個の素因数2をもれなく集めるための工夫がいるのだ。

ヒロト
ヒロト

要するに、2で割り切れる限りリストに追加し続ければいいのですよね?

つまり、\(100 \div 2 = 50\) だから、次に \(50 \div 2 =25\) という風に、2で割り切れる限り割り続けていき、割り切れなくなったら次の数3に移るという方針はどうでしょう?

マサト先生
マサト先生

とてもいいと思うぞ!

2で割り切れる限り割り続けるという操作は『while文』が相性良さそうだな!

その際、最初に与えた整数 n はその都度上書きする必要があることにも注意してくれ。では、そろそろ本番といこう!

ヒロト
ヒロト

はい、『while文』はある条件を満たすときに処理を繰返してくれるものでしたね!今回は『file51』から書いていきます。では、ちょっと格闘してきます!

解答


約20分後


ヒロト
ヒロト

ふう、やっとできました!これからプログラムの説明をします。

1行目で素因数分解したい整数 n をキーボードから入力します。2行目で空のリストAを用意しています。3行目のfor文の範囲は、2から \(\frac{n}{2}\) の整数部分までです。for文については、まず i に2が代入されて、4行目のwhile文の条件により、n が2で割り切れるとき、5行目によってリストAに2が追加されます。6行目では、n を 商 \(\frac{n}{2}\) で上書きしています。while文は次に、この上書きされた整数に対して同じく2で割り切れるかチェックします。2で割り切れなくなったら i=2 の場合のwhile文のループは終了し、こんどはfor文のループにより i に3が代入されて同様の処置が繰り返されるわけです。最終的に7行目でリストAが空のまま、つまり2から \(\frac{n}{2}\) までに素因数がなかった場合、自分自身が素数となるので『素数です!』と表示し、2から \(\frac{n}{2}\) までに素因数があったら、 n の素因数すべてが追加されたリストAをプリント関数で表示しています。上の例では\(100=2^{2} \times 5^{2}\) より、A=[2,2,5,5] と表示されています。

マサト先生
マサト先生

素晴らしい!

for文の中にwhile文が入る形は初めてだった思うが、よく応用できたな!とっても感心したぞ!プログラムの答えとしては他にもあると思うが、ヒロトが書いたプログラムは非常にすっきりしていて美しい。

ヒロト
ヒロト

はい、ありがとうございます!

マサト先生
マサト先生

ところで、前回の素数判定プログラムで合成数だと分かった数『1234567』を素因数分解してみてくれ!どうなるか単純に気になるのだ。

ヒロト
ヒロト

はい、お任せあれ!

ヒロト
ヒロト

できました!結果は

$$1234567=127 \times 9721$$

でした!

マサト先生
マサト先生

うーむ、二つだけの素数の積で表されるのか・・・どうりでなかなか見つからなかったわけだ。うむ、納得した!ありがとう。素因数分解してくれる計算機はあまりみないから、とてもいいものを作ったと思うぞ!

ヒロト
ヒロト

はい!とてもうれしいです!

マサト先生
マサト先生

では、今日はここまでにしよう。お疲れさん。

ヒロト
ヒロト

はい、ありがとうございました!

コメント

タイトルとURLをコピーしました