この問題はサイコロの各面が指示された操作により刻々と変化していく状態をトレース(追跡)していく,空間認識とシミュレーションの問題である.
シミュレーション方法は大きくわけて以下の 2 通りの方法が考えられる.
- サイコロを東西南北に各面が面した状態で置く置き方は,上面の目(1 〜 6)× 水平に 90 度ずつ回転(4 通り) = 24 通り ある.この 24 通りの状態の中で 6 通りの操作により状態が変化して行くのをトレースする.
- それぞれの方向を向いている面の目の数を 6 要素の配列または 6 個の変数に保持し,6 通りの操作により,変数の値を入れ替えながら状態の変化をトレースする.
この問題の場合は各ステップで上面に出ている目の数を加算していくという単純なトレースで,直前のステップまでのサイコロの動きや全体を通しての動きを調べる必要はまったくないので,どちらの方法をとっても結果は同じとなる.
しかし,前者の場合は状態間を移動する遷移関数(どの状態からどの操作をするとどの状態になるか)が状態の数(24 通り)× 操作の種類(6 通り) = 144 通り と非常に多くなるのでプログラミングにかかる時間を考慮すると後者を選択するほうが良いだろう.
初期配置および各操作による変数の値の入れ替えは以下のようになる.変数名を
上面 vTop,底面 vBottom,北面 vNorth,東面 vEast,南面 vSouth,西面 vWest
とし,初期配置を
vTop = 1, vBottom = 6, vNorth = 5, vEast = 3, vSouth = 2, vWest = 4
とする.
各操作では 2 つの面の値がそのままで,残りの 4 つの面の値が入れ替わる.
以下では 4 つの変数の値を入れ替える際の一時退避用に変数 vTemp を使っている.
- 操作 North
vEast と vWest はそのまま.
vTemp ← vTop, vTop ← vSouth, vSouth ← vBottom, vBottom ← vNorth, vNorth ← vTemp
- 操作 East
vNorth と vSouth はそのまま.
vTemp ← vTop, vTop ← vWest, vWest ← vBottom, vBottom ← vEast, vEast ← vTemp
- 操作 West
vNorth と vSouth はそのまま.
vTemp ← vTop, vTop ← vEast, vEast ← vBottom, vBottom ← vWest, vWest ← vTemp
- 操作 South
vEast と vWest はそのまま.
vTemp ← vTop, vTop ← vNorth, vNorth ← vBottom, vBottom ← vSouth, vSouth ← vTemp
- 操作 Right
vTop と vBottom はそのまま.
vTemp ← vNorth, vNorth ← vWest, vWest ← vSouth, vSouth ← vEast, vEast ← vTemp
- 操作 Left
vTop と vBottom はそのまま.
vTemp ← vNorth, vNorth ← vEast, vEast ← vSouth, vSouth ← vWest, vWest ← vTemp
変数間の値の入れ替えを繰り返すため,非常に間違えやすいので,アップロード用の出力データを作成する前に 6 種類の各操作が 1 回だけ行われる入力を自分で作成し,操作後の各変数の値を出力して確認するなどの動作テストは必須であろう.