高校数学をプログラミングで解く(数学A編)「1-2 場合の数」
マガジンリスト > 数学A編 1.場合の数と確率 > 1-2 場合の数
はじめに
今回は、数学Aで学ぶ「場合の数」について、2個のさいころの目の和に関する問題をプログラミングして解いてみます。
大小2個のさいころの目の和
まず、大小2個のさいころの目の和に関する問題を考えます。
問題1
大小2個のさいころの目の和が次のようになる場合は何通りあるか。
(1) 8または10 (2) 6の倍数 (3) 9以上の数
この問題の答えは、(1)8通り、(2)6通り、(3)10通り です。
アルゴリズム設計
これらの答えは簡単に計算することができますが、今回あえて条件を満たす目の和の個数を地道に数えていくようにします。つまり、
1つ目のさいころの目として1から6までの整数を順番に選び、
2つ目のさいころの目として1から6までの整数を順番に選び、
選んだ2つのさいころの目の和が条件を満たすかを確認し、
条件を満たすものを数える。
という流れでプログラムを作成していきます。
プログラム
では、プログラムを作成していきます。問題1(1)のソースコードについて示します。
// 大小2個のさいころの目の和が8または10になる場合は何通りあるか。
void setup(){
int pip_num = 6; // さいころの目の数
int counter = 0; // カウンターを準備、初期化
for(int i=1; i<=pip_num; i++){ // 1. 1つ目のさいころの目
for(int j=1; j<=pip_num; j++){ // 2. 2つ目のさいころの目
if( i+j == 8 || i+j == 10 ){ // 3. (1)和が8または10になっているか
counter++; // 4. カウンターの値を一つ増やす
}
}
}
println(counter); // カウントした数をコンソールに出力
}
ソースコード1 さいころの目の和が8または10になる場合を数えるプログラム
このソースコードを、Processingの開発環境ウィンドウを開いて(スケッチ名を「countTwoDice」としています)、テキストエディタ部分に書いて実行します。
図のように、大小2個のさいころの目の和が8または10となる場合の数「8」をコンソールに出力します。
今回のプログラムのポイントは、大小2個のさいころの目を表すために二重ループを利用しているところ、条件をどのように条件式として書いていくかというところです。以下で解説していきます。
プログラムの解説1「2重ループ」
今回の問題では、大小2個のさいころの目の出方36通りについて、それらの目の和について条件に一致するかどうかを見ていきます。これはforループを2重にすることで実現することができます。1つ目(大)のさいころの目を i(1から6までの整数)とし、2つ目(小)のさいころの目を j(1から6までの整数)とし、さいころの目の数を
int pip_num = 6; // さいころの目の数
とすると、
for(int i=1; i<=pip_num; i++){ // 1. 1つ目のさいころの目
for(int j=1; j<=pip_num; j++){ // 2. 2つ目のさいころの目
// 処理
}
}
と書くことができます。
プログラムの解説2「問題1(1)の条件式」
問題1(1)の条件は「大小2個のさいころの目の和が8または10」でした。この条件をプログラミングしていきます。まず、「大小2個のさいころの目の和が8」を考えます。1つ目(大)のさいころの目をiとし、2つ目(小)のさいころの目をjとすると、
i+j == 8
と書くことができます。「==」は「左辺と右辺が等しいかどうか」という条件式になります。同様にして、「大小2個のさいころの目の和が10」は
i+j == 10
と書くことができます。この問題の条件は「大小2個のさいころの目の和が8または10」となっていますので、これらの条件式のどちらかを満たせばよいことになります。これは、
i+j == 8 || i+j == 10
と書くことで実現できます。「||」は「または」を表し、「条件式1 || 条件式2」は「条件式1と条件式2のどちらか一方を満たすかどうか」という結合された条件式になります。
プログラムの解説3「問題1(2)の条件式」
問題1(2)の条件は「大小2個のさいころの目の和が6の倍数」でした。「6の倍数」は言い換えると、「6で割ったときの余りが 0 になる」となります。つまり、この条件は、
(i+j)%6 == 0
と書くことができます。
ソースコード 1のif文の条件をこの条件式で置き換えてプログラムを実行すると、大小2個のさいころの目の和が6の倍数となる場合の数「6」をコンソールに出力します。
プログラムの解説4「問題1(3)の条件式」
問題1(3)の条件は「大小2個のさいころの目の和が9以上」でした。この条件は、
i+j >= 9
と書くことができます。「>=」は「左辺が右辺以上になるかどうか」という条件式になります。ソースコード 1のif文の条件をこの条件式で置き換えてプログラムを実行すると、大小2個のさいころの目の和が 9 以上となる場合の数「10」をコンソールに出力します。
区別できない2個のさいころの目の和
今度は、区別できない2個のさいころの目の和に関する問題を考えます。
問題2
同じ大きさで区別できない2個のさいころの目の和が 8 になる場合は何通りあるか。
この問題の答えは、3通り です。
アルゴリズム設計
この問題2について、もし2個のさいころの大きさが違う区別できるものであれば、
(2, 6)、(3, 5)、(4, 4)、(5, 3)、(6, 2)
の5通りになりますが、2個のさいころが同じ大きさで区別できない場合、(2, 6)と(6, 2)、(3, 5)と(5, 3)の組はそれぞれ区別できないものとなりますので、結局(2, 6)、(3, 5)、(4, 4)の3通りが問題2の答えとなります。これは、言い換えると、2つ目のさいころの目が1つ目のさいころの目の値以上になる目の組み合わせのみ数えていけばいいわけです。
これを実現するために、上記で説明した2重ループを少し変形します。
for(int i=1; i<=pip_num; i++){ // ① 1つ目のさいころの目
for(int j=i; j<=pip_num; j++){ // ② 2つ目のさいころの目
// 処理
}
}
このように2重ループを書くと、1つ目のさいころの目 i が選ばれたら、2つ目のさいころの目 j は i 以上の値のみ選ばれることになりますので、(2, 6)は存在しますが、(6, 2)となることはないので、必然的にカウントされることはありません。
以上のことをまとめると、プログラムの流れは
1つ目のさいころの目として1から6までの整数 i を順番に選び、
2つ目のさいころの目として i から6までの整数 j を順番に選び、
選んだ2つのさいころの目の和が条件を満たすかを確認し、
条件を満たすものを数える。
となります。
プログラム
では、プログラムを作成します。
// 区別できない2個のさいころの目の和が8になる場合は何通りあるか。
void setup(){
int pip_num = 6; // さいころの目の数
int counter = 0; // カウンターを準備、初期化
for(int i=1; i<=pip_num; i++){ // 1. 1つ目のさいころの目
for(int j=i; j<=pip_num; j++){ // 2. 2つ目のさいころの目
if( i+j == 8 ){ // 3. 和が8になっているか
counter++; // 4. カウンターの値を一つ増やす
}
}
}
println(counter); // カウントした数をコンソールに出力
}
ソースコード2 区別できないさいころの目の和が8になる場合を数えるプログラム
このプログラムを、Processingの開発環境ウィンドウを開いて(スケッチ名を「countTwoDice_same」としています)、テキストエディタ部分に書いて実行します。
図4のように、区別できない2個のさいころの目の和が8になる場合の数「3」をコンソールに出力します。
まとめ
今回は、数学Aで学ぶ「場合の数」について、2個のさいころの目の和に関する問題をプログラミングして解いてみました。特に、区別できる大小2個のさいころの場合と区別できない同じ大きさの2個のさいころの場合で、プログラムを書いてみました。
技術的には、forループを2つ重ねた2重ループや条件式の表し方などを学びました。これらのプログラムの書き方は今後もよくでてきますので、何度も書いて慣れていってもらえればと思います。
参考文献
改訂版 教科書傍用 スタンダード 数学A(数研出版、ISBN9784410209277)
演習問題
2桁の自然数のうち、各位の数の和が偶数になる自然数を地道に数えてその個数をコンソールに出力するプログラムを作成してください。
演習問題の解答例
ここから先は
この記事が気に入ったらサポートをしてみませんか?