解决瞳难题


21

介绍

用最少的字节数写一本关于Hitori难题的求解器。

挑战

您的任务是为Hitori(日语中的“孤独”一词;游戏名称的含义为“让我一个人呆”)编写解算器。规则如下:

  • 您会看到一个n×n的单元格网格,每个单元格包含1到n(含)之间的整数。
  • 您的目标是通过从给定的网格中删除数字,以确保在该网格的每一行和每一列中都不会出现多次重复的数字,但要遵守以下两个规则中的限制,
  • 您不能从两个相邻的(水平或垂直)单元格中删除两个数字。
  • 其余编号的单元必须全部相互连接。这意味着可以将任意两个剩余编号的单元格与一条曲线连接,该曲线仅由连接相邻剩余编号(水平或垂直)的线段组成。(感谢@ user202729指出这是丢失的)

我希望规则现在已经明确。如果规则有任何不清楚的地方,请查看Wikipedia页面

测试用例

删除数字的单元格用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 PuzzlesWikipediaYoutube

眼镜

  • 无需担心异常处理。

  • 可以假设输入始终是具有唯一解决方案的有效难题,并且可以在编写代码时利用此优势。

  • 这是,赢得的最低字节数。

  • 4 <= n <= 9(最初为16,根据Stewie Griffin的建议更改为9,也节省了IO的麻烦)

  • 您可以采用任何标准格式输入和提供输出,并且可以自由选择格式。

  • 有关输出格式的一些建议是(但您不限于这些)

    • 输出最终网格
    • 输出包含所有已删除数字的网格
    • 输出上述之一的坐标列表
  • 与往常一样,默认漏洞适用于此。


相关(受此挑战启发):检查矩阵中的所有元素是否都已连接

我的最后一个挑战:七人游戏的扩展


2
我建议您需要确定性的运行时,或要求最大的测试用例可以在不超过1分钟(或更多/更少)的时间内解决。您也说过4 <= n <= 16,但是最大的测试案例是n=9。我建议您发布一个n=16测试案例,或者说4 <= n <= 9。顺便说一句好挑战:)
Stewie Griffin

1
@StewieGriffin单独进行最快的算法挑战怎么样?
乔纳森·艾伦

@StewieGriffin尝试添加16x16,但尚未准备好。现在更改为9。

@JonathanAllan如您所愿。

关于“我决定进行更改以查看是否会更好”:肯定会更糟。另外,您不应该更改已经发布的挑战。
user202729 '18

Answers:


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以及w分别确定为黑色和白色的单元格。初始化b为全零。w仅对具有相反匹配邻居的那些单元初始化为1。

重复,直到bw安身立命:

  • 将与b在同一行(水平或垂直)且值与的单元格相同的单元格相加w

  • 添加到w中所有单元的直接邻居b

  • 添加到w所有切点-删除后的单元会将非黑色单元的图分成多个相连的分量

最后,输出not(b)乘以原始矩阵。


非常感谢您的关注和解释。我认为您所描述的也是一种手动解决难题的典型算法。
周玮钧

1
老实说,我什至从未尝试过手工解决瞳。我从Wikipedia那里获得了这些技巧,但是我没有证据表明该算法将始终收敛到唯一的解决方案。
ngn

2

果冻,62 字节

从另一个问题使用user202729的isConnected单链链接


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

完整程序,用于打印列表列表的表示形式。
靠蛮力运作,效率低下。

在线尝试!-3 x 3,因为即使在60秒TIO限制内运行4号尺寸也太低了!

怎么样?

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

NIce作为开始。谢谢。我会看看。

您忘记了第四条规则。(已连接)
user202729 '18

(祝您在Jelly中实现BFS / DFS / DSU
感到幸运

哦...在计算机上时会删除。谢谢。
乔纳森·艾伦

是的,我认为这不可能发生在<60字节的果冻中,而不是说<100 ...
Erik the Outgolfer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.