ヒューマン・リソース・マシーン 攻略 入社22年目 フィボナッチ数列
ここで解説している内容なりヒントなりはあくまで筆者の解法に基づいたものなので、別の考え方ももちろんあるよ。ってのは念頭に置いてください。
課題
左側の数値に対し、それ自身を超える直前までのフィボナッチ数列を右側に運んでください。
使用可能な命令
- inbox
- outbox
- copyfrom
- copyto
- add
- sub
- bump+
- bump-
- jump
- jump_if_zero
- jump_if_neg
効率目標
- サイズ:19行
- スピード:156ステップ
ヒント
その1
最初の2つの数字は1から始まるらしいから、9番のカーペットは1の方が都合がよい
最初をA=1,B=1とした場合、運ぶのはどっち?
その2
数値を入れ替える場合は仮領域を用意しよう。
実は入れ替えは[4年目]の内容だったりする。
回答例 + 解説
サイズ + スピード
回答例 + 解説
1. bump+ 9 ラベル1:// 1セットの開始位置 2. inbox 3. copyto target 4. copyfrom 9 5. copyto B ラベル2:// Aを保持して右側に運ぶ 6. copyto A 7. outbox // 終了判定 8. copyfrom target 9. sub B 10. jump_if_neg:ラベル1へ // 次の数値を算出して保持 11. copyfrom B 12. copyto temp 13. add A 14. copyto B 15. copyfrom temp 16. jump:ラベル2へ
上司から1,1から開始と言われるので、まずはA=1,B=1で処理を始める。
9番にあるのが1じゃなくて0なので1に変えてしまう。これによって初期化の時に9番が使えるようになる。
あとは計算してはA,Bに詰め替えて、Aが基準値を超えるまでAを運び続ける。
初期化用に9番を1に変える(bump+)
左のパネルを取って(inbox)、比較用に保持(copyto target)
初期値(copyto target)をBとAに保持。この後Aを運ぶのでB->Aの順に保持すると処理に無駄がなくなる。
Aを右側に運ぶ(outbox)
B(=次に運ぶ予定の数値)が基準を超えていないか判定。基準値(copyfrom target)よりBが大きい場合(sub -> jump_if_neg)は次のパネルへ
そうじゃなければ、新たな数値を算出してA,Bを更新する。
まずBを退避(copyto temp)してから、Aと合算(add)。
合算した数値をBとして保持(copyto B)し、保持しておいたBの値(copyfrom temp)をAに保持して右側に運ぶ。
これを基準値を超えるまで繰り返す(jump)