30代SEの自由帳

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

ヒューマン・リソース・マシーン 攻略 入社36年目 辞書順に並べよ

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

課題

左側のコンベアに2つの単語が運ばれてきます。
辞書順で並べたときに、先に来る単語を右側に運んでください。

使用可能な命令

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

効率目標

  • サイズ:39行
  • スピード:109ステップ

ヒント

その1

辞書順ということはアルファベットの早い順。
文字同士であれば数値と同じように比較できる。

その2

「辞書順に並べよ」とは言っているけど、
カーペットに並べるのは最初の単語だけで良い。

その3

カーペットに順番に並べるのは32年目に実施済み。

回答例 + 解説

サイズ + スピード

回答例 + 解説

1. copyfrom 23
2. copyto idx
ラベル1// 1つ目の単語をカーペットに並べる
3. inbox
4. copyto [idx]
5. jump_if_zero:ラベル2
6. bump+ idx
7. jump:ラベル1へ
ラベル2// 2つ目の単語用に初期化
8. copyto idx
ラベル3// 2つ目の単語と比較
9. inbox
10. jump_if_zero:ラベル411. copyto 2nd
12. copyfrom [idx]
13. jump_if_zero:ラベル414. sub 2nd
15. jump_if_zero:ラベル516. jump_if_neg:ラベル6// 2つ目の単語を採用
17. copyfrom 2nd // このパスに来る際は必ず手元に0がある状態なので、改めて0を拾う必要ない
ラベル7// 2つ目の単語を右に運ぶ
18. outbox
19. inbox
20. jump_if_zero:ラベル421. jump:ラベル7へ
ラベル6// 1つ目の単語を右に運ぶ
22. copyfrom [idx]
23. jump_if_zero:ラベル424. outbox
25. bump+ idx
26. jump:ラベル6へ
ラベル5// 同じなのでとりあえず1文字運ぶ。同じ=ここまで単語が一致している状況なのでどちらを運んでもOK
27. copyfrom 2nd
28. outbox
29. bump+ idx
30. jump:ラベル3へ
ラベル4// 処理終了

「辞書順に並べよ」とは言っているけど、カーペットに並べるのは最初の単語だけで良い。カーペットに順番に並べるのは32年目に実施済み。
文字同士であれば数値と同じように比較できるため、2つ目の単語を都度カーペットの単語と比較すれば良い。
ただ、最初から配置されてる10は何に使うんだろうか。。カーペットもやたら広いから何かありそうだけど、思いつかないから別の機会に

初期値として0を拾って(copyfrom 23)、参照位置を初期化(copyto idx)
最初の単語を順番にカーペットに並べる。
左のパネルを拾って(index)、0を拾う(jump_if_zero)まで順番にカーペットに並べ続ける(copyto[idx]->bump+ idx -> jump)
この時、終端判定用に0もカーペットに並べる

0を拾ったら、比較参照用に参照位置を初期化(copyto)し、2つ目の単語との比較を開始。
パネルを拾って(inbox)、0なら(jump_if_zero)終了
0じゃなければ、比較用に一旦保持(copyto)し1つ目の単語と比較。 1つ目の単語の対応位置の文字を取得(copyfrom)して0なら(jump_if_zero)終了、
0じゃなければ、保持していた文字と比較(sub)
同じ場合(jump_if_zero)、対象が決まらないのでとりあえず1文字運ぶ。
2つ目の単語の方大きい(=辞書順が後ろ)の場合(jump_if_neg)、1つ目の単語で確定のため、1つ目の単語を運ぶ。
そうじゃない場合、2つ目の単語で確定のため、2つ目の単語を運ぶ。

  • とりあえず1文字運ぶ:
     保持していた文字を取得(copyfrom 2nd)し、右へ運ぶ(outbox)
     参照位置を更新(bump+)して、次の文字へ(jump)

  • 1つ目の単語を運ぶ
     1つ目の単語の参照位置の文字を取得(copyfrom [idx])し、右へ運ぶ(outbox)
     参照位置を更新(bump+)して、0を拾う(jump_if_zero)まで順次運んでいく(jump)

  • 2つ目の単語を運ぶ
     保持していた文字を取得(copyfrom 2nd)し、右へ運ぶ(outbox)
     次のパネルを拾って(inbox)、0を拾う(jump_if_zero)まで順次運んでいく(jump)

  

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