ルービックキューブを解くためのソフトウェアを開発している場合、キューブをどのように表現しますか?
12 に答える
このACMペーパーでは、ルービックキューブを表すために使用されたいくつかの代替方法について説明し、それらを相互に比較します。残念ながら、全文を入手するためのアカウントはありませんが、説明には次のように記載されています。
ルービックキューブの7つの代替表現が提示され、比較されます。3桁の整数の3行3行3行の配列。リテラルの6x3行3列の配列。5行12列のリテラル行列。llxllのスパース文字列。54要素のベクトル。4次元配列。3行3行3行のネストされた配列。APL関数は、方向移動と1/4回転に加えて、立方体を解くためのいくつかの便利なツールのために提供されています。
また、このRubiksCube.javaファイルには、セクションを回転させるための関連コード(実際のコードを探している場合)とともに、かなりクリーンな表現が含まれています。セルと面の配列を使用します。
1つの方法は、外観に焦点を当てることです。
立方体には6つの面があり、各面は3x3の正方形の配列です。それで
Color[][][] rubik = new Color[6][3][3];
次に、各移動は、色付きの正方形の特定のセットを並べ替える方法です。
最適化を避けます。オブジェクト指向にします。私が使用した疑似コードクラスの概要は次のとおりです。
class Square
+ name : string
+ accronym : string
class Row
+ left_square : square
+ center_square : square
+ right_square : square
class Face
+ top_row : list of 3 square
+ center_row : list of 3 square
+ bottom_row : list of 3 square
+ rotate(counter_clockwise : boolean) : nothing
class Cube
+ back_face : face
+ left_face : face
+ top_face : face
+ right_face : face
+ front_face : face
+ bottom_face : face
- rotate_face(cube_face : face, counter_clockwise : boolean) : nothing
使用されるメモリの量は非常に少なく、処理は最小限であるため、特にコードの使いやすさを犠牲にする場合は、最適化はまったく必要ありません。
これを行うには多くの方法があります。いくつかの方法は、他の方法よりもメモリをより効率的に使用します。
私は人々が直方体オブジェクトの3x3 x 3配列を使用しているのを見てきました。ここで、直方体オブジェクトは色情報を格納する必要があります(もちろん、その中央のオブジェクトは使用されません)。私は人々が6つの配列を使用しているのを見てきました。それぞれは3x3の直方体の配列です。直方体の3x18配列を見たことがあります。多くの可能性があります。
おそらくより大きな懸念は、さまざまな変換をどのように表現するかです。物理的な立方体の単一の面の回転(すべての立方体の動きは基本的に単一の面の回転です)は、多くの直方体オブジェクトを交換することによって表す必要があります。
あなたの選択は、あなたが書いているどんなアプリケーションにとっても意味のあるものでなければなりません。立方体のみをレンダリングしている可能性があります。UIがない可能性があります。あなたは立方体を解いているかもしれません。
3x18アレイを選択します。
重要な20の立方体があります。したがって、これを行う1つの方法は、20個の文字列の配列として行うことです。文字列は、色を示す2文字または3文字を保持します。1回の移動で、7つのキュービーに影響します。したがって、6つの側面のそれぞれにリマッパーが必要です。
注:このソリューションでは、白い中央にあるロゴステッカーの向きを覚えることはできません。
ちなみに、ルービックキューブのソフトウェアを誰かがやるのを手伝ったのは15年前かもしれませんが、どう表現したのか思い出せません。
キューブは、3つの水平リンクリストと交差する3つの垂直円形リンクリストとして想像できます。
立方体の特定の行が回転するときはいつでも、対応するポインターを回転させるだけです。
次のようになります。
struct cubeLinkedListNode {
cubedLinkedListNode* nextVertical;
cubedLinkedListNode* lastVertical;
cubedLinkedListNode* nextHorizontal;
cubedLinkedListNode* lastHorizontal;
enum color;
}
実際には2'最後の'ポインタは必要ないかもしれません。
[これはCで行いましたが、JavaまたはC#で、cubeLinkedListNodeの単純なクラスを使用して行うことができ、各クラスは他のノードへの参照を保持しています。]
6つの連動する循環リンクリストがあることを忘れないでください。3垂直3水平。
回転ごとに、対応する円形のリンクリストをループして、回転する円と接続する円のリンクを順番にシフトします。
そのようなもの、少なくとも...
他の人は物理的な立方体の説明にうまく対処しましたが、立方体の状態に関しては...私はベクトル変換の配列を使用して立方体の変化を説明しようとしました。そうすれば、変更が加えられたときにルービックキューブの履歴を保持できます。そして、最も単純な解を見つけるために、ベクトルを変換行列に乗算できるかどうか疑問に思います。
可動する48面の順列として。基本的なローテーションも順列であり、順列を構成してグループを形成できます。
プログラムでは、このような順列は、0 から 47 までの数字を含む 48 個の要素の配列で表されます。数字に対応する色は固定されているため、順列から視覚的な表現を計算できます。逆の場合も同様です。