ヒューマン・リソース・マシーン 攻略 入社23年目 一番小さいのは?
ここで解説している内容なりヒントなりはあくまで筆者の解法に基づいたものなので、別の考え方ももちろんあるよ。ってのは念頭に置いてください。
課題
複数の「0で終わる数値グループ」があります。
各グループの中から一番小さい数字を右側に運んでください。
ただし、各グループは少なくとも1つの数値を含むものとする。
使用可能な命令
- inbox
- outbox
- copyfrom
- copyto
- add
- sub
- bump+
- bump-
- jump
- jump_if_zero
- jump_if_neg
効率目標
- サイズ:13行
- スピード:75ステップ
ヒント
その1
引いた数字をもとに戻すためには同じ数字を足せば良い。
回答例 + 解説
サイズ + スピード
回答例 + 解説
1. jump:ラベル1へ ラベル2:// 一番小さい数値を運ぶ 2. copyfrom 0 3. outbox ラベル1:// 1セットの開始位置 4. inbox 5. copyto 0 ラベル3:// 比較 6. inbox 7. jump_if_zero:ラベル2へ 8. sub 0 9. jump_if_neg:ラベル4へ 10. jump:ラベル3へ ラベル4:// 最小数値更新 11. add 0 12. copyto 0 13. jump:ラベル3へ
単純に0を拾うまで比較を繰り返すだけ。
左のパネルを取って(inbox)、初期値として保持(copyto)
次のパネルを取って(inbox)、0なら比較終了(jump_if_zero)。保持している最小数(copyfrom)を右側へ運ぶ(outbox)
0じゃないなら、今の最小数と比較して最小数の方が大きければ(sub -> jump_if_neg)、最小数を更新する。
この時、手元の数値は比較減算後の値になってしまっているため、減算に使用した値を加算しなおす(add)ことで、元の値を復元して保持(copyto)
これを0を拾うまで繰り返す(jump)
例によって無駄なジャンプが発生しないようにoutboxとinboxがつながるように配置して、初回の無駄処理(inboxより前)は実行しないように飛ばす(jump)。