Kさんの学校の印刷室には,同じ性能のコピー機が3台あり,1から3の番号が付いている。朝の授業前には,多くの先生がプリントの印刷を頼みに来る。プリントごとに枚数が違うので,印刷にかかる時間もそれぞれ異なる。事務職員のTさんは,頼まれた印刷物を決まった手順でコピー機に回し,何分目に終わるかを先生方に伝えている。Kさんは,Tさんに頼まれて,この割当てと終わる時刻をプログラムで求めることにした。
時刻は,印刷室が開いてからの「何分目」で表す。印刷は1分単位で行い,一つの印刷物を途中で止めたり,別のコピー機に移したりはしない。例えば,ある印刷物を3分目に始め,その印刷に4分かかるときは,3分目から6分目まで印刷し,そのコピー機は7分目から次の印刷物に使える。印刷室が開いたときは,3台とも1分目から使える。Tさんは,頼まれた順に番号を付けた印刷物を,次の規則1〜規則3に従って一つずつコピー機に割り当てている。
ある朝に頼まれた7件の印刷物について,印刷にかかる時間と,規則1〜規則3による割当ての結果を表1にまとめた。
| 印刷物 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| 印刷にかかる時間(分) | 5 | 3 | 8 | 4 | 6 | 2 | 7 |
| 割り当てるコピー機 | 1 | 2 | 3 | 2 | ア | ? | ? |
| 開始(分目) | 1 | 1 | 1 | 4 | イ | ? | ? |
| 終了(分目) | 5 | 3 | 8 | 7 | ウエ | ? | ? |
(表の一部を“?”で隠してある)
印刷物1を割り当てるときは3台とも1分目から使えるので,規則2によりコピー機1に割り当てる。印刷物2と印刷物3も,1分目から使えるコピー機のうち番号の最も小さいものに割り当てる。印刷物4を割り当てるときは,コピー機1が6分目,コピー機2が4分目,コピー機3が9分目から使えるので,最も早いコピー機2で4分目から7分目まで印刷する。同じように考えると,印刷物5はコピー機アでイ分目からウエ分目まで印刷する。さらに,続く印刷物6を割り当てるときに最も早く使えるようになるのは,コピー機オである。
Kさんは,規則1〜規則3に従って割当ての結果を表示するプログラムを作成した(図1)。
配列 Jikan には各印刷物の印刷にかかる時間(分)を,配列 Aki には各コピー機が次に使えるようになる分目を格納する。配列の添字は1から始まり,Jikan では印刷物の番号を,Aki ではコピー機の番号を表す。例えば,Jikan[3] の値は印刷物3の印刷にかかる時間8である。印刷室が開いたときは3台とも1分目から使えるので,(02)行目で Aki の要素をすべて1にしている。(03)行目と(04)行目では,関数「要素数」を用いて,印刷物の件数を変数 insatsusu に,コピー機の台数を変数 kopisu に代入する。
Z が [4, 9, 2] のとき,要素数(Z)は3となる。(05)〜(13)行目の繰り返しでは,印刷物 insatsu を一つずつ割り当てる。(06)〜(09)行目では,割り当てるコピー機の番号を変数 tantou に求める。まず tantou を1とし,コピー機2から番号の順に調べて,それまでの tantou のコピー機より早く使えるコピー機が見つかるたびに,tantou をそのコピー機の番号に置き換える。(10)行目では印刷を終える分目を変数 owari に求め,(11)行目と(12)行目で割当ての結果を表示し,(13)行目でそのコピー機が次に使えるようになる分目を更新する。
図1のプログラムを実行すると,最初の2行に「印刷物1:コピー機1」と「1分目から5分目まで」が表示され,表示された割当ての結果は,いずれも表1と一致した。
Y が [7, 3, 5, 3] のとき,最小番号(Y, 4)は2,最小番号(Y, 1)は1となる。Kさんは,台数ごとにすべての印刷が終わる分目を求めるプログラムを作成した(図2)。どの台数のときも,印刷室が開いたときと同じく,使うコピー機がすべて1分目から使える状態から,同じ7件の割当てを最初からやり直すものとする。配列 Aki には4台分の要素を用意し,daisu 台のときは1番目から daisu 番目までの要素だけを使う。変数 saigo は,その台数のときにそれまでに割り当てた印刷物の終了の分目のうち最も遅いものを表す。(06)行目は,図1の(10)行目と(13)行目の処理を一つにまとめたものである。
(図2の⓪〜③は,文を挿入する位置の候補を表す。⓪は(02)行目と(03)行目の間で,どの繰り返しにも入らない位置である。①は(03)行目と(04)行目の間で,(03)行目からの繰り返しの中にあり,(04)行目からの繰り返しが始まる前の位置である。②は(04)行目と(05)行目の間で,(04)行目からの繰り返しの中の位置である。③は(07)行目と(08)行目の間で,(04)行目からの繰り返しを終えた後で,(03)行目からの繰り返しの中の位置である。)
図2には,Aki と saigo に最初の値を代入する処理が抜けている。そこでKさんは,「Aki = [1, 1, 1, 1]」と「saigo = 0」の2行を,この順にスの位置に入れることにした。2行を入れた後の図2を実行すると,図3の結果が得られた。
その朝に頼まれた10件の印刷にかかる時間は,番号の順に6,2,5,3,4,7,2,5,3,4(分)であった。2行を入れた後の図2の(01)行目を次のように変更して実行すると,2行目に「コピー機3台のとき:セソ分目にすべて終わる」と表示された。