4


1

「drive ya nuts」パズルのユニークな組み合わせをすべて生成する

しばらく前、私は単純なpythonプログラムを作成して、ドライブナットパズルの単一のソリューションを総当たり攻撃しました。

パズルは数字1〜6の7つの六角形で構成されており、すべてのピースは、各数字が次のピースの同じ数字に隣接するように配置する必要があります。

パズルには、「〜1.4G」という一意ではない可能性があります。ピースを順番に並べ替える「7!」オプションがあります(たとえば、「center = 0」、「top = 1」、時計回りの順番で続きます…​) 。 ピースをソートした後、各ピースを6つの方法で回転させることができます(各ピースは六角形です)ので、7つのピースの特定の順列に対して「6 7」の可能な回転を取得します。 Totalling: `7!*(6 7)=〜1.4G`の可能性。 次のPythonコードは、これらの可能なソリューションを生成します。

def rotations(p):
    for i in range(len(p)):
        yield p[i:] + p[:i]

def permutations(l):
    if len(l)<=1:
        yield l
    else:
        for perm in permutations(l[1:]):
            for i in range(len(perm)+1):
                yield perm[:i] + l[0:1] + perm[i:]

def constructs(l):
    for p in permutations(l):
        for c in product(*(rotations(x) for x in p)):
            yield c

ただし、可能性のある合計数を6で除算する必要があるため、パズルには「〜0.2G」*ユニークな可能性のあるソリューションしかないことに注意してください。変化)。

このパズルの*ユニークな可能性のみ*を生成するより良い方法はありますか?

3 Answer


5


一意の有効なソリューションのみを取得するには、中央のピースの向きを修正します。 たとえば、中央のピースの「1」が常に「上」を指していると仮定できます。

まだ実行していない場合は、各ピースを配置した後に有効なソリューションをチェックすることにより、プログラムをより効率的にすることができます。 2つのピースを無効な方法で配置したら、他の無効な組み合わせをすべて列挙する必要はありません。


3


中央にピースがなければ、これは簡単です。 ピース「0」が一番上にある状況のみを考慮してください。

しかし、その考えを実際の状況に拡張できます。 ピース i`が中央にあり、ピース(i + 1)%7`が上部にある状況のみを考慮することができます。


1


プログラミングは厄介かもしれませんが、検索スペースは非常に小さいと思います。

センターピースには7つの選択肢があります。 次に、上にあるピースに対して6つの選択肢がありますが、その下端は中央のピースの上端に一致する必要があるため、方向は固定されています。同様に、スロットに入れるピースを選択するたびに、方向は固定されます。

残りのピースの選択肢は少なくなります。 たとえば、図のように中央部分と上部部分を選択したとします。右上のピースには、所定の位置にあるピースと一致するように(時計回りに)連続したエッジ(5,3)が必要であり、そのようなエッジのペアを持つのは3つのピースだけです(実際、すでに1つを選択しました)センターピース)。

最初に各エッジペアのピースのリストを含むテーブルを作成し、次に、中央と上部の42の選択肢のそれぞれについて時計回りに進み、必要なエッジのペアを持つピースのみから選択します(中央のピースに一致するように)および以前に配置されたピース)およびそのようなピースがない場合はバックトラックします。

エッジの最も一般的なペアは、4個で発生する(1,6)、3個で発生する他の2つのエッジペア((6,5)および(5,3))であり、9個のエッジペアがあります2個、1個で発生する14個と、まったく発生しない4個。 したがって、選択しなければならない非常に悲観的な見積もりは、7 * 6 * 4 * 3 * 3 * 2または3024です。