プログラミング第14回 共通テスト「情報」のサンプル問題をなでしこを使って解く

今回学ぶこと

共通テスト「情報」のサンプル問題(令和3年3月24日)をなでしこを使って解いてみる

令和3年3月24日に公開された共通テストのサンプル問題は第2問がプログラミングを扱った問題になっています。

2024年現在、少なくとも高松市の公立高校では、学校からプログラミングについてほとんど説明がなく何をしていいかわからない方が多いかと思います。何もわからなければプログラミングの問題を敬遠してしまうと思いますが、本ブログでここまでプログラミングの学習をしてきた方は共通テストのサンプル問題を解く力を十分にもっています。

さっそく問題文を見てみましょう。まずは問1です。

問1の問題文の概要は次の通りです。

  • 議席数は6
  • 得票の総数(3480)を議席数(6)で割ると 580 となる。これを基準得票数と呼ぶ。
  • 各政党の得票数が何議席分に相当するかは、各政党の得票数を基準得票数で割ればよい。


 問題文に従って各政党の得票数が何議席分になるかをプログラムしていきます。図4の結果になるように、図3に適切なプログラムを入力していきます。

 配列変数と繰り返しの制御構文を使った問題ですね。これをなでしこを使ってプログラムしていきます。


共通テストのサンプル問題のプログラムに寄せて書きました。
なでしこは繰り返しの最後に「ここまで」が必要になるなど記述のルールが多少違いますが、ほぼサンプル問題通りにプログラムできました。当然プログラムの結果も同じです。

サンプル問題にあるように、これだと議席が小数になってしまい、切り上げても切り捨てても四捨五入してもうまくいきません。
そこで、先生に相談するという形で問2につながっていきます。

問2では相談された先生が比例代表選挙で使われている「ドント方式」でプログラムすることを提案します。問題文は次の通りです。

ドント方式の説明がなされます。ドント方式を知らなくても問題ありません。問題文は次に続きます。


これはプログラミングの問題というか読み取り問題ですね。

問題文に書いているように「当選者が1人増えるごとに得票数を『当選者数+1』で割る」というルールで計算していけばいいだけですね。

 次の問3では問2の手順をプログラムしていきます。まず問題文です。

これをなでしこでプログラムしていきます。


なでしこを使ってほぼ同じプログラムを作ることができました。

異なる点は、なでしこは繰り返しや条件分岐ごとに「ここまで」が必要になります。「ここまで」が対応している箇所を色分けしています。

また、Hikaku[m] は Hiakaku という配列変数の m 番目の要素を表すのですが、Hikaku という配列変数を最初に定義しておかないとうまく作動しないみたいです。

Hikaku[m]=Tokuhyo[m] は Hikaku という配列変数の m 番目の要素は Tokuhyo という配列変数の m 番目の要素と同じとすることを表しているので、最初に定義する Hikaku は空の配列変数でOKです。

それ以外には、なでしこでは「切り捨て」ではなく「切り下げ」とする点ですね。

 ちょっと何をしているかわかりにくいかもしれませんので、それぞれの箇所について説明していきます。

 まずは①の箇所です。

 次は②③の繰り返しの箇所です。

このように②と③の処理を繰り返します。なんとなくどのような処理が行われているかわかって頂けたかと思います。
それでは、tosenkei=5 のとき以降を見ていきます。

 最後に④の処理です。


問3の前半の説明は以上です。

 共通テストサンプル問題はさらに続きます。問3の後半の問題は次の通りです。

 候補者が不足した場合に Hikaku=[] が次に多い党に議席を回すようにプログラムするわけですね。先ほどの問3前半の②③の繰り返し部分の仕組みがわかれば大丈夫ですね。

 ②③の繰り返し部分で、max や maxi に該当した党に議席が割り振られました。ということは、候補者が不足した政党に議席が割り振られないようにするには max や maxi に該当しないようにプログラムしてやればいいわけですね。


サンプル問題は選択肢に「koho[i]>Tosen[i]」がないので、「koho[i]>=Tosen[i]+1」が答えとなります。

max や maxi に該当する条件なので、「koho[i]>=Tosen[i]」としてしまうと獲得した議席が候補者の数と同じときも max や maxi に該当してしまい、候補者の数を超えてさらに議席を獲得してしまいます。

また、サンプル問題の選択肢は「and」ですが「かつ」を使っています。アルファベットばかりで見にくかったので見やすさ重視で「かつ」を使いまいした。「かつ」を「and」に変えてもらっても作動します。

これで共通テストサンプル問題の第2問は終了です。サンプル問題は「なでしこ」を使ってほぼ同じようなプログラムを作れましたので、少なくともこのサンプル問題を解けるレベルに至るには「なでしこ」で十分かと思います。

日本語ベースでプログラムを学べて、アプリのインストールも不要なため手軽にスマホで扱える「なでしこ」は中高生が初めに学ぶべきプログラミング言語として非常にお勧めできます。まずは「なでしこ」でプログラミングの基礎を学び、次に「phython」などに移る方が挫折することなく学んでいけるため、もっと多くの中学・高校で「なでしこ」を使ってプログラミングの基礎からしっかりと教える授業を行って欲しいですね。

それでは今回の問題です。

問題

共通テストサンプル問題の第2問 問3の問題文の最後に次のような記述があったかと思います。

まず、これがどういうことか確認してみます。

D党の得票数を「480」に変更すると、6番目の議席をめぐってC党とD党が同じ値となります。6番目の議席はC党とD党のどちらのものになるでしょうか?

プログラムでD党の得票数を「480」に変更すると

次はB党の得票数を「960」にしてみます。

6番目の議席はB党とC党のどちらが獲得できるでしょうか?

なぜこのようなことが起こるかと言うと

i に要素を 0 から順に代入し、Hikaku[i] が最も大きいものが max となり、議席が1増えます。
Hikaku[i] の値が同じものが複数あれば最初に max になったものが max の状態を維持します。

それでは、添字(要素番号)が小さい方が有利になっている状況をくじを使って解消してみましょう。
くじはコインの表裏のような 1/2 の確率としましょう。今まで学んだ知識を使えばできます。

ヒントは表示しますので、空欄を埋めてください。

無事にプログラムが完成すれば実行ボタンを押す度に、6議席目がB党に入る場合とC党に入る場合がランダムに切り替わるはずです。