2

TrialPay は、ブログにスネーク キューブ パズルに関するプログラミングの質問を投稿しました。

最近、当社のエンジニアの 1 人がスネーク キューブを紹介してくれました。スネーク キューブは、各キューブレットを通る弾性バンドで接続された一連のキューブレットで構成されるパズルです。各キューブレットは弾性バンドを中心に 360° 回転することができ、チェーンを最初に構築する方法に応じてさまざまな構造を構築できます。最終的な目標は、キューブを作成するような方法でキューブを配置することです。

例:

ここに画像の説明を入力

この特定の配置には、17 グループのキューブレットが含まれており、2 つのキューブレットの 8 つのグループと 3 つのキューブレットの 9 つのグループで構成されています。この配置はさまざまな方法で表すことができますが、この演習では、回転によってパズルの向きが変わらないピース、または「まっすぐな」ピースと見なされるピースを「0」、「1」とします。は、回転によってパズルの構成が変化するピース、またはヘビを「曲げる」ピースを示します。そのスキーマを使用すると、上記のヘビ パズルは 00111011011101011101010100 と記述できます。

チャレンジ:

あなたの課題は、選択した任意の言語で、立方体の次元 (X、Y、Z) とバイナリ文字列を入力として取り、問題を解決できる場合は '1' (引用符なし) を出力するプログラムを作成することです。パズル、つまりキューブレットの向きを指定して適切な X Y Z 立方体を構築し、現在の配置が解決できない場合は '0' を返します。

解決策の半詳細な説明を投稿しましたが、プログラムが問題を解決するかどうかを判断するにはどうすればよいですか? もっと多くのテストケースを取得することを考えましたが、いくつかの問題に遭遇しました:

  1. TrialPay のブログのスネーク キューブの例は、ウィキペディアのスネーク キューブのページと www.mathematische-bastelien.de の写真と同じ組み合わせです。
  2. 画像を手動で文字列に変換するのは非常に面倒です。

多くの組み合わせを生み出すプログラムを作成しようとしました。

#We should start at the binary representation of 16777216 (00100...), because
#lesser numbers have more than 2 consecutive 0s (000111...)
i = 16777216
solved = []
while i <= 2**27:
    s = str(bin(i))[2:]
    #Add 0s
    if len(s) < 27:
        s = '0'*(27-len(s)) + s
    #Check if there are more than 2 consecutive 0s
    print s
    if s.find("000") != -1:
        if snake_cube_solution(3, 3, 3, s) == 1:
            solved.append(s)
    i += 1

しかし、実行が完了するまでには永遠に時間がかかります。プログラムを検証するためのより良い方法はありますか?

前もって感謝します!

4

3 に答える 3

3

TL;DR:これはプログラミングの問題ではなく、数学的な問題です。math.stackexchange.comでより適切なサービスを受けることができます。

立方体のサイズとスネークの長さが入力として渡されるため、チェッカー プログラムが検証する必要がある入力のスペースは本質的に無限です。単一の入力に対するソリューションの回答をチェックすることは合理的ですが、入力空間全体にわたってこのチェックを力ずくで行うことは明らかにそうではありません。

ソリューションが特定のケースで失敗した場合、チェッカー プログラムはこれらを見つけるのに役立ちます。ただし、プログラムの正確性を確立することはできません。解決策が実際に正しい場合、チェッカーは永久に実行され、疑問に思うままになります。

残念ながら (あなたの好み次第ですが)、あなたが探しているのはプログラムではなく、数学的証明です。

(証明) アルゴリズムの正しさは、それ自体が全体の研究分野であり、長い時間を費やすことができます。とはいえ、帰納法による証明はしばしば適用できます (特に再帰アルゴリズムの場合)。

また、状態構成間の移動は、ユーティリティ関数の最適化と言い換えることもできます。最適化されている空間に関すること (極値が 1 つしかないなど) を証明することは、プログラムの正しさの証明に変換できます。

この 2 番目のアプローチでの状態構成は、スネークの向きである場合もあれば、より深い構造である場合もあります。たとえば、ルービック キューブを解くための一般的な戦略は、通常、文字通りの立方体の状態ではなく、関連する対称性のグループの式で示されます。これは、私が個人的にあなたのソリューションが最終的に実行されることを期待しているものです.

編集:数年後、特定の固定キューブサイズとスネークの長さについて、もちろん検索スペースは実際には有限であることを指摘する必要があると感じています。すべての組み合わせをブルート フォース チェックするプログラムを作成できます。もしあなたが賢ければ、一連のケースをチェックする時間は一連の独立した確率変数として扱うことができると主張することさえできます。これから、合理的な進行状況バーを作成して、待機時間が (非常に) 長くなるかを見積もることができます。

于 2012-07-24T07:29:43.740 に答える
0

3つの連続した0はあり得ないというあなたの主張は誤りだと思います。この配置を検討してください。

000
  100
    101
      100
        100
          101
            100
              100
                100

このパズルで私が抱えている問題の1つは、表記法です。A1は、キューブレットがパズルの向きを変えることができることを示していますが、どの軸を中心にしていますか?上記の例では、Y軸が垂直で、X軸が水平であると想定しています。左側のA1は、キューブレットのY軸を中心に1回転する機能を示し、右側のAは、キューブレットのX軸を中心に回転する機能を示します。

上記と同様のアレンジを構築することは可能だと思いますが、3つの000グループで構成されています。しかし、私にはその表記法がありません。明らかに、上記の例は、最初の3行が次のようになるように変更できます。

001
  000
    101

最初のセグメント1はY軸を中心とした回転を示しています。

于 2012-07-24T11:17:36.967 に答える
0

少し前に、同じ問題に対して Java アプリケーションを作成しました。

これにはバックトラッキングアルゴリズムを使用しました。

立方体全体を再帰的に検索して、可能な方向を確認するだけです。解決策が見つかった場合は、解決策を停止して印刷できます (すべての解決策を印刷することにしました)。

3x3x3 の立方体の場合、私のプログラムは 1 秒もかからずにそれらを解決しました。それよりも大きな立方体の場合、約 5 秒から 15 分かかりました。

申し訳ありませんが、現在コードを見つけることができませんでした。

于 2015-09-08T20:30:53.223 に答える