【C言語入門】好きな人と隣の席になる確率を求める


はじめに

春といえば出会いの季節。

新学期が始まって初めての席替えは少し緊張した覚えがあります。
が、気になる人が近くの席になると嬉しい。

ということで、気になる人が近くの席に座る確率を計算してくれるプログラムを
書いてみようと思います。

ペアワークがしたい

前提として、クラスにはN人の列がM列あり、M×N人の生徒がいるとします。
また、どの席も同じ確率で当たるものとします。

まず求めたいのは隣の席になる確率ですよね。
ただ、隣の席と言っても1列目と2列目3列目と4列目などで隣になった方が席が近かったり、ペアワークができたりする。

なのでこのペアワークができる隣をガチ隣と名付けて、左右を区別しない隣と区別し、どちらの確率も求めることにします。ついでに前後左右にどれかに隣接する確率も求めます。

二重ループを使う

for文の中に、さらにfor文で処理を施したものを二重ループと言います。
今回は外側のループで自分の席を、内側のループで気になる人の席を回していきます。

for(int i = 1; i <= seats; I++)           //自分を座席番号1から全て試す
    {
        for(int j = 1; j <= seats; j++)   //好きな人を座席番号1から全て試す
        { 
            //ここに処理をかく
        }
     }

if文を使う

if文は条件分岐処理を行うための命令文です。

具体的には、「条件Aが成立する場合、処理A´をする」といったことをさせるための手法です。

ここでは「席どうしの決まった関係」が条件になり、条件が成立した場合は「成立した回数を数える」という処理を行います。

例えば、条件が「左右を区別しない隣になる」とき、、、

  //自分と好きな人の座席番号がN(rows)だけ離れているとき、隣の席になる
     if(( i-j == rows) || ( j-i == rows)) 
        {
             trials++; tonari++; rinsetsu++;
           //全体の試行回数、隣が成立する回数、隣接する回数をそれぞれ1ずつ増やす   
        }

好きな人の隣になれる確率は

最後に、N(縦一列の人数)とM(列数)を入力すると、気になる人とガチ隣になる、隣になる、隣接する確率をそれぞれ求めるプログラムを書きました。

これは、上記で説明したfor文とif文の知識だけでほとんど書くことができると思います。

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    int columns, rows, seats, trials=0, gachi_tonari=0, tonari=0, rinsetsu=0;


    printf("縦と横の列の数を入力してください。\n");
    printf("\n");

   //columnsに縦列数、rowsに横列数を代入する
    printf("縦列 :"); scanf("%d",&columns);
    printf("横列 :"); scanf("%d",&rows);

    seats = columns * rows;

    for(int i = 1; i <= seats; i++)
    {
        for(int j = 1; j <= seats; j++)
        {  
      //自分と好きな人の座席番号が同じ(現実的にありえない)ときはそれ以降の処理を行わない 
            if(i == j){
                continue;       
            }
      //自分が縦1,3,5...の奇数列目にいるとき、座席番号が好きな人よりNだけ小さいならガチ隣
            if(( (i-1)/rows % 2 == 0) && ( j-i == rows ))             
            {
                trials++; gachi_tonari++; tonari++; rinsetsu++;   
            }
     //自分が縦の2,4,6...の偶数列目にいるとき、座席番号が好きな人よりNだけ大きいならガチ隣
            else if(( (i-1)/rows % 2 == 1) && ( i-j == rows))         
            {
                trials++; gachi_tonari++; tonari++; rinsetsu++;   
            }
    //自分と好きな人の座席番号がNだけ離れているとき、隣の席
            else if(( i-j == rows) || ( j-i == rows))             
            {
                trials++; tonari++; rinsetsu++;                 
            }
    //好きな人と座席番号が1つ違いのとき
            else if(( i-j == 1) || ( j-i == 1))                   
            {
      //かつ自分が一番後ろの席のとき
                if(i % rows == 0)           
                {
            //好きな人の後ろの席ならば隣接できる
                    if(i>j){                
                        trials++; rinsetsu++;
                    }
                    else{
                        trials++;
                    }  
                }
       //かつ自分が一番前の席のとき
                else if(i % rows == 1)      
                {
            //好きな人の前の席ならば隣接できる
                    if(i<j){                
                        trials++; rinsetsu++;
                    }
                    else{
                        trials++;
                    }

                }
        //このとき、先頭でも一番後ろでもなければ必ず隣接できる
                else                        
                {
                    trials++; rinsetsu++;
                }

            }
        //上記のどれにも当てはまらないとき、席は離れている
            else                            
            {
                trials++;
            }
        }
    }

    printf("座席数:%d\n", columns * rows);
    printf("組合せ総数:%d回、 ガチ隣:%d回、 隣:%d回、 隣接:%d回 \n" ,trials, gachi_tonari, tonari, rinsetsu);

    printf("ガチ隣になれる確率: %fパーセント\n", (double)gachi_tonari / trials * 100);
    printf("隣の席になれる確率: %fパーセント\n", (double)tonari / trials * 100);
    printf("席が隣接する可能性: %fパーセント\n", (double)rinsetsu / trials * 100);
}


ちなみに縦列が6列、横列が7列の教室として試してみたところ、、

座席数:42
組合せ総数:1722回、 ガチ隣:42回、 隣:70回、 隣接:142回
ガチ隣になれる確率: 2.439024パーセント
隣の席になれる確率: 4.065041パーセント
席が隣接する可能性: 8.246225パーセント

という結果でした。
とはいえ、これを知ったところで隣になれる確率が上がるわけでもないのですが…。