Giải câu đố Hitori


21

Giới thiệu

Viết một bộ giải cho các câu đố Hitori bằng cách sử dụng ít byte nhất.

Thử thách

Nhiệm vụ của bạn là viết một bộ giải cho Hitori (と, từ "một mình" trong tiếng Nhật; ý nghĩa của tên trò chơi là "Để tôi yên") các câu đố logic. Luật như sau:

  • Bạn được trình bày với một lưới các ô n-by-n, mỗi ô chứa một số nguyên nằm trong khoảng từ 1 đến n (bao gồm).
  • Mục tiêu của bạn là đảm bảo rằng không có số nào xuất hiện nhiều hơn một lần trong mỗi hàng và mỗi cột của lưới, bằng cách xóa các số khỏi lưới đã cho, tuân theo các hạn chế được chỉ ra trong hai quy tắc tiếp theo,
  • Bạn không thể xóa hai số từ hai ô liền kề (theo chiều ngang hoặc chiều dọc).
  • Các ô được đánh số còn lại phải được kết nối với nhau. Điều đó có nghĩa là bất kỳ hai ô được đánh số còn lại nào cũng có thể được kết nối với một đường cong chỉ bao gồm các phân đoạn kết nối các số còn lại liền kề (theo chiều ngang hoặc chiều dọc). (Cảm ơn @ user202729 vì đã chỉ ra rằng điều này bị thiếu)

Tôi hy vọng các quy tắc được rõ ràng bây giờ. Nếu có bất cứ điều gì không rõ ràng về các quy tắc, hãy kiểm tra trang Wikipedia .

Các trường hợp thử nghiệm

Các ô mà từ đó các số được loại bỏ được biểu thị bằng 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 

Những trường hợp thử nghiệm được lấy từ khái niệm này là câu đố , PuzzleBooks , khái niệm này là câu đố , Wikipedia , và Youtube , tương ứng.

Thông số kỹ thuật

  • Không cần phải lo lắng về việc xử lý ngoại lệ.

  • Bạn có thể giả định rằng đầu vào luôn là một câu đố hợp lệ với một giải pháp duy nhất và bạn có thể tận dụng điều này bằng cách viết mã của mình.

  • Đây là , số byte thấp nhất sẽ thắng.

  • 4 <= n <= 9 (16 ban đầu, được đổi thành 9 theo đề xuất của Stewie Griffin, cũng tiết kiệm một số rắc rối trong IO)

  • Bạn có thể nhận đầu vào và cung cấp đầu ra thông qua bất kỳ hình thức tiêu chuẩn nào và bạn có thể tự do chọn định dạng.

  • Một số đề xuất cho định dạng đầu ra là (nhưng bạn không bị hạn chế đối với những định dạng này)

    • Xuất ra lưới cuối cùng
    • Xuất ra lưới chứa tất cả các số bị loại bỏ
    • Xuất ra một danh sách tọa độ của một trong những điều trên
  • Như thường lệ, sơ hở mặc định áp dụng ở đây.


Liên quan (lấy cảm hứng từ thử thách này): Kiểm tra xem tất cả các yếu tố trong ma trận có được kết nối không

Thử thách cuối cùng của tôi: Mở rộng Trò chơi Sevens


2
Tôi đề nghị bạn yêu cầu thời gian chạy xác định hoặc yêu cầu trường hợp thử nghiệm lớn nhất có thể được giải quyết trong không quá 1 phút (hoặc có thể nhiều hơn / ít hơn). Ngoài ra, bạn nói 4 <= n <= 16, nhưng trường hợp thử nghiệm lớn nhất là cho n=9. Tôi đề nghị bạn hoặc đăng một n=16trường hợp thử nghiệm, hoặc nói 4 <= n <= 9. Nhân tiện, đây là một thử thách thú vị :)
Stewie Griffin

1
@StewieGriffin làm thế nào về việc chỉ có một thử thách thuật toán nhanh nhất riêng biệt?
Jonathan Allan

@StewieGriffin Đã thử thêm 16x16 nhưng chưa hoàn toàn sẵn sàng. Thay đổi thành 9 bây giờ.
Weijun Zhou

@Jonathan ALLan Như bạn muốn.
Weijun Zhou

Re "Tôi quyết định thực hiện một thay đổi để xem liệu nó sẽ tốt hơn": Nó chắc chắn sẽ tồi tệ hơn. Ngoài ra, bạn không nên thay đổi một thách thức đã được đăng.
dùng202729

Câu trả lời:


3

Haskell , 374 byte

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])]

Hãy thử trực tuyến!


Cảm ơn bạn. Rất ấn tượng. Cá nhân tôi là người mới bắt đầu nhưng cũng là một fan hâm mộ lớn của Haskell.
Weijun Zhou


1
Ở trên là quá nhiều nhân vật quá để lại một bình luận cùng. Nó chỉ xóa một số khoảng trắng
H.PWiz


2

APL (Dyalog Unicode) , 133 byte 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}

Hãy thử trực tuyến!

Việc thực hiện quy tắc số 4 của tôi (các ô phải tạo thành một thành phần được kết nối duy nhất) khá lãng phí, nhưng điều này vẫn vượt qua tất cả các thử nghiệm trong khoảng 10 giây trên TIO.


Thuật toán tổng thể: Lưu trữ hai ma trận boolean bwcho các ô chắc chắn có màu đen và trắng tương ứng. Khởi tạob là tất cả bằng không. Khởi tạo wlà 1 chỉ cho những ô có hàng xóm đối diện.

Lặp lại cho đến khi bwổn định:

  • thêm vào bcác ô nằm trên cùng một dòng (ngang hoặc dọc) và có cùng giá trị với một ô trongw

  • thêm vào whàng xóm ngay lập tức của tất cả các tế bào trongb

  • thêm vào wtất cả các điểm cắt - các ô bị loại bỏ sẽ chia biểu đồ của các ô không đen thành nhiều thành phần được kết nối

Cuối cùng, đầu ra not(b)nhân với ma trận gốc.


Cảm ơn bạn rất nhiều vì sự quan tâm và giải thích của bạn. Tôi nghĩ những gì bạn mô tả cũng là một thuật toán điển hình được sử dụng nếu một người giải câu đố bằng tay.
Weijun Zhou

1
Thành thật mà nói, tôi thậm chí không bao giờ cố gắng giải quyết Hitori bằng tay. Tôi đã nhận được những thủ thuật này từ Wikipedia và tôi không có bằng chứng nào cho thấy thuật toán sẽ luôn hội tụ tất cả các cách để giải pháp (duy nhất).
ngn

2

Thạch , 62 byte

Sử dụng liên kết đơn âm isConnected của user202729 từ một câu hỏi khác.


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

Một chương trình đầy đủ in một đại diện của một danh sách các danh sách.
Hoạt động bằng vũ lực và là không hiệu quả ngu ngốc.

Hãy thử trực tuyến! - 3 trên 3, vì nó quá kém hiệu quả để chạy ngay cả kích thước 4 trong giới hạn TIO 60 giây!

Làm sao?

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 như một khởi đầu. Cảm ơn bạn. Tôi sẽ xem thử.
Weijun Zhou

Bạn đã quên quy tắc thứ 4. (đã kết nối)
user202729

(chúc may mắn với việc triển khai BFS / DFS / DSU trong Jelly)
user202729

Oh ... sẽ xóa khi ở máy tính. Cảm ơn.
Jonathan Allan

vâng, tôi không nghĩ điều này là có thể, giả sử, <60 byte Jelly, không phải nói <100 ...
Erik the Outgolfer 30/1/18
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.