![見出し画像](https://assets.st-note.com/production/uploads/images/67792220/rectangle_large_type_2_ca962ee124d92fe33e9ac697906ce972.png?width=1200)
じゃんけんをプログラミングするよ
![画像1](https://assets.st-note.com/production/uploads/images/67792334/picture_pc_35a2a604559fd92ed7e1225b3ecff6e3.jpg)
井手広康(愛知県立小牧高等学校)
情報Ⅰが大学入学共通テストに出題されることが決まり,入試対策をどうしようと悩み転がっている今日このごろ.来年度には各教科書会社から問題集が出されるはず(希望的観測)ですが,何か参考になる問題はないだろうか?
そんなあなたにおすすめするのが,大学入試センターの「情報関係基礎」.現在,情報処理学会の情報入試委員会「情報関係基礎アーカイブ」[1]では,1997年からの過去問が公開されています.
ただ,「おすすめの問題を教えてほしい」という毎日忙しくしているあなたのために,放送大学の辰己丈夫先生が厳選した「情報関係基礎」の良問を下に紹介します.
※クリックすると「情報関係基礎アーカイブ」のPDFにとびますよ.
・2003年度 第2問 文字列の部分一致
・2005年度 第2問 じゃんけん大会
・2005年度 第4問 デジタルカメラの操作インタフェイスの改善
・2007年度 第2問 イベントを中止するかどうかのルールセット
・2012年度 第1問 送田さんと受田さんのエラー訂正
・2013年度 第2問 旅行代理店の業務改善
・2013年度 第3問 24時間営業の飲食店
・2020年度 第1問 情報の符号化とデータ量
上の問題のうち,本稿では「2005年度 第2問 じゃんけん大会」を紹介します.いま,「なんだ,ただのじゃんけんかよ」と思われた人は,ぜひ問題に挑戦して,心を折られてみてください.
問題の冒頭部分だよ
まず,問題の冒頭部分です.
![画像2](https://assets.st-note.com/production/uploads/images/67792356/picture_pc_e7f0dabdff28fc7a21044196f992df2d.png)
もしかしたら,どこかの国のじゃんけんみたいに5種類も手が出てきたり,条件を満たせばグーはパーに勝つみたいなウルトラCのルールがあるのかと思いきや,どうやら普通のじゃんけんのよう…….
大事なことは,グー,チョキ,パーの順に,1,2,3と表すということだけですね.
問1 勝つ手と負ける手を決めるよ
問1の問題です.文章を読むと,グー,チョキ,パーに勝つ手と負ける手を,それぞれKati[x]とMake[x]の配列に入れていることが分かります.
![画像3](https://assets.st-note.com/production/uploads/images/67792391/picture_pc_d3f4e88e4cf027cd757a0561a3da908b.png)
表にすると,次のようになります.これは簡単ですね.
![画像4](https://assets.st-note.com/production/uploads/images/67792400/picture_pc_334f4ad5dc23170a96582ef86647dc3b.png)
「ア」の答え:1
「イ」の答え:2
「ウ」の答え:2
「エ」の答え:3
「オ」の答え:1
問2 勝った回数をカウントするよ
問2の問題です.プログラムを見ると,繰り返しと条件分岐を使って,Aが勝った回数を,変数kaisuを使ってカウントしていることが分かります.
![画像5](https://assets.st-note.com/production/uploads/images/67792432/picture_pc_b3850646e524e460df028273ef964c19.png)
問題となるのは条件分岐の部分で,A[i] =「カ」となっています.
「はて?A[i]って何だっけ?」と思いますが,表1を見ると,どうやら「Aのi番目の手」が入っているようです.iは繰り返しによって1から10まで増えていくので,A[i]とB[i]の配列には,AとBの10個の手が入っていることが分かります.
さて,(03)~(05)行目の条件分岐の中身を見ると,A[i] =「カ」を満たすときに,kaisuの値を1増やしています.表1にkaisuは「Aが勝った回数」とあるので,この条件は「Aが勝った場合」ということが分かりますね.
ここで,「カ」に何が入れば,Aが勝ったことになるのかを考えなければいけません.
じゃんけんの結果の判定には色々なパターンが考えられますが,ここでは,問1で考えたものを使用しましょう.
たとえば,kati[1] = 3は「グー(1)に勝つのはパー(3)」という意味でした.これを踏まえて,A[i] =「カ」を考えましょう.
左辺はA[i](Aの手)となっているので,右辺のどこかにはB[i](Bの手)が入らなければいけません.ただし,そのままA[i] = B[i]とすれば,条件は「あいこ」になってしまうことが分かります.
B[i]はBの手を表しているので,右辺にはKati[B[i]]かMake[B[i]]が入りそうです.ここではB[i]に勝つ手がA[i]であればいいため,A[i] = Kati[B[i]]になることが分かります.
次は「カ」の解答群です.よって,「カ」は⑦のKati[B[i]]になります.
![画像6](https://assets.st-note.com/production/uploads/images/67792498/picture_pc_edc8fc1cd28f898e5480784b4381fd17.png)
「カ」の答え:⑦ Kati[B[i]]
問3 10人でじゃんけんするよ
問3の問題の前半部分です.10人がじゃんけんを行い,1番目の人だけの勝敗を判定すればいいらしいです.
「え? そんなのほとんどあいこじゃん?」と湧き出る疑念は振り払い,とりあえずプログラムを見ていきましょう.
![画像7](https://assets.st-note.com/production/uploads/images/67792548/picture_pc_4f61ecd4412a568f0cd620506123baa5.png)
次の表2から,Ninzu[x]には「手xを出した人数」が入ることが分かります.
たとえば,10人のうち,グーを出した人が3人であれば,Ninzu[1]には3が入るという感じです.
プログラムの(01)行目で,グーを出した人数の配列Ninzu[1],チョキを出した人数の配列Ninzu[2],パーを出した人数の配列Ninzu[3]にそれぞれ0を入れて初期化しています.
![画像8](https://assets.st-note.com/production/uploads/images/67792565/picture_pc_f5dc9ab0e74814a4b56192bce94b2d29.png)
次に,(01)~(04)行目で,iを1ずつ増やしながら,Ninzu[x]の操作を行っています.ここで表2から,Te[i]は,「i番目の人の手」が入ることが分かります.(01)~(04)行目では,10人の手のうち,グーの数をNinzu[1]に,チョキの数をNinzu[2]に,パーの数をNinzu[3]にカウントしているわけです.
次に,(05)行目では,1番目の人の手を変数aに代入しています.また,(06)行目では,1番目の人の手に「勝つ手」をbに,「負ける手」をcにそれぞれ代入しています.
次に,(07)~(15)行目において,条件分岐で1番目の人の「勝ち」「負け」「あいこ」の判定を行っていることが分かります.ここで,1番目の人が勝つ条件を考えてみましょう.
たとえば,1番目の人がグーを出した場合,2~10番目の人は,1人以上がチョキを出し,かつ,パーを出した人が1人もいない状態でなければいけません(パーが1人でもいた場合,「負け」か「あいこ」になる).
つまり,次の2つの条件を同時に満たしている必要があります.
条件Ⅰ:1番目の手に負ける手を出した人が1人以上いる
条件Ⅱ:1番目の手に勝つ手を出した人数が0である
ここで,問題となっている「キ」と「ク」の解答群は次の通りです.
![画像9](https://assets.st-note.com/production/uploads/images/67792619/picture_pc_e652f292aa7f63a13b140ce062c47095.png)
条件Ⅰは,言い換えるとNinzu[c] >= 1になります(cは1番目の人の手に負ける手).ただ,上の解答群にこの表記はありませんが,②のNinzu[c] > 0がこれと同じ意味になるので,「キ」は②が正解であることが分かります.
一方で,条件Ⅱは,言い換えるとNinzu[b] = 0となり(bは1番目の人の手に勝つ手),「ク」は⑦が正解であることが分かります.
「キ」の答え:② Ninzu[c] > 0
「ク」の答え:⑦ Ninzu[b] = 0
※「キ」と「ク」は順不同
最後に「ケ」と「コ」で,これはAが負けになる条件です.ここで,1番目の人が負ける条件を考えてみましょう.
たとえば,1番目の人がグーを出した場合,2~10番目の人は,1人以上がパーを出し,かつ,チョキを出した人が1人もいない状態でなければいけません(チョキが1人でもいた場合,「勝ち」か「あいこ」になる).
つまり,次の2つの条件を同時に満たしている必要があります.
条件Ⅲ:1番目の手に勝つ手を出した人が1人以上いる
条件Ⅳ:1番目の手に負けるを出した人数が0である
条件Ⅲは,言い換えるとNinzu[b] >= 1になります(bは1番目の人の手に勝つ手).ただ,上の解答群にこの表記はありませんが,①のNinzu[b] > 0がこれと同じ意味になるので,「ケ」は①が正解であることが分かります.
一方で,条件Ⅳは,言い換えるとNinzu[c] = 0となり(cは1番目の人の手に負ける手),「コ」は⑧が正解であることが分かります.
「ケ」の答え:① Ninzu[b] > 0
「コ」の答え:⑧ Ninzu[c] = 0
※「ケ」と「コ」は順不同
問3は,次の後半部分に続きます.
![画像10](https://assets.st-note.com/production/uploads/images/67792657/picture_pc_ab07b492775f3ada9517332de6d0caa7.png)
まず,表3のTe[i]にある10人の手を出したときのNinzu[b],つまり1番目の人の手(表3ではTe[1]が2なのでチョキ)に勝つ手(グー)の数を求めます.
グーは1なので,Te[i]が1となるi = 2, 4, 7, 8がこれに該当します.そのため,「サ」は4となります.
「サ」の答え:4
次に,1番の人が勝った場合に,他の勝者がいないときの条件を求めます.この場合は,次の条件を満たしている必要があります.
条件Ⅴ:1番目以外の全員が1番目の手に負ける手を出している
ただ,「シ」の選択肢を見ても,条件Vに該当しそうなものはありません.
そこで,(07)行目に注目します.
図3の(08.1)~(08.3)行目は(08)行目の直後に挿入されるため,(07)行目の条件である次を満たしていることになります.
条件Ⅰ:1番目の手に負ける手を出した人が1人以上いる
条件Ⅱ:1番目の手に勝つ手を出した人数が0である
条件Ⅱより,1番目の人に勝つ手を出した人が0人であることが分かっています.そのため,残りは1番目の人に負ける手か,1番目の人と同じ手ということになります.
ここで,1番の人だけが勝つためには,1番目の人と同じ手を出した人が自分しかない状態でなければいけません.つまり,これはNinzu[a] = 1を表し,解答群から「シ」には③が該当することが分かります.
「シ」の答え:③ Ninzu[a] = 1
問4 10人でじゃんけん大会するよ
問4の問題です.10人のうち3回勝つ人が現れるまでじゃんけんを繰り返すらしいです.
「え? それ結構な時間かかるよね?」と湧き出る疑念は振り払い,とりあえずプログラムを見ていきましょう.
![画像11](https://assets.st-note.com/production/uploads/images/67792707/picture_pc_f038ca3d18ffb4608852a045aaf46315.png)
問題文から,変数Kekka[i]には,i番目の人の勝った回数が入ることが分かります.ただ,この問題文からは,xとyが何を表しているのかは分かりません(最後に問われます).
(03)~(04)行目はこれまでと同じですね.
(05)行目で何やらxを1増やしています.繰り返した回数のカウントでしょうか?
(06)~(08)行目も問3と同じで,10人の手をグー,チョキ,パーのいずれかでカウントしています.
問題は(09)~(19)行目です.jを1ずつ増やしながら繰り返しています.
ここで,(10)~(11)行目が図2の(05)~(06)行目と似ており,違いは(05)行目が「a ← Te[1]」となっていることが分かります.
問3の問題では判定の対象が1番目の人に限定していましたが,この問題では3回勝つのは10人のうち誰でも構いません.そのため,すべての人に対して勝敗をチェックする必要があります.
ちょうど上の(09)行目でjを1ずつ増やしているので,「セ」には次の解答群から「① Te[j]」が入るのではないか,という予想ができます.いったん保留にしておきましょう.
![画像12](https://assets.st-note.com/production/uploads/images/67792745/picture_pc_6f8691df33d1999051ef176efdc252bf.png)
プログラムの続きを見ていきましょう.
(12)~(14)行目で,(12)行目はじゃんけんで勝つ条件でした.
じゃんけんで勝った場合,(13)行目でKekka[j]を1増やしていることが分かります.ここで,やはり変数jは人の番号を表していることが分かり,先の「セ」にはTe[j]が入ることがほぼ確定できました.
次に(15)~(18)行目です.もし「ソ」が3に等しければ,yを1増やしてjの値を表示しています.
プログラムは(21)行目を残してここで終わりになるので,何かしらの終了条件が(15)~(18)行目には入りそうです.このじゃんけん大会は,3回勝った人が現れたらプログラムを終了しますので,「ソ」には「勝った回数」が入るのではないかという予想がつきます.
また,勝った回数はKekka[i]に記録されており,この(15)~(18)行目は(09)~(19)行目の繰り返しの中に含まれているので,「ソ」には上の解答群から「⑧ Kekka[j]」が入るのではないかと予想できます.
その場合,(17)行目では,3回勝った人の番号jを表示していることになり,プログラム的にも合点がいきます.
最後に「ス」で,ここには繰り返しの条件が入ります.3回勝った人が現れたらプログラムを終了するので,言い換えれば,「3回勝つ人が現れるまで」プログラムを繰り返します.
ここで,(15)~(18)行目において,3回勝った人がいた場合,変数yを1増やしていました.つまり,「yが0の間」繰り返せばよいため,「ス」には次の解答群の「④ y = 0」が当てはまることが分かります.
![画像13](https://assets.st-note.com/production/uploads/images/67792781/picture_pc_4b68852d6cf4e17855f12bf2612eccee.png)
なお,yを1増やす作業は(09)~(19)行目の繰り返しの中にあるので,同じ回で3勝目をあげる人が複数同時に出てきても,yはその人数をしっかりカウントすることができますね.
「ス」の答え:④ y = 0
「セ」の答え:① Te[j]
「ソ」の答え:⑧ Kekka[j]
問4はもう少し続きます.
![画像14](https://assets.st-note.com/production/uploads/images/67792810/picture_pc_3a73ba2740ac216682881c069a352a21.png)
最後の(21)行目で表示される変数xとyの値を求める問題です.次が「タ」と「チ」の解答群になります.
![画像15](https://assets.st-note.com/production/uploads/images/67792844/picture_pc_eb96e79251db91d5c763927f711e5dd3.png)
まず,「タ」はxの値です.xの値に変化があるのは(05)行目だけになります.そのため,繰り返した回数(じゃんけんの回数)をカウントしており,解答群から①が正解であることが分かります.
一方,「チ」はyの値です.「ソ」の解答から,yは3勝した人数を表していることが分かっています.そのため,解答群から⑤が正解であることが分かります.
「タ」の答え:① じゃんけんの総回数
「チ」の答え:⑤ 3勝した人数
じゃんけん大会お疲れ様でした
いかがでしたでしょうか? たかが「じゃんけん」と言えど侮るなかれ.
よく知っていることでも,プログラムにするとなんだか難しく感じますね.
参考文献
1) 情報処理学会 情報入試委員会:情報関係基礎 アーカイブ
https://sites.google.com/a.ipsj.or.jp/ipsjjn/resources/JHK
(2021年11月23日受付)
(2022年2月8日note公開)
■井手広康(正会員)
愛知県立小牧高等学校情報科教諭.愛知県立大学大学院情報科学研究科博士後期課程修了,博士(情報科学).本会コンピュータと教育研究会運営委員,日本産業技術教育学会理事,日本情報科教育学会評議員など.
情報処理学会ジュニア会員へのお誘い
小中高校生,高専生本科~専攻科1年,大学学部1~3年生の皆さんは,情報処理学会に無料で入会できます.会員になると有料記事の閲覧,情報処理を学べるさまざまなイベントにお得に参加できる等のメリットがあります.ぜひ,入会をご検討ください.入会はこちらから!