バイナリパズルソルバー


10

前書き

パズルのルール:

パズル(としても知られているバイナリTakuzuまたはSubikuは)理解することは非常に簡単で、かつ唯一のいくつかのルールがあります。
ゲームの名前はバイナリであるので、それはかなり明白だが、あなただけの0と1を記入することができます。

  1. 同じ数字を2つだけ縦または横に互いに隣接させることができます
  2. 各行と各列には、等しい量のゼロと1が含まれている必要があります(これは暗黙的に、すべてのバイナリゲームが常に偶数次元を持つことを意味します)。
  3. 行と列が重複していない場合があります(ゼロと1の順序がまったく同じ)。

必要に応じて、www.binarypuzzle.comでゲームをプレイできます。

戦術:

ルール1により、次の場合は常に数字を入力できます。-
同じ数字が2つ縦または横にすでに隣接している場合、両側で反対の数字を入力できます。すなわち.11...0110..
-縦または横に同じ数字が2つあり、その間に1つのギャップしかない。すなわち.1.1...101..

ルール1により、3つのギャップが残っており、同じ数字を3つ隣接させることができない場合、ギャップの1つを埋めることができます。すなわち.0.1.010.1.0(まだ2つ入力する必要があり、3つの隣接するものを中央に配置することはできないため、最初のギャップはでなければなりません1。)

ルール2により、行または列の残りのギャップの半分がすでに反対の桁で埋められている場合は、常に残りのギャップを埋めることができます。すなわち.1.011010011

規則3により、同じ順序の行を解くために2つだけ残っている場合は、常に反対の数字を埋めることができます。すなわち101100 & 1..100101100 & 110100

ルール3により、3つのギャップが同じ順序の線上に残っている場合、ギャップを埋めることができます。すなわち010011 & .1.01.010011 & .1.0101最後にaを入力することはできません。これは、他の2つのギャップにゼロを入力し、両方の行を順番に等しくする必要があるためです。)

例:

いくつかの1と0が埋められた次の6x6グリッドから始めます(ドットはまだ埋めていないギャップです):

.1....
.10.0.
1.11..
.1....
...1.0
......

ルール1および2により、次の数字を入力できます。

.1.01.
.1010.
101100
010011
.0.1.0
.010..

ルール1により、行5、列1に1を入力できます。

.1.01.
.1010.
101100
010011
10.1.0
.010..

ルール3により、行1、列6に0を入力できます(行4を見た場合):

.1.010
.1010.
101100
010011
10.1.0
.010..

これで、ルール1と2により、ギャップを数字で埋め続けることができます。

.1.010
010101
101100
010011
10.1.0
.010.1

これで、ルール3(行3を見たとき)のために行5を終了できます。

.1.010
010101
101100
010011
100110
.010.1

そして、ルール1と2によってパズルを完成させることができます。

011010
010101
101100
010011
100110
101001

チャレンジ:

課題は簡単です。開始グリッドを指定して、解決したパズルを出力します。

注:上記のルールを実装する必要はありません。もちろん可能であり、この課題を実装する方法についてのヒントが得られるはずですが、ルールを考慮してソリューションをブルートフォースすることは完全に問題ありません。
どのように解決するかはあなた次第ですが、課題は解決したパズルを出力することです。

チャレンジルール:

  • グリッドの入出力フォーマットは柔軟ですが、使用するものを明記してください。(つまり、2Dバイト配列、改行付きの文字列など)
  • これは、使用される文字にも当てはまります。例ではを使用しました01.が、必要に応じてABx代わりに使用できます。使用した入出力形式と文字を記入してください。
  • 次のグリッドサイズのみが使用されると想定でき6x6ます。8x8; 10x10; 12x12; 14x14; 16x16

一般的なルール:

  • これはなので、バイト単位の最短の回答が優先されます。
    コードゴルフ言語では、コードゴルフ言語以外の言語で回答を投稿しないようにしないでください。「あらゆる」プログラミング言語について、可能な限り短い答えを考え出すようにしてください。
  • 回答には標準ルールが適用されるため、STDIN / STDOUT、関数/メソッド、適切なパラメーター、完全なプログラムを使用できます。あなたの電話。
  • デフォルトの抜け穴は禁止されています。
  • 可能であれば、コードのテストを含むリンクを追加してください。
  • また、必要に応じて説明を追加してください。

テストケース:

ドットは読みやすさのためにのみ追加されています。代わりに、スペースなど、ギャップに使用したいものを自由に使用してください。入力形式と出力形式の両方に柔軟性があります。

Input:
1..0..
..00.1
.00..1
......
00.1..
.1..00

Output:
101010
010011
100101
011010
001101
110100

Input:
.1....
.10.0.
1.11..
.1....
...1.0
......

Output:
011010
010101
101100
010011
100110
101001

Input:
.......1..
.00..0..1.
.0..1..0.0
..1...1...
1.1......1
.......1..
.0..1...0.
....11...0
.0.0..1..0
0...0...1.

Output:
0110010101
1001100110
1001101010
0110011001
1010100101
0101010110
1001101001
0110110100
1010011010
0101001011


回答:


4

Brachylog、34バイト

{ℕ<2}ᵐ²&≜{d?ọᵐctᵐ=&{ḅlᵐ⌉<3}ᵐ}&\↰₂&

オンラインでお試しください!

これはかなり遅いので、TIOのテストケースは4x4です。現在、私のコンピューターで6x6テストケースを実行して、所要時間を確認しています。

これは、リストのリストを入力として受け取ります。不明な値は、変数、つまりすべて大文字の文字列で示す必要があります(そうでない場合、一部のセルに同じ値が必要であることを示すため、値はすべて異なる必要があります)

説明

値をに制限し、{0,1}3つのルールすべてを順守するまで変数のインスタンス化を試みます。これが非常に遅い理由です(1つが見つかるまですべてを試行するためです。その場合、可能な行列を試行する前に制約を課すことができるようにBrachylogが十分に実装されていないためです)。

                                 &  Output = Input
{   }ᵐ²                             Map two levels on the Input (i.e. each cell):
 ℕ<2                                  The cell is either 0 or 1
       &≜                           Assign values to all cells
         {                  }       Define predicate 2:
          d?                          The Input with no duplicates is still the Input
                                        (i.e. all rows are different)
           ?ọᵐctᵐ=                    All occurences of 1s and 0s for each rows are equal
                  &{      }ᵐ          Map on rows:
                    ḅlᵐ                 Get the lengths of runs of equal values
                       ⌉<3              The largest one is strictly less than 3
                             &\↰₂   Apply predicate 2 on the transpose of the Input
                                      (i.e. do the same checks but on columns)

好奇心から、ブラキログは大文字のアルファベット以外の変数をどのように示しますか?したがって、ソリューションがより高速に動作するとします。14x14グリッドのすべての空のスペースAYZ出力パラメーターとして)スルーで埋めることはできません。それはを続けないAAABなど?
Kevin Cruijssen

2
@KevinCruijssenすべて大文字の識別子は変数であるため、yes AAは変数であり、変数でKEVINCRUIJSSENもあります。
Fatalize

3
私が疑ったように、Brachylog:D
Jonathan Allanの

3

JavaScript(ES6)、274 270バイト

空のセルがでマークされている2D配列として入力を受け取ります2。考えられるすべてのソリューションをコンソールに出力します。

f=(a,x=0,y=0,w=a.length,p,R=a[y])=>(M=z=>!a.some((r,y)=>/(0|1),\1,\1/.exec(s=r.map((v,x)=>(v=z?v:a[x][y],b-=v&1,c-=!v,m|=v&2,v),b=c=w/2))||b*c<0|o[b*c||s]&(o[s]=1),o={}))(m=0)&M(1)&&(m?R&&[0,1].map(n=>(p=R[x])==n|p>1&&(R[x]=n,f(a,z=(x+1)%w,y+!z),R[x]=p)):console.log(a))

使い方

コードの最初の部分では、M()関数を使用して、現在のボードの有効性を水平方向と垂直方向の両方で確認します。

M = z =>
  !a.some((r, y) =>
    /(0|1),\1,\1/.exec(
      s = r.map((v, x) =>
        (
          v = z ? v : a[x][y],
          b -= v & 1,
          c -= !v,
          m |= v & 2,
          v
        ),
        b = c = w / 2
      )
    ) ||
    b * c < 0 |
    o[b * c || s] &
    (o[s] = 1),
    o = {}
  )

行全体または列全体を文字列sにマッピングします。これは実際には文字列に強制変換された配列なので、のようになります"1,2,2,0,2,2"

それは使用しています:

  • /(0|1),\1,\1/3つ以上の連続する同一数字を検出するための正規表現。
  • 10の数を追跡するためのカウンターbおよびc。両方のカウンターはw / 2に初期化され、1または0に(それぞれ)遭遇するたびに減少します。これは次のいずれかにつながります。
    • B = C = 0 B * C = 0 →ラインが(多くのように完全かつ正確であるゼロとしてのもの
    • B> 0とC> 0 B * C> 0 →ラインが完全にこれまでのところ、正しくありません(私たちが持っていない以上 / 2ワット のゼロまたは以上 / 2ワット のもの
    • b <0 OR c <0 b * c <0 →行は無効です
  • ボード上に残りの2つが少なくとも1つある場合、ゼロ以外のフラグm(「欠落」)。
  • これまでに遭遇したすべての線パターンを追跡するオブジェクトo

ボードが無効な場合は、すぐに停止します。ボードが有効で完成している場合は、コンソールに出力します。それ以外の場合、コードの2番目の部分は、各2ゼロまたは1で再帰呼び出しに置き換えようとします。

[0, 1].map(n =>
  (p = a[y][x]) == n |
  p > 1 && (
    a[y][x] = n,
    f(a, z = (x + 1) % w, y + !z),
    a[y][x] = p
  )
)

デモ


説明を追加していただきありがとうございます。そして、1つだけでなく、すべての可能な出力を印刷する方法が気に入っています。
Kevin Cruijssen、2017年

1
@KevinCruijssenこれはおそらく最適とは言えませんが、書くのは面白かったです。いい挑戦だ!
アーノールド2017年

1

ゼリー53 51 バイト

ṡ€3ḄFf0,7L
SḤnLṀȯÇ
⁻QȯÇ
Fṣ©2L’0,1ṗż@€®F€s€LÇÐḟZÇ$Ðḟ

、、および(スペース)を含む0、グリッドを表すリストのリストを取ります。リストのリストのリストを返します。リストの各リストは同じ形式であり(s はありません)、入力に対する可能な解決策を表します。122

オンラインでお試しください!(これは、メモリの制限により、質問のテストケースを実行しません-2つの nSpacesグリッドはすべて、整数のリストのリストのリストとして作成されます-しかし、私はそこに単一の解決策で比較的重いケースを入れました)。フッターはグリッドを分離してフォーマットします。

純粋な総当り法-ルールを実装し、2sのいずれかを1sまたは0sに置き換えることによって形成される可能性のあるグリッドごとにそれらをチェックします。

ṡ€3ḄFf0,7L - Link 1, # of runs of 3 1s or 3 0s by row: list of lists
ṡ€3        - all contiguous slices of length 3 for €ach list
   Ḅ       - convert all results from binary
    F      - flatten into one list
     f     - filter keep values in:
      0,7  -   0 paired with 7: [0,7]
         L - length

SḤnLṀȯÇ - Link 2, unequal counts of 1s and 0s by column ...or link 1: list of lists
S       - sum (vectorises, hence "by column", counts 1s since only 1s or 0s appear)
 Ḥ      - double
   L    - length (number of rows - OK since square)
  n     - not equal? (vectorises)
    Ṁ   - maximum (1 if any not equal)
     ȯÇ - ... or last link (1) as a monad

⁻QȯÇ - Link 3, rows are unique ...or link 2: list of lists
 Q   - unique
⁻    - not equal?
  ȯÇ - ... or last link (2) as a monad

Fṣ©2L’0,1ṗż@€®F€s€LÇÐḟZÇ$Ðḟ - Main link: list of lists
F                           - flatten
 ṣ©2                        - split at 2s and copy the result to the register
    L                       - length (# of such slices)
     ’                      - decrement (# of 2s)
      0,1                   - 0 paired with 1
         ṗ                  - Cartesian power (all binary lists of length # of 2s)
             ®              - recall value from register (the flat version split at 2s)
          ż@€               - zip (reversed @rguments) for €ach (1s & 0s where 2s were)
              F€            - flatten €ach
                s€L         - split €ach into chunks of length length(input) (into rows)
                    Ðḟ      - filter discard if:
                   Ç        -   call last link(3) as a monad
                         Ðḟ - filter discard if:
                        $   -   last two links as a monad:
                      Z     -     transpose
                       Ç    -     call last link(3) as a monad
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.