30代SEの自由帳

最初のタイトルは頓挫した

ヒューマン・リソース・マシーン 攻略 入社38年目 数字をバラせ

ここで解説している内容なりヒントなりはあくまで筆者の解法に基づいたものなので、別の考え方ももちろんあるよ。ってのは念頭に置いてください。

課題

左側のパネルの数値を桁ごとに分解して右側へ運んで下さい。
たとえば数字が123だったら、答えは「1,2,3」になります。

使用可能な命令

  • inbox
  • outbox
  • copyfrom
  • copyto
  • add
  • sub
  • bump+
  • bump-
  • jump
  • jump_if_zero
  • jump_if_neg

効率目標

  • サイズ:30行
  • スピード:165ステップ

ヒント

その1

各桁の値を出すためには割り算をすれば良い。
割り算は[23年目]で実施済み

その2

101など、10の位が0のケースをカバーするためにはどうすればよい?

その3(スピード目標)

大きい数値はまとめて処理してしまえばよい。

回答例 + 解説

サイズ

回答例 + 解説

1. jump:ラベル1へ
ラベル210の位を運ぶ
2. copyfrom 10の位
3. outbox
ラベル31の位を運ぶ
4. copyfrom 0
5. outbox
ラベル1// 1セットの開始位置
6. inbox
7. copyto 0
8. sub 10
9. jump_if_neg:ラベル3// 10以上だった場合の処理
10. copyfrom 9
11. copyto 10の位
12. copyto 100の位
ラベル4// 100の位の算出
13. copyfrom 0
14. sub 11
15. jump_if_neg:ラベル516. copyto 0
17. bump+ 100の位
18. jump:ラベル4へ
ラベル5// 100の位を運ぶ
19. copyfrom 100の位
20. jump_if_zero:ラベル621. outbox
ラベル6// 10の位の算出
22. copyfrom 0
23. sub 10
24. jump_if_neg:ラベル225. copyto 0
26. bump+ 10の位
27. jump:ラベル6

各桁の値を出すためには割り算をすれば良い。割り算は[23年目]で実施済み。
101などに対応するため、最初に10以上かを判定するのがポイント

パネルを拾って(inbox)、一旦保持(copyto 0)
10以上か判定(sub 10)し、10より小さかった場合(jump_if_neg)は、保持したパネル(copyfrom 0)をそのまま運ぶ(outbox)
10以上の場合は各桁を計算してから運ぶ
各桁の初期化用に0を取得(copyfrom 9)し、10の位,100の位をそれぞれ初期化する(copyto)
保持している値を取得(copyfrom)し、100で割り算(sub 11 ~ bump+ 100の位)
割り切れなくなったら(jump_if_neg)、100の位(copyfrom 100の位)を運ぶ(outbox)
この時、100未満の場合は100の位が0になるため、その場合は運ばない(jump_if_zero)ようにする。※先に100以上か?の判定を入れても良いがの場合はサイズが膨れる
同様に10で割り算(sub 10 ~ bump+ 10の位)を行い、割り切れなかったら10の位を運ぶ。

例によって無駄なジャンプが発生しないようにoutboxとinboxがつながるように配置して、初回の無駄処理(inboxより前)は実行しないように飛ばす(jump)。

スピード

回答例 + 解説

1. copyfrom 11
2. add 11
3. add 11
4. copyto "300"
5. copyfrom 10
6. add 10
7. add 10
8. copyto "30"
9. jump:ラベル1へ
ラベル210の位を運ぶ
10. copyfrom 10の位
11. outbox
ラベル31の位を運ぶ
12. copyfrom 0
13. outbox
ラベル1// 1セットの開始位置
14. inbox
15. copyto 0
16. sub 10
17. jump_if_neg:ラベル3// 10以上だった場合の処理
18. copyfrom 9
19. copyto 10の位
20. copyto 100の位
ラベル4// 100の位の算出
// 300でまとめて計算
21. copyfrom 0
22. sub "300"
23. jump_if_neg:ラベル724. copyto 0
25. bump+ 100の位
26. bump+ 100の位
27. bump+ 100の位
28. jump:ラベル4へ
ラベル7// 100で計算
29. copyfrom 0
30. sub 11
31. jump_if_neg:ラベル532. copyto 0
33. bump+ 100の位
34. jump:ラベル7へ
ラベル5// 100の位を運ぶ
35. copyfrom 100の位
36. jump_if_zero:ラベル637. outbox
ラベル6// 10の位の算出
// 30でまとめて計算
38. copyfrom 0
39. sub "30"
40. jump_if_neg:ラベル841. copyto 0
42. bump+ 10の位
43. bump+ 10の位
44. bump+ 10の位
45. jump:ラベル6へ
ラベル8// 10で計算
46. copyfrom 0
47. sub 10
48. jump_if_neg:ラベル249. copyto 0
50 bump+ 10の位
51. jump:ラベル8

前述の内容でサイズ目標をクリアしている前提。
大きい数値用300/30を作って、3つ分を一気に計算して処理を短縮する

最初に300(copyfrom 11 ~ copyto "300")と30(copyfrom 10 ~ copyto "30")を作って、 あとは100/10で割っていたタイミングにそれぞれ差し込むだけ

  

<前:37年目> <目次> <次:39年目>