1)課題
左の各数値に対して、0までのカウントダウンを行い、自身を含めたすべての数値を加算した結果を出力せよ。
例えば左の数値が3である場合、右に運ぶ数値は6(=3+2+1)になります。
2)考え方
ここまでの課題をクリアーすれば, 次のような考えが浮かんでくると思います.
- 左のコンベアから取ったパネルを1つずつ減らし, その都度, 答えを書いてあるカーペットに足し込んでいけばよい.
- 左のコンベアから取ったパネルと答えのパネルをカーペットに保存する場所を用意しておく.
- 当然, 答えのパネルは0に初期化しておく.
これぐらい思いつけば, コマンドを並べて試行錯誤することで課題をクリアーできるでしょう. ここでは, もう少し落ち着いて考えていきます.
ここで, 総和を求める関数Sを考えます. 例を挙げます.
S(3) = 3 + 2 + 1
S(5) = 5 + 4 + 3 + 2 + 1
「関数S」などと書いてあると苦い経験を思い出されるかもしれませんが, 1からSに続く数字までの和を計算するすることを表す, 程度に考えてください.
さて, S(3)を例にしてもう少し考えます. S(3)は3+2+1ですが, 2+1はS(2)に相当します. ですから, S(3)は次のようにも書けます.
S(3) = 3 + S(2)
同じようにして, S(2)=2+1ですが, S(2)=2+S(1)と書けます. また, S(1)=1です. これらをまとめると次のようになります.
S(3) = 3 + S(2)
S(3) = 3 + 2 + S(1)
S(3) = 3 + 2 + 1
式を変形する途中で, できる足し算は片付けてしまいます.
S(3) = 3 + S(2)
S(3) = 5 + S(1)
S(3) = 6
ヒューマン・リソース・マシーンのプログラムにするため, もう少し式に手を加えます.
S(3) = 0 + S(3)
S(3) = 3 + S(2)
S(3) = 5 + S(1)
S(3) = 6 + S(0)
右辺の1つ目の項をカーペットの「こたえ」に, 2つ目の項をカーペットの「S」に割り当てれば, プログラムをつくれます.
3)プログラムを作る
プログラムを作っていきます.
計算するための準備をします. 所謂, 初期化です. 「こたえ」に0を配置し, 「S」に左のコンベアから取り出したパネルを配置します.
左のコンベアから取り出し, 「S」に配置したパネルを「こたえ」に足し込みつつ, 「S」を1つずつ減らしています. 左のコンベアから取り出したパネルが3でしたので, 「S」が0になった時に「こたえ」が6になっており, 期待通りの結果が得られました. 「S」が0になった時, 「こたえ」を右のコンベアに運べば上司の要求に応えられます.
9行目にJUMP if zeroコマンドを追加して, 「S」が0になった時に「こたえ」を右のコンベアに運ぶようにしました. うまく計算できているようですが, 図では「S」が-1となっています. 0ではありませんので, 無限ループに入ってしまいます.
9行目をJUMP if zeroコマンドからJUMP if negativeコマンドに変更し, 無限ループを回避します. また, この変更により, 「こたえ」に0を加えることになりますが, 結果に変わりはありませんのでこのままとします.
課題をクリアーできました. スピード目標を達成するためには, 左のコンベアから取り出したパネルが0の時, そのまま右のコンベアに運ぶ, といった工夫が必要です.
0 件のコメント:
コメントを投稿