web-dev-qa-db-ja.com

この「treefarm」パズルを解くためのアルゴリズム

この種のパズルを解くためのプログラムを作成するにはどうすればよいでしょうか。緑色の正方形は木を表しており、次のように植える必要があります。

  • 木はまったく接触しません(斜めにさえも)
  • 各行と列には特定の数のツリーが含まれており、メイングリッドの右側または下の対応するセルにそれぞれ示されています。

メイングリッドのセル内の数字は関係ありません。

Puzzle grid

必要なツリー量が1で、ツリーが含まれている行と列、および各ツリーの周囲に9x9の正方形がある行と列をすぐに削除できます。その後、行き詰まりました。

アイデアをありがとう。

2
sammko

このようなパズルを解くとき、あなたができることが2つあります:

  1. パターンを適用して正方形を消したり、確実にそこに木を植えたりできる場所を探します
  2. 推測を行い、解決できない状況になるまで(この場合は前の推測に戻ります)、または終了するまで続行します。

この特定のパズルの場合、私が見ることができる最初のカテゴリに分類される操作は次のようになります。

  • 必要な数(0を含む)と同じ数のツリーを含む行または列のすべてのセルをマークします。
  • 植えられた木に隣接するすべてのセルをマークします
  • 残りのセルが1つだけで、もう1つのツリーが必要な行または列で、そのセルにツリーを植えます
  • 残りのセルが2つあり、さらに2つのツリーが必要な行または列で、これらのセルの両方にツリーを植えます
  • 残りの3つのセルがすべて接続されており、さらに2つのツリーが必要な行または列で、3つのグループの両端のセルにツリーを植えます。
  • 2つが接続され、さらに2つのツリーが必要な、残りの3つのセルがある行または列で、切断されたセルにツリーを植えます。

これらはすべて、最初に開始するときにすべての行、列、およびツリーについてチェックする必要があります。その後、植樹時に最初の2つをすぐに行うことができます。

2より大きい行番号と列番号が許可されている場合は、最後の4つのルールのより一般的なバージョンを作成する必要があります。または、すべての有効な組み合わせをチェックして、それらのいずれかが常にツリーを持っているか、またはまったく持っていないかを確認する単純なブルートフォースが機能します。


2番目のカテゴリでは、深さ優先のツリー検索を実行します。ノードごとに、次のことを実行する必要があります。

  1. これがリーフノードである場合は、それがターミナルであるかどうかを確認します(ゲームが勝てないか勝ちました)。もしそうなら、あなたは終わったか、あなたは親に戻る必要があります
  2. これがリーフノードの場合は、上記のIDを適用して、すぐにマークを付けたり、他のタイルに木を植えたりできるかどうかを確認します。
  3. これがリーフノードの場合は、マークされていないいくつかの塗りつぶされていないタイルに対応する子を追加します。
  4. まだ完全に拡張されていない子を選択し、拡張します。

3.と4の単純な方法は、マークされていないすべての子を追加し、ランダムに(または任意の順序で)1つを選択して展開することです。しかし、ヒューリスティックを使用すると、ほぼ確実にうまくいくことができます。

すぐに頭に浮かぶのは、3番目のステップで、単独でそれを満たすツリー配置の可能な限り少ない組み合わせで行または列を選択することです。たとえば、上から5番目の行には、それを満たす5つの可能な組み合わせがあります。次に、これらの組み合わせごとに1つの子のみを追加します。 oneは間違いなく正しいので、拡張する子は5つだけになり、そのうちの1つが確実に正しい答えになります。

1
Ben Aaronson