ひとりパズルを解く


21

前書き

最小バイトを使用して、ひととりパズルのソルバーを作成します。

チャレンジ

あなたの仕事は、ヒトリ(ひとり、日本語で「一人で」の単語。ゲーム名の意味は「一人でいる」)の論理パズルを書くことです。ルールは次のとおりです。

  • n行n列のセルのグリッドが表示され、各セルには1〜nの整数が含まれます。
  • 目標は、次の2つのルールで示された制限に従って、指定されたグリッドから番号を削除することにより、グリッドの各行と各列に複数の番号が表示されないようにすることです。
  • 2つの隣接する(水平または垂直)セルから2つの数値を削除することはできません。
  • 残りの番号付きセルはすべて相互に接続する必要があります。残りの2つの番号付きセルは、隣接する残りの番号(水平または垂直)を接続するセグメントのみで構成される曲線で接続できることを意味します。(これが欠落していることを指摘してくれた@ user202729に感謝)

今までにルールが明確になっていることを願っています。ルールについて不明な点がある場合は、ウィキペディアのページを確認してください

テストケース

番号が削除されるセルは0で表されます。

Input  ->  Output

4
2 2 2 4      0 2 0 4
1 4 2 3  ->  1 4 2 3
2 3 2 1      2 3 0 1
3 4 1 2      3 0 1 2

4
4 2 4 3      0 2 4 3
4 1 1 2  ->  4 1 0 2
3 1 2 1      3 0 2 1
4 3 1 3      0 3 1 0

5
1 5 3 1 2      1 5 3 0 2
5 4 1 3 4      5 0 1 3 4
3 4 3 1 5  ->  3 4 0 1 5
4 4 2 3 3      4 0 2 0 3
2 1 5 4 4      2 1 5 4 0

8
4 8 1 6 3 2 5 7      0 8 0 6 3 2 0 7
3 6 7 2 1 6 5 4      3 6 7 2 1 0 5 4
2 3 4 8 2 8 6 1      0 3 4 0 2 8 6 1
4 1 6 5 7 7 3 5  ->  4 1 0 5 7 0 3 0
7 2 3 1 8 5 1 2      7 0 3 0 8 5 1 2
3 5 6 7 3 1 8 4      0 5 6 7 0 1 8 0
6 4 2 3 5 4 7 8      6 0 2 3 5 4 7 8
8 7 1 4 2 3 5 6      8 7 1 4 0 3 0 6

9
8 6 5 6 8 1 2 2 9      8 0 5 6 0 1 2 0 9
5 6 2 4 1 7 9 8 3      5 6 2 4 1 7 9 8 3
5 8 2 5 9 9 8 2 6      0 8 0 5 0 9 0 2 0
9 5 6 6 4 3 8 4 1      9 5 6 0 4 3 8 0 1
1 1 6 3 9 9 5 6 2  ->  0 1 0 3 9 0 5 6 2
1 1 4 7 3 8 3 8 6      1 0 4 7 0 8 3 0 6
3 7 4 1 2 6 4 5 5      3 7 0 1 2 6 4 5 0
3 3 1 9 8 7 7 4 5      0 3 1 9 8 0 7 4 5
2 9 7 5 3 5 9 1 3      2 9 7 0 3 5 0 1 0 

これらのテストケースは、それぞれConcept Is PuzzlesPuzzleBooksConcept Is PuzzlesWikipedia、およびYoutubeから取得されます。

スペック

  • 例外処理を心配する必要はありません。

  • 入力は常にユニークなソリューションを備えた有効なパズルであり、これを利用してコードを記述することができると想定できます。

  • これはであり、最小バイト数が勝ちます。

  • 4 <= n <= 9(元々16、Stewie Griffinの提案に従って9に変更され、IOのトラブルも軽減)

  • 任意の標準フォームを介して入力および出力を行うことができ、フォーマットを自由に選択できます。

  • 出力形式に関するいくつかの提案があります(ただし、これらに限定されません)

    • 最終グリッドを出力する
    • 削除されたすべての数値を含むグリッドを出力する
    • 上記のいずれかの座標のリストを出力します
  • いつものように、デフォルトの抜け穴がここに適用されます。


関連(このチャレンジに触発された):マトリックス内のすべての要素が接続されているかどうかを確認する

私の最後の課題:セブンスのゲームの拡張


2
確定的なランタイムを必要とするか、最大のテストケースを1分以内に(または多かれ少なかれ)解決できることを要求することをお勧めします。また、あなたは言う4 <= n <= 16が、最大のテストケースはですn=9n=16テストケースを投稿するか、と言うことをお勧めします4 <= n <= 9。ちなみに素敵なチャレンジ:)
スチューウィーグリフィン

1
@StewieGriffinでは、別の最速のアルゴリズムチャレンジを行うだけではどうですか?
ジョナサンアラン

@StewieGriffinは16x16を追加しようとしましたが、まだ準備ができていません。9に変更されました。
ウェイジュン周

@JonathanAllanあなたが望むように。
ウェイジュンジョウ

再 "私はそれが良くなるかどうかを確認するために変更を加えることにしました":それは間違いなく悪いだろう。また、既に投稿されたチャレンジを変更しないでください。
user202729

回答:


3

Haskell、374バイト

import Data.Array;import Data.List;r=range;p=partition
c(e,f)=p(\(b,p)->any(==1)[(b-d)^2+(p-q)^2|(d,q)<-e])f
n#g=[s|(o,(e:f))<-[p((==0).(g!))$indices g],
 null.fst$c(o,o),null.snd$until(null.fst)c([e],f),
 s<-case[((l,c),d)|((l,c),h)<-assocs g,h>0,
 d<-[filter((==h).(g!))$r((l,c+1),(l,n))++r((l+1,c),(n,c))],d/=[]]
 of[]->[g];((c,d):_)->n#(g//[(c,0)])++n#(g//[(c,0)|c<-d])]

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


ありがとうございました。非常に印象的。個人的に私は初心者ですが、Haskellの大ファンでもあります。
ウェイジュン周


1
上記の文字数が多すぎて、コメントを残しています。空白を削除しているだけです
-H.PWiz


2

APL(Dyalog Unicode)、133バイトSBCS

{q←{⊢/4 2⍴⍵}⌺3 3g←⍵=⊂∪,⍵⋄⍵×~1⊃{((⌈/q b)⌈b<{2<≢∪0,,(⍵×⊢⌈⌈/∘q)⍣≡⍵×(⍴⍵)⍴1+⍳≢,⍵}¨~b∘⌈¨⊂⍤2∘.≡⍨⍳⍴b)(+/↑w<g×⌈.⌈⍨w×g)⌈w b←⍵}⍣≡×\(⌈/=∘⌽⍨q⍵)0}

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

ルール#4(セルは単一の接続コンポーネントを形成する必要があります)の実装はかなり無駄ですが、それでもTIOで約10秒ですべてのテストに合格します。


全体的なアルゴリズム:それぞれ黒と白であることが確実なセルに対してb、2つのブール行列を保存しwます。bすべてゼロとして初期化します。w一致する隣接セルが反対のセルに対してのみ1として初期化します。

を繰り返しbw落ち着きます:

  • b同じ行(水平または垂直)にあり、セル内のセルと同じ値のセルに追加するw

  • wのすべてのセルのすぐ隣に追加するb

  • wすべてのカットポイントに追加-削除すると、黒以外のセルのグラフが複数の接続コンポーネントに分割されます

最後に、出力にnot(b)元の行列を掛けます。


ご関心と説明をありがとうございます。あなたが説明したものは、パズルを手で解決する場合に使用される典型的なアルゴリズムでもあると思います。
周潤順

1
正直に言うと、私はひととりを手で解こうとさえしませんでした。これらのトリックはウィキペディアから得たもので、アルゴリズムが常に(一意の)ソリューションに収束するという証拠はありません。
-ngn

2

ゼリー、62 バイト

別の質問からuser202729のisConnectedモナドリンクを使用します。


FJṁa@µ«Ḋoµ€ZUµ4¡ÐLFQL<3
ḟ0ĠḊ€
¬T€œ&2\;Ç€FȦ
ZÇȯÇ_1Ŀ
2ḶṗLṗLa⁸ÇÞḢ

リストのリストの表現を印刷する完全なプログラム。
総当たりで動作し、愚かなほど非効率的です。

オンラインでお試しください!-60秒のTIO制限内でサイズ4を実行するのは非効率的であるため、3 x 3です!

どうやって?

FJṁa@µ«Ḋoµ€ZUµ4¡ÐLFQL<3 - Link 1 isConnected? List of lists
...                     - 1 if connected 0 if not -- see linked answer in the header

ḟ0ĠḊ€ - Link 2, helperFor-AnyRepeatedValues: list
ḟ0    - filter out zeros
  Ġ   - group indices by value (i.e. [[indices of min],...,[indices of max]]
   Ḋ€ - dequeue €ach -- leaving a list of empty lists iff no repeated values
      -                 any remaining values are non-zero (1-based indexing in Jelly)

¬T€œ&2\;Ç€FȦ - Link 3, columnwiseAnyAdjacentZerosOrRowwiseAnyRepeatedValues: list of lists
¬            - logical not (convert all zeros to ones and all others to zeros)
 T€          - for €ach row get a list of truthy indexes (i.e. indexes of original zeros)
     2\      - pairwise reduction (i.e. for neighbouring rows) with:
   œ&        -   intersection (empty if no columnwise adjacent original zeros
             -                 any remaining values are non-zero due to 1-based indexing)
        Ç€   - call last link (1) as a monad for €ach row
       ;     - concatenate
          F  - flatten into a single list (empty iff no columnwise adjacent original zeros
             -                                   AND no rowwise repeated values)
           Ȧ - any and all (0 if empty [or contains any zero -- never] else 1)

ZÇȯÇ_1Ŀ - Link 4, validity check? list of lists
Z       - transpose
 Ç      - call last link (2) as a monad rowwiseAnyAdjacentZerosOrColumnwiseAnyRepeatedValues?
   Ç    - call last link (2) as a monad columnwiseAnyAdjacentZerosOrRowwiseAnyRepeatedValues?
  ȯ     - logical OR
     1Ŀ - call link 1 as a monad (isConnected?)
    _   - subtract
        - this yields -1 for valid, while it yields 0 or 1 if not.

2ḶṗLṗLa⁸ÇÞḢ - Main link: list of lists
2Ḷ          - lowered range of 2 -> [0,1]
   L        - length (number of rows in the input)
  ṗ         - Cartesian power (all lists of zeros and ones of length L)
     L      - length (number of rows in the input again)
    ṗ       - Cartesian power (all grids of zeros and ones of same shape as the input)
       ⁸    - the input
      a     - logical AND -- effectively uses each of the formed grids as a mask
         Þ  - sort by:
        Ç   -   last link (3) as a monad
          Ḣ - head
            - implicit print

スタートとしてのナイス。ありがとうございました。見てみましょう。
ウェイジュン周

4番目のルールを忘れました。(接続済み)
-user202729

(JellyでBFS / DFS / DSUを実装して幸運を祈ります)
-user202729

ああ...コンピュータにいるときに削除します。ありがとう。
ジョナサンアラン

ええ、私が言うことではないゼリーの60バイト、<100 ... <、たとえば、これが可能であるとは思わない
エリックOutgolfer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.