web-dev-qa-db-ja.com

未知の要素を持つ数独バリアントを解く

私は最近、特別な数独の変種に出くわし、プログラムでそれを効果的に解決するのに苦労しています。

次の最初の6x6グリッドについて考えてみます。
enter image description here

ルール

赤い疑問符は私たちの秘密の数字を表すことになっています。シークレットディジットは通常のディジットのように動作します。つまり、実際の値は16の間にありますが、この値はプレーヤーに公開されません。このゲームタイプでは、衝突を作成すると、新しく配置された数字はニュートラル要素になり、ジョーカーと見なされ、どのゲームとも衝突しません。他の桁。たとえば、秘密の数字が実際に6であり、その行に6を配置した場合、それはニュートラル要素になります(これにより、秘密の数字が何であるかもわかります)。最大1つのニュートラル要素を生成できます(つまり、1つの衝突しか作成できません)。2回目の衝突ではグリッドが未解決になります。
補足:当然、このインタラクティブなゲームタイプは、紙に印刷しても意味がありません。それは例えばシークレットがプレーヤーに公開されないようにするには、クライアントサーバーインフラストラクチャが必要です。

分析

シークレットディジットは基本的なルールに従っているため、グリッド例では4にすることはできないと推測できますが、他のすべてのディジットは可能です。また、独自の解決策がないこともわかります。実際、通常、考えられる解決策は何百もあります。 6x6の初期グリッドでは、常に1つの秘密の数字と6つの数字がグリッドにかなりランダムに配置されます(互いに衝突することはありません)。つまり、秘密は賭けの直後に公開される可能性がありますが、それはまったく面白くないので、些細なケースを却下します:)

解決戦略

最も有望な戦略は、秘密の数字をできるだけ早く見つけることです。つまり、すべての可能性が尽きるまで、または衝突が発生するまで、行、列、またはボックスに数字を配置します。秘密が何であるかがわかるとすぐに、通常のパズルのようにパズルを解くことができます(存在する場合はニュートラル要素を単に無視します)。

問題

解けないボードを作らずに秘密の数字を見つけるアルゴリズムを書きたい。
ブロッカーが最も少ないシークレットの行、列、ボックスのフィールドを識別することから始める、かなり鈍いプログラムを作成しました。次に、衝突または枯渇によって秘密が推測されるまで、ブロッカーが最も少ないものから最も多いものの順に、これらのフィールドに数字を挿入します。グリッドの例では、次のようになります。

enter image description here
青い数字は昇順で配置されます(1で始まります)。私の現在のアルゴリズムでは、約20%の確率で解決できないボードが作成されますが、これは私には受け入れられません。そしてそれが私が質問をしている理由です:
解決できないパズルを作成する可能性を最小限に抑える、または排除する、よりスマートなアプローチは何でしょうか?

追記:あらゆる種類の回答に感謝します。理論的な散文、疑似コード、または一般的な言語の実際のコードはすべて問題ありません。開始戦略として選択するフィールド/数字の要点を取得したいだけです。

2
MCL

ワイルドカードの概念をよく理解していないと思います。ボード上のサンプル構成のいくつかの画像が役立つかもしれませんか?

すでに確立された数独解法アルゴリズムが存在します。好きな人

バックトラック。

解決できない位置に到達するまで番号を1つずつ配置し続けてから、最後のステップに戻って続行します。

制約解決

各セルには、行、列、およびセルのグループのために多くの制約があります。各セルのすべての制約をマップし、その制約に対して答えが一意であるセルの解決を開始します。数字が追加されるにつれて、他の制約を更新し続けます。

あなたはもっと見つけることができます ここ

十分に確立されたアルゴリズムがあるため、この問題に取り組む1つの戦略は、これを含めるように上記の戦略を変更することです。例:このセルは、行、列、およびより大きなセルに制約を課しません。

時間があれば、制約ベースのソリューションの擬似コードで編集してみます。

1
Gaurav Ramanan