Kさんが所属する軽音楽部には六つのバンドがあり,文化祭前の一週間は,部が借りている三つの練習室を放課後に使って練習する。これまでは部長が毎朝,各バンドの希望を聞いて手作業で割り当てていた。ところが,練習に必要な時間がバンドごとに違うので割当てに手間がかかり,空いている練習室を見落として,あるバンドを長く待たせてしまうこともあった。そこでKさんは,だれが行っても同じ結果になる割当ての手順を決め,プログラムで割当てを求めることにした。
放課後の時間を30分ごとに区切って,それぞれをコマと呼び,1コマ目,2コマ目,…と番号を付ける。三つの練習室には1〜3の番号が付いていて,どの練習室も1コマ目から使える。各バンドが1日に練習する時間(以下,練習時間と呼ぶ。)はコマの数で表し,練習は途中で中断せずに続けて行う。Kさんは,次の規則1〜規則3に従って割り当てることにした。
表1は,ある日の各バンドの練習時間と,規則1〜規則3によって求めた割当ての結果である。
| バンド1 | バンド2 | バンド3 | バンド4 | バンド5 | バンド6 | |
|---|---|---|---|---|---|---|
| 練習時間(コマ) | 4 | 2 | 3 | 1 | 3 | 2 |
| 練習室 | 1 | 2 | 3 | ア | ウ | ? |
| 開始のコマ | 1 | 1 | 1 | イ | ? | ? |
| 終了のコマ | 4 | 2 | 3 | ? | エ | ? |
(表の一部を“?”で隠してある)
バンド1を割り当てるときは三つの練習室がどれも1コマ目に空くので,規則2により練習室1を使う。練習時間は4コマなので1コマ目から4コマ目まで練習し,練習室1は5コマ目から再び空く。バンド2を割り当てる時点では,練習室2と練習室3がどちらも1コマ目に空くので,番号の小さい練習室2を使い,1コマ目から2コマ目まで練習する。同じように考えると,バンド3は練習室3を1コマ目から3コマ目まで使う。続くバンド4は練習室アをイコマ目から使い,バンド5は練習室ウを使ってエコマ目に練習を終える。
次にKさんは,規則1〜規則3に従って割当てを求め,バンドごとに使う練習室と練習するコマを表示するプログラムを作成した(図1)。
配列 Jikan には各バンドの練習時間を格納する。配列の添字は1から始まり,バンドの番号を表す。例えば,Jikan[3] の値はバンド3の練習時間3である。配列 Aki は,添字が練習室の番号を表し,各要素にはその練習室が次に空くコマの番号を格納する。(02)行目では,どの練習室も1コマ目から空いていることを表すため,すべての要素を1にしている。例えば,表1でバンド2の割当てが済んだ時点では,練習室2は3コマ目から空くので,Aki[2] の値は3になっている。(03)行目と(04)行目では,関数「要素数」を用いて,変数 bandsu にバンドの数を,変数 heyasu に練習室の数を代入する。
Z が [2, 7, 7, 1, 5] のとき,要素数(Z)は5となる。(05)行目からの繰り返しで,バンドを1から順に一つずつ割り当てる。変数 heya は,割り当てる練習室の候補の番号を表す。(06)行目でまず練習室1を候補とし,(07)〜(09)行目の繰り返しで練習室2以降を順に調べて,候補より早く空く練習室が見つかったら,候補をその練習室に替える。こうして規則2の練習室を決め,(10)行目でバンドの番号,練習室の番号,開始のコマと終了のコマを表示する。(11)行目では,規則3に従って,その練習室が次に空くコマを更新する。
図1のプログラムを実行すると,最初に「バンド1:練習室1,1〜4コマ目」と表示され,続けて表示された割当ては,すべて表1と一致した。
Kさんが図1の実行結果を部長に見せたところ,次のような会話になった。
Kさんは,規則3を次の規則3′に改めた。規則1と規則2は変えない。
そしてKさんは,図1のプログラムを図2のように書き直した。図2の(10)行目では,割り当てたバンドの終了のコマを変数 owari に代入し,(11)行目でそれを表示する。(12)行目では,規則3′に従って,その練習室が次に空くコマを owari を用いて求める。
図2のプログラムを実行すると,バンド1からバンド3までの表示は図1と同じであったが,バンド4からは図1と異なる割当てが表示された。
文化祭の当日は,午前中に最後の練習を行う。当日は,他校から招いた二つのバンドを加えた八つのバンドが練習し,練習室も音楽準備室を加えた四つを使える。ただし,練習室1は2コマ目まで吹奏楽部が使うので3コマ目から空き,練習室4は1コマ目に機材の点検を行うので2コマ目から空く。
Kさんは,図2の(01)行目と(02)行目を次のように変更して,当日の割当てを求めた。
このプログラムを実行すると,八つのバンドの割当てが表示される。このとき,(09)行目は全部でシ回実行される。