気が付けばとっくに今日は終わって昨日のこととなってしまい、これを書いているのは実は明日だったという話だ。

 どこか裏の方から戻って来た店主は、床に散らばった本には目もくれず、五連休だシルバーウイークだとかいってもそんなに休んでばかりはいられない。たまっている仕事を片付けなくてはと、パソコンの電源を入れブラウザを開いた。「今、お気に入りの音楽教えて!」とか「お彼岸スペシャル。あなたの、一番好きな“おはぎ”の種類は?」とかいうネタが並んでいるのを見たが、どうも気乗りしない様子でブラウザを閉じ、DOSプロンプトを開いた。

| コメント(4) | トラックバック(0)

 酒場の店主が、本棚の奥から何やらカラフルな立方体(以下、「ルービックキューブ」と書く)を取り出した。
 「このところ、残念な物語が考えられなくなるという原因不明の症状が続いているので、今回は、このルービックキューブの話でもしてみようかと思います」
 前から少しおかしなところがあるとは思っていたが、いよいよ残念な兆候があらわれてきたようた。誰もいない店内で、店主は以下のような話を口走った。

 ルービックキューブが日本で発売された1980年、僕は浪人生をやっていました。雑誌の記事で面白そうな立体パズルがあると知り、百貨店の玩具売り場や玩具専門店を捜し回って、ようやく現物を手に入れました。それは使っているうちにシールがはがれてしまうという粗悪な模造品でしたが、構造は本物と同じだったので特に問題はありません。

 さて、僕が手にしているこのキューブは(実は現実の世界では僕の目の前に現物はないのですが)、立方体を3×3×3個に賽の目切りにしたような物で、大きな立方体の表面は、それぞれ異なる色に塗り分けられています。(図1

 大きな立方体の同じ面を共有する小立方体(3×3個)は、表面中央の小立方体と裏面中央の小立方体を結ぶ線を軸にして(90度ずつ)自由に回転できるような構造になっています。回転軸は3本あります。何回か軸を適当に変えながら回転していくと、小さな立方体の位置が変化して、大きな立方体の各面の色は入り交じった状態になってしまいます。
 論理的には、「今やったこと」を逆の順番で逆に回転させて行けば元の状態に戻る筈ですが、見かけの単純さにすっかり騙されて、うかつにも「今やったこと」を記憶も記録もしていなかった僕は元に戻す手順が分からず、さらに出鱈目に回し続けるしかありませんでした。そして、何日間か闇雲にいじくり回しているうちに、偶然、元の状態に戻すことができました。

 多くの人が知っているルービックキューブについて必要以上に詳しく説明してしまいましたが、それはこの立体パズルのシンプルな美しさを頭の中に思い描いてもらいたかったからなのです。

 僕は、偶然元に戻せただけでは納得できず、この難しいパズルの正体を突き止めてやろうと思いました。いつでも最初の状態に戻せるように紙に記録を取りながら、「少し崩しては戻す」という操作を、しつこく繰り返しました。その当時の記録も手元にはないのですが、展開図の各面を9分割して色を表わす記号を書き込んだものでした。(図2

 例えば、赤の面を右に90度回した場合は、図3のように変化します。こうやって、何度も回転しては同じような図を書いていきました。

 今にして思えば、ルービックキューブの解法を調べるのために何十枚も図を書く必要はありませんでした。図2図3だけあれば充分だったのです。

 ここで、店主は口を噤み、どこかへ出て行った。たぶん現実の仕事の時間が迫っていたのだろう。


| コメント(2) | トラックバック(1)

 ――現実の仕事から戻るなり、店主はルービックキューブをパッケージから取り出していじり始めた。どこかに寄り道して買って来たのだろう。誰もいない店内で、店主は何やら独り言をぶつぶつとつぶやいている。

 赤の面を「右へ1/4回転」すると、キューブの状態は前回書いた(図2)から(図3)のように変化します。このときの操作を、「Red」の頭文字をとって「R」と書くことにしましょうか。ついでに、他の面についても、同様に「W」・「G」・「Y」・「O」・「B」と書くことにします。このときに変化する部分を(図4)に示します。

 こうすると、「白・緑・赤・黄・橙・青の各面の右への1/4回転」は、「W,G,R,Y,O,B」という6個のアルファベットで表わせるようになります。そして、驚くべきことに(別に驚かなくてもいいですけど)、ルービックキューブに対する全ての操作(ただし分解と組み立てを除く)は、この6文字の並びだけで記述できることになります。つまり、ルービックキューブの取り得る状態は、全部、(図4)の変化の組み合わせで実現可能なのです。

 例えば、「Rの面を右へ1/4回転した後、Yの面を右に3/4回転する」は、

R+Y+Y+Y

のように書きますが、さすがにこのままでは面倒です。「右へ3/4回転」は「左へ1/4回転」と同じことなので、「Y+Y+Y」を「-Y」にして、

R-Y

と書いた方がシンプルだし、実際の手順も簡単になります。これを21回繰り返す場合は、

21(R-Y)

と書くことにします。この後に「Rの面を左に1/4回転した後、Yの面を右に1/4回転する」を21回繰り返す操作を付け加えると、

21(R-Y)+21(-R+Y)

となります。これを実際にやった結果は(図5)のようになります。

 ちょっと脱線しますが、この「2個のコーナーキューブの向きを変えるための84ステップの手順」は、恐らくどの攻略本にも掲載されていないでしょう。
 自慢ではありませんが、この手順はキューブを適当に(ある程度は規則的に)回しているうちに偶然見つけました。そのころ見つけた手順のうち、覚えているのはこれだけですが、先にエッジを完全に揃えておいて最後にコーナーの向きを合わせるという、これまた攻略本には載っていないやり方でした。
 脱線したついでに言っておきますが、最短の手順をマスターして6面揃えるスピードを競っているのを見ると、確かに凄いなーとは思うけれども、面白がるポイントがずれているように感じてしまいます。考案者のルービックさんも、それを見て、つい「リベンジ」したくなったんではなかろうかなどと、勝手な妄想をしています。

 「Rの面を右へ1/4回転する」を2回続けるときは「2R」と書くことにします。

2R+2O+2G+2Y+2W+2B

 この「R・O」、「G・Y」、「W・B」は、それぞれ反対側の面のペアになっているので、さらに以下のように簡略化することにします。

2RO+2GY+2WB

 この結果がどうなるかを想像してみてください。

 ――ここで店主は、午後の光が傾き始めているのを見て、口を噤んだ。


| コメント(1) | トラックバック(0)

 ――店主は今日もまた、独り言を続けている。

 いくら何でも「21(R-Y)+21(-R+Y)」を偶然見つけるなんて、確率的にはほとんど有り得ないだろうと思いました。僕は一体どうやってこの手順にたどりついたんだろうか…。そう考えてみても、ちっとも思い出せませんでした。

 しかし、「2個のコーナーキューブの向きを変える84ステップの手順」を知っていることは間違いないし、現物を使ってやってみると確かにコーナーキューブの向きが変わりました。だいたい、この「21回繰り返し」という手順はどこから出てきたのか?

 そんなことをぼんやり考えながら何度もキューブを回しているうちに、どこかで手順を間違ったらしく、元に戻らなくなってしまいました。そこで、当時のやり方でエッジキューブの色から揃えていきました。エッジだけなら完全な解法を知らなくても適当にやっていけば何とか揃います。コーナーキューブもいくつかは正しい位置に入っています。

 そこで、位置だけは正しいコーナーキューブの向きを揃えるために、例の84ステップを(今度は間違わないように)慎重に2ステップずつ数えながらやっていきました。すると、7の倍数(つまり14の倍数のステップ)のときに、エッジキューブが正しい位置に正しい向きで戻ってくることに気付きました。しかし、コーナーキューブは相変わらずバラバラのままです。このとき、やっと思い出しました。この14ステップで、エッジキューブの位置と向きを保存したまま、コーナーキューブの位置や向きを変えることができるのです。

 いろいろ試してみた結果、隣り合った面Pと面Qに関して、以下の操作を加えると、エッジキューブの状態を崩すことなく、6個のコーナーキューブの位置や向きを変えられることが分かりました。

7(P+Q), 7(P-Q), 7(-P+Q), 7(-P-Q),
7(Q+P), 7(Q-P), 7(-Q+P), 7(-Q-P)

 当時は、この手順と結果をメモしておいて使い分けていたのだろうと思います。これをいろんな面のペアに対して繰り返していけば、コーナーキューブの位置を全部合わせることができそうです。そして、最後の仕上げでコーナーキューブの向きを揃える手順が、例の84ステップだったのでしょう。道理でほかの手順をすっかり忘れてしまっているわけです。

 そして、(P-Q)や(-P+Q)のように隣り合った面を互いに逆方向に回転させる場合は、3回(6ステップ)ごとに、コーナーキューブが元の位置に戻る(ただし向きは一定方向にずれる)ことが分かりました。9回(18ステップ)目には、元の位置・元の向きに戻ります。ということは、21回(42ステップ)目には、エッジキューブの位置と向きが元に戻り、かつ、コーナーキューブは位置だけが正しい状態になるわけです。

 その後、同じ面のペアをさっきとは逆方向に回転する手順に切り換えて21回繰り返すと、2つの面に共有されるコーナーキューブの向きだけが変化して、他のキューブは最初の状態に戻りました。おそらく、片方の面に属するコーナーキューブでは、前半の21回(42ステップ)で生じた向きのずれが後半の21回(42ステップ)によって相殺されたのでしょう。

 この件については、後日改めて詳しく検証してから補足したいと思います。

 ――店主は、喋り疲れたのか、奥に引っ込んで昼寝を始めた。

| コメント(3) | トラックバック(0)

 ――このところルービックキューブにのめり込んでいる店主は、今日もまた一人でつぶやいている。

 展開図を回転して「r3」が「r1」に変化するなんていうのは、どうもピンとこないよな。それに「r3」が「y1」や「w9」と頂点を共有しているというのをいちいち展開図で確認しなくてはならないのも面倒くさいし、この番号の付け方が面の向きによってバラバラになってしまうも気に入らない。このままで、キューブの動きをシミュレートするプログラムを作ろうとすると、どの面とどの面がつながっているのかを書かなきゃならないだろう。

 これを何とかすっきり書けるようにしたいものだ。だけど、「群論」なんていう難しいことを考えたくはない。別に数学の論文を書こうとしているわけでもないし、最短の手順を探索するプログラム作りに挑戦しようとしているのでもない。単純にキューブの動きをシミュレートしたいだけなのだから…。

 そんなことをぼんやり考えながら、ランダムな回転操作(左手を使って背後で回すと、よく分からなくなる)を数回繰り返して、ほどほどに崩れたところから数回の手順で元に戻す一人遊び(詰めキューブ?)をやっていた。定型的な解法に頼らず、色の配置を見てその都度考えることになるので、何べんやっても飽きがこない。訳も分からず暗記した解法を使って元に戻してもちっとも面白くない。そんなのは、解の公式を使って二次方程式を解くようなものだ。

 そのとき突然、ひらめいた。立体なんだから平面上で考えるより空間で考えりゃいいんだ。なんだ、簡単じゃないか。(x, y, z)を使ってキューブを識別すれば、どの面とどの面がつながっているかをいちいち考えずにすむ。複数の面を持ったキューブ自体を移動させれば計算もシンプルになるはずだ。なるほど、面を倒したりして考えていたから面倒なことになっていたんだな。

 ――結局、最後は駄洒落かよ。ひねりが足りんな。


| コメント(0) | トラックバック(0)

 ――ひねりが足りんな。

 すると、店主がこちらを向いてこう言った。
 「ひねりだって…? そうそう、キューブの向きのことをまだ考えてなかったな」

 ――ここに書いたことがそのまま聞こえているのか? 一体どうなっているんだ?

 「今さら何を言ってるんだ。そんなところに突っ立ってないで、あんたも少し手伝ってくれよ」

 ――それじゃ仕方がないな。

 「この“ひねり”をどうするかが問題なんだよな…」

 ――それは小キューブのデータの中に入れてしまえばいいんじゃないか?

 「ははあ、小キューブをカプセル化して、あとはオブジェクトに任せるというわけか」

 ――何もそこまでやらなくても、perl4で十分だよ。適当な連想配列に位置と一緒に入れるだけだよ。これを仮に%cubesとして、例えば、最初に図7の(1, 1, 1)の位置にあった小キューブに関する位置と向きのデータが欲しければ、$cubes{'1,1,1'}を見るって感じで…。ここに、現在位置(x, y, z)と回転状態(i, j, k)を一緒に入れておけばいいだろう。

 「コーナーキューブの向きは3通りだから(i, j, k)でいいと思うけど、エッジキューブの向きは2通りだけだよね。それに、いつ、どの段階で小キューブの向きがズレたり反転したりするのかと考えると、よく分からなくなるんだけど…」

 ――それは、キューブの色が揃っていると、ズレたり反転したりしてるようには見えにくいけど、操作する毎にX・Y・Zのどれか一つを軸にして回ってるんだから、その段階で向きが変化してると考えた方がいい。その回転状態を(i, j, k)で表わすと、X軸を中心に90度右に回転すると(1, 0, 0)になり、続けてY軸を中心に左に90度回転すると(1, 3, 0)となる。これは、コーナーもエッジもセンターも区別せず、全部同じでいい。

 「ちょっと待ってくれよ。なぜ同じなんだ?」

 ――9個の小キューブが一緒に回転してるんだから同じでなきゃ変じゃないか?

 「そう言われると、そんな気もしてくるけど、何だかどうもうまく騙されてるような気がするな…」

 ――じゃあ、こう考えてみたらどうかな。例えば、一連の操作をした結果、(1, 3, 1)にあった小キューブが(1, 1, 3)に移動したとしようか。その小キューブの向きの情報(i, j. k)を見れば、どの軸の回転で移動したのかが分かる。(2, 0, 0)だったらX軸で180度、(1, 3, 0)だったらX軸で90度とY軸で-90度の組み合わせ、(0, 3, 3)だったらY軸で-90度とZ軸で-90度の組み合わせだということが分かる。

 「コーナーキューブはそれでいいだろうけど、エッジキューブの場合はどうなるんだ?」

 ――同じように何回か操作をしたら、(1, 2, 1)にあった小キューブが(1, 1, 2)に移動した場合について考えてみようか。向きが(1, 0, 0)だったらX軸で90度、(0, 3, 3)だったらY軸で-90度とZ軸で-90度の組み合わせ、(3, 2, 2)だったらX軸で-90度とY軸で180度とZ軸で180度の組み合わせだということになる。

 もちろん、もっと複雑な操作をした場合は、そう単純には言えないだろうけれども…。

 「いや、僕は解法をプログラムで探索したいわけじゃなくて、シミュレーションできればそれでいいんだ」

 ――そうか、それは残念だな。まあ、位置と向きの情報さえあれば、一連の操作の結果、どこが何色になるかぐらいは簡単に表示できると思うよ。出力の書式はリストよりも、やっぱり展開図みたいなやつの方がいいのかな?

 「そりゃあ、もちろん、現物の形に近い方がありがたいよ」

 ――展開図を見て、“こう操作したら、こうなった”というのを見るわけだよね? 現物を使ってやるのと同じように?

 「そうだよ。現物は元に戻すのに時間がかかるし、結果を記録するのも面倒だから」

 ――じゃあ、最後の展開図の前に、途中経過のデータも出力するようにしておこうか?

 「そうだなあ…。途中は省いて、最後のデータだけ出してくれればいいや」

 ――ここで、僕はperlスクリプトを書いてみた。展開図の表示は面倒なので後回しにして、とりあえず操作前後で変化した各キューブのデータだけを出力するようにした。ちょっと試してみたところ、位置に関しては期待した通りの結果が出た。しかしどうも向きのデータが怪しい。

 そこで、二つのコーナーキューブの向きだけが変化する例の84手の操作パターンを入れてみた。すると、どういうわけか、二つのキューブの向きを表わす(i, j, k)の値が両方とも(2, 2, 0)になってしまう。向きが逆向きにずれるのだから、二つの向きは違っていなければならない筈だ。

 それで初めて気付いたのだが、X軸で90度回転した小キューブをY軸で-90度回転するのだから、元の向きで考えるとZ軸で-90度回転することになるのだった。つまり、(1, 3, 0)ではなくて(1, 0, 3)にしなくてはならなかったのだ。これはややこしいことになってしまった。

 結局、向きの情報を(i, j, k)で表わすのはあきらめて、小キューブの6面の色を6個の記号で表わすことにした。そして、回転操作をする度に小キューブの各面の移動を6個の記号の移動に対応させるようにした。これでたぶん大丈夫だろう。その結果は以下の通りだ。

operators='1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y'
(111,RYW---)->(313,-Y-R-W)
(113,RY---B)->(133,B---YR)
(131,R-W-G-)->(113,RG---W)
(133,R---GB)->(131,G-B-R-)
(311,-YWO--)->(111,OWY---)
(313,-Y-O-B)->(311,-OBY--)
operators='1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y'
(313,-Y-R-W)->(311,-RWY--)
(133,B---YR)->(131,Y-R-B-)
(113,RG---W)->(133,W---GR)
(131,G-B-R-)->(113,GR---B)
(111,OWY---)->(313,-W-O-Y)
(311,-OBY--)->(111,YBO---)
operators='1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y,1R,3Y'
(311,-RWY--)->(111,YWR---)
(131,Y-R-B-)->(113,YB---R)
(133,W---GR)->(131,G-R-W-)
(113,GR---B)->(133,B---RG)
(313,-W-O-Y)->(311,-OYW--)
(111,YBO---)->(313,-B-Y-O)
operators='3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y'
(111,YWR---)->(131,R-Y-W-)
(113,YB---R)->(311,-BRY--)
(131,G-R-W-)->(133,W---GR)
(133,B---RG)->(111,BRG---)
(311,-OYW--)->(313,-W-O-Y)
(313,-B-Y-O)->(113,YO---B)
operators='3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y'
(131,R-Y-W-)->(133,W---RY)
(311,-BRY--)->(313,-Y-B-R)
(133,W---GR)->(111,WGR---)
(111,BRG---)->(131,G-B-R-)
(313,-W-O-Y)->(113,OY---W)
(113,YO---B)->(311,-OBY--)
operators='3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y,3R,1Y'
(133,W---RY)->(111,WRY---)
(313,-Y-B-R)->(113,BR---Y)
(111,WGR---)->(131,R-W-G-)
(131,G-B-R-)->(133,R---GB)
(113,OY---W)->(311,-YWO--)
(311,-OBY--)->(313,-Y-O-B)

 エッジキューブの位置と向きが正しくなる7周期ずつに区切って操作記号を与えたので、変化を受けるコーナーキューブだけが表示されている。最終的な結果は(1,1,1)と(1,1,3)のキューブ以外は最初の状態に戻っているので、今度は間違いないだろう。

 これを見て、店主が言った。
 「位置はこれでも分かるけど、色のところがさっぱり分からんな…。やっぱり展開図の方がいいや。まだできてないの?」

 ――それは、もう少し待ってくれよ…。

| コメント(2) | トラックバック(0)

 ――ここまで出来たら、展開図を表示するのは簡単に追加できる。とは言っても、けっこう面倒臭い作業になるから後回しにして…。その前に、小キューブの“ひねり”をもっとスマートに算出する方法を考えてみようかと思うんだけど。

 「じゃ、展開図の部分は、僕がやっとくよ。この表示データから変換するだけでいいんだろ」
 そう言って、店主は前回の囲み部分をコピーしようとした。

 ――ちょっと待った。向きのデータを追加するから、こっちの方を使ってくれよ。

(111,000,RYW---)->(111,???,WRY---)
(112,000,RY----)->(112,000,RY----)
(113,000,RY---B)->(113,???,BR---Y)
(121,000,R-W---)->(121,000,R-W---)
(122,000,R-----)->(122,000,R-----)
(123,000,R----B)->(123,000,R----B)
(131,000,R-W-G-)->(131,000,R-W-G-)
(132,000,R---G-)->(132,000,R---G-)
(133,000,R---GB)->(133,000,R---GB)
(211,000,-YW---)->(211,000,-YW---)
(212,000,-Y----)->(212,000,-Y----)
(213,000,-Y---B)->(213,000,-Y---B)
(221,000,--W---)->(221,000,--W---)
(222,000,------)->(222,000,------)
(223,000,-----B)->(223,000,-----B)
(231,000,--W-G-)->(231,000,--W-G-)
(232,000,----G-)->(232,000,----G-)
(233,000,----GB)->(233,000,----GB)
(311,000,-YWO--)->(311,000,-YWO--)
(312,000,-Y-O--)->(312,000,-Y-O--)
(313,000,-Y-O-B)->(313,000,-Y-O-B)
(321,000,--WO--)->(321,000,--WO--)
(322,000,---O--)->(322,000,---O--)
(323,000,---O-B)->(323,000,---O-B)
(331,000,--WOG-)->(331,000,--WOG-)
(332,000,---OG-)->(332,000,---OG-)
(333,000,---OGB)->(333,000,---OGB)

 ――やりやすいように、全部表示させたから。あと、「???」のところは'0'~'3'が入る筈なんだけど、実際の数値がまだ分からないんで…。

 「おおっ、これは有り難い! あれっ? 向きのデータは3桁でいいの? 6桁になるかと思ってたんだけど」

 ――なぜ6桁も必要なんだ? X・Y・Z軸で回転するんだから(i, j, k)の3個で充分だろう。

 「いや、小キューブがどの面でどれだけ回転したのかを表示すれば簡単になるかと思ったから」

 ――いやいや、そのやり方では小キューブの向きとは一致しなくなることが分かったから、今、どうしようかと考えてるんじゃないか。

 「あっ、そうか。今ちょっと別のことを考えてたから。小キューブが、どこの面でどれだけ回転したかが分かれば役に立つかなって…」

 ――それは面白いな。小キューブの履歴を保存するわけだな。状態とは別のデータでやってみよう。とりあえず、状態の表示はさっきの3桁でやるから、それで進めておいてくれよ。

 「了解」

 ――店主は、上の引用部分をマウスで選択して、そのまま自分のノートパソコンまでドラッグしていって、エディタの中にドロップした。一体どうなってるんだ、この世界は?

| コメント(0) | トラックバック(0)

 ――その次の夜、語り姫は話の続きを語った。

 おお、幸多き王様、第一の鼠はこのように語ったのです。

 ある研究施設の実験で鼠に移植された私の脳は、来る日も来る日も繰り返される迷路の実験に飽き飽きしていました。(こんな単純な迷路なんて、ちっとも面白くない)と、私は思いました。すると、私の脳の中で、こんな声が聞こえました。
 (ねずみさん、ねずみさん)
 それは、私が迷路の中で餌の在りかを捜していると、ときどき私の脳に直接聞こえてくる声でした。
 (わたしがもっと楽しいところに連れて行ってあげるわ)
 (本当に?)
 (本当よ)
 その声の主は、頭の中で私のいる迷路の壁に穴を開け始めました。すると、現実の迷路の壁に穴が開きました。
 (一体どうなっているんだ、この世界は……)
 私は吃驚仰天して、気を失ってしまいました。

 気がつくと、私は妙な小部屋の中にいました。どういうわけか、壁も床も天井も全部が全部真四角です。四面ある壁のうちの隣り合った二面は窓になっています。窓というより壁全体が半透明の素材でできているといった方が正しいのかもしれませんが、外光が入ってきているのでやはり窓だろうと思います。左側の窓は黄色く、右側の窓は赤く着色されています。天井も窓と同じ素材のようで白く光っています。

 壁と床は一面真っ黒で、真ん中に丸いハッチが付いています。どうやら、ここは扉付きの立体迷路になっているようです。これは面白そうです。

 左側の壁のハッチを開けてみると、隣の小部屋が見えました。左側は赤窓、天井は白窓になっていて、右側と正面と床にはハッチがありました。
 右側の壁の扉を開けてみると、隣の小部屋が見えました。右側は黄窓、天井は白窓になっていて、左側と正面と床にはハッチがありました。
 床の扉を開けてみると、床下の小部屋が見えました。左側は黄窓、右側は赤窓になっていて、その他の壁と床にはハッチがありました。

 この小部屋の中にいたままで分かることはこれだけです(窓は開かず、外の景色を見ることはできませんでした)。あとは隣の小部屋と床下の小部屋に移って調べるしかありません。私は、迷路を進むときのいつものやり方(左手を壁にあてて進む)で、隣の(左手側に赤窓のある)小部屋に移動しました。潜り抜けたハッチはかすかな機械音を立てながらゆっくりと自動的に閉まりました。把手をひねってみましたが、びくとも動きません。オートロックになっているようです。

 左手側に赤窓のある小部屋の正面のハッチを開くと、また小部屋がありました。左手側に赤窓、正面に緑窓がありました。その小部屋の右手側の扉の向こうには左手側に緑窓、正面と右手側にハッチのある小部屋があり、さらにその先には、左手側に緑窓、正面に橙窓、右手側にハッチのある小部屋がありました。その次の小部屋は左手側が橙窓、正面と右手側がハッチ、その次は左手側が橙窓、正面が黄窓で右手側がハッチ、そのまた次は左手側が黄窓、正面がハッチ、さらにまたその次は左手側が黄窓、正面が赤窓、右手側がハッチの小部屋でした。どうやら一巡して最初の小部屋に戻って来たようです。8個の小部屋の天井は白窓に統一されていて、床には必ずハッチがありました。

   緑緑緑
   窓窓窓
   ↓↓↓
赤窓→□□□←橙窓
赤窓→□?□←橙窓
赤窓→□□□←橙窓
   ↑↑↑
   黄黄黄
   窓窓窓

 八つの小部屋の中央にはもうひとつ小部屋があるはずです。そこで私は、もう一度、左赤窓の小部屋に移動しようとしましたが、さっきは開いたハッチが開かなくなっていました。一つ前の左黄窓の部屋に戻るハッチも開きません。どうやら一度通ったハッチはロックされてしまうようです。仕方がないので床にあるハッチを開いて下の小部屋に移動しました。

 下の小部屋には赤窓と黄窓があり、他の壁と床にはハッチがありました。上の小部屋とほぼ同じ構成ですが、天井が窓ではないので、上よりもかなり暗く感じます。壁のハッチを両方開けてみました。予想通り、左は赤窓の小部屋、右は黄窓の小部屋につながっていました。床のハッチを開けてみると、この小部屋と同じ向きに赤窓と黄窓がありましたが、床は青窓になっていました。何だか吸い込まれそうな気がしたので、すぐにハッチを閉めました。

 窓の配置はだいたい見当がついたので、今度は黄窓の部屋に移動しました。左手側のハッチを開ければ、まだ見ていない中央部の小部屋を見ることができる筈です。そこで私は、ハッチを回しました。すると、驚いたことに…。

 ――ここまで話したとき、語り姫は、暁の光が射すのを見て、慎ましく口を噤んだ。

| コメント(0) | トラックバック(0)

 ――店の奥で仮眠していた店主が、突然飛び起きて叫んだ。

 「そうか、キューブの中に入って考えればよかったんだ!」

 ――いったい、どうしたんだ?

 「どうもこうも、キューブの中に鼠が入ってマッピングしてるんだよ!」

 ――何を言ってるんだ、夢でも見たのか?

 「夢? そうか、今のは夢だったのか…。夢中で考えていたから夢の中でも考え続けてたんだな。うん、これは論理的だ。ちゃんと筋が通っているぞ」

 ――店主は、普通よりも一回り小さなルービックキューブの紛い物をいじっている。これは、著作権にうるさいことで有名な黒鼠の絵が入っている子供騙しのキャラクター商品で、キューブを回そうとするとバリがひっかかるという粗悪品なのだが、税込みで百五円という安値につられて、つい買ってしまったらしい。

 「そんな話はどうでもいいから、早くスクリプトを出してくれ!」

 ――店主は、エディタでスクリプトを開くと、脳内のジャンクを打ち込み始めた。

 ――しばらくすると、DOSプロンプトを開いた。島内本を見ながらコマンドを打ち込んでは、スクリプトを修正していった。

 「よーし。こんな感じで大体いいだろう…」

 ――店主は、DOSプロンプトでコマンドを打ち込み、パソコンのディスプレイをこちらに向けた。

| コメント(0) | トラックバック(0)

 ――店主がフリーズしている間に、僕はもう一度考えてみた。小体(小キューブ)の向きの変化が回転によって生じることは間違いない。しかし、その状態をX・Y・Zの各軸での回転数(以下、右回りの90度を“1ひねり”と書くことにする)だけで表現することは無理なようだ。
 例えば、(i, j, k)=(1, 1, 0)は、X軸で1ひねり、Y軸で1ひねりしたことを表わしてはいるけれども、その結果、小体の向きがどうなるかが特定できないのだ。X軸とY軸のどちらで先にひねるかによって向きが異なってしまうからだ。これは、個別の小体の“主観的”な座標で考えても全体の“客観的”な座標で考えても同じことだ。

 向きの変化には回転数だけでなく回転順も影響することが分かったところで、それをどうやって“向きを表わす変数”に反映させればいいのかが分からない。

 仕方がないので、島内本に掲載されている手順のいくつかをマクロに書いて試してみたりもしたが、うまい解決策を思い付くこともなく、ただ本に書いてあることを追認するだけの単調な作業になってしまった。ただ、見た目は同じ結果になる複数の異なる手順を実行したときに、(i, j, k)の値に違いが出るのは、手順が違えば回転する軸も異なるのだから当然といえば当然なのだが、これはこれで面白い。とはいえ、実際のキューブを見ても、崩したときの手順の違いが分かるわけではないのが残念だ。
 読みかけだった「ルービック・キューブによる群論入門」に、正六面体(立方体)の向きのバリエーションは24パターンあるとかいうことが書いてあったのを思い出して、もう一度読んでみた。頂点の位置が8通りで、その頂点を含む辺の向きが3通りだから、8×3=24だということで、いたってシンプルだ。それならばと、小体のある頂点の位置を(i, j, k)として、その頂点を含む辺の向きを表わす変数をもう一つ加えて(i, j, k, l)にしてみた。
 その結果、確かに小体の向きを正しく反映するようになったけれども、二面体は頂点の位置の変化、三面体は一辺の向きの変化になってしまうのが面倒だ。もっと簡単に分かるようにできないものだろうか…。

 正八面体の向きは正六面体と同じ24通りになるという説明を読み、正六面体に内接する正八面体の図を眺めていて、なるほど、正八面体の頂点は正六面体の各面の中心とぴったり一致しているので、8個の頂点×3本の辺と、6個の頂点×4本の辺は同じになるんだな、と納得した。

 「だったら、正八面体で考えてもいいんじゃないか?」

 ――いつの間にやら店主のフリーズが解除されたようだ。

 「おおっ、この線を見てみろよ。ほら、この、正八面体の辺だよ。これは立方体の面の移動方向と同じじゃないか!」

 ――何を言ってるんだ。立方体の各面の中心をつなぐ線だから、当然そうなるだろう。

 「だから、ここだよ。正三角形だよ。この正三角形がキューブの向きがズレる原因だったんだ」

 ――まあ、確かにそうだね。面の中心を繋いだ線が正方形になるのは、一つの軸で一回転した場合だからね。それで?

 「その場合は向きは保存されるけれども、二つ以上の軸にまたがって回転した場合は向きは保存されない。つまり、一つの正方形の軌道から別の正方形の軌道への乗り換えると、そこで向きが変わるということだ」

 ――それが分かっても、どういうデータにすればいいのか…?

 「X軸→Y軸、Y軸→Z軸、Z軸→X軸の乗り換えを+1、その逆を-1として…」

 ――ちょっと待てよ。立方体の向きの変化を考えてるんだから、3つの軸(x, y, z)が移動後にどこに行ったかを調べればいいかもしれないぞ。うん、それだ。

 X軸で1ひねりするとY軸とZ軸が入れ代って(x, z, y)、次にY軸で1ひねりするとX軸とZ軸が入れ代わって(y, z, x)、さらにZ軸で1ひねりすると(z, y, x)となる。これは、3個の順列だから6通りにしかならない。元の状態(x, y, z)になっても位置が異なるパターンが4通りあるということだな。だけど、それだけで充分だったんだ。元の位置に戻ったときの向きに注目してるんだから。

 「つまり、どういうこと?」

 ――つまり、(x, y, z)、(x, z, y)、(z, y, x)、(y, x, z)、(z, x, y)、(y, z, x)という6通りのパターンの置換にするってことだよ。

 「なんだか分かりにくいな」

 ――じゃ、正しい向きを(0, 0, 0)として、向きのズレを(0, 2, 1)、(1, 0, 2)、(1, 1, 1)、(2, 1, 0)、(2, 2, 2)で表わせばいいだろう。

 「(1, 1, 1)と(2, 2, 2)は3つの軸が全部ズレたパターンだな。でも、この1と2の違いは何だ?」

 ――さっきの"+1"と"-1"の違いだよ。X→Y→Zを"+1"、Z→Y→Xを"-1"と考えて、マイナスが邪魔だったから"-1"を"+2"にしたんだ。

 「なるほど。分かってしまえばこんなに単純なことを、複雑に考えてしまっていたんだな。キューブの向きだけに、向きになって考えてしまったってオチでいいかな?」

 ――そんなことを言っている店主を無視して、僕はさっそくスクリプトを書き直した。

 ――できたよ。じゃ、この前と同じ島内本の【6a】を実行してみるぞ。


| コメント(0) | トラックバック(0)

カレンダー

<   2010年1月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Powered by Movable Type 4.261

このページについて

このページは、メインページです。このページには最新のブログ記事が含まれています。

過去の記事はアーカイブで閲覧できます。

最近のコメント