Bạn có thể kết nối các dấu chấm?


18

Thử thách này dựa trên Flow Free. Một phiên bản trực tuyến có thể được tìm thấy ở đây: http://www.moh97.us/

Bạn sẽ được đưa ra một câu đố, và bạn phải quay lại 1nếu câu đố có thể giải được, hoặc 0nếu không.

Để giải câu đố, người chơi phải tạo một đường dẫn để kết nối từng cặp số bằng cách sử dụng mỗi ô vuông trống chính xác một lần.

Bạn được truyền vào các kích thước của hình vuông, và sau đó là x, y, c (trong đó c là một số đại diện cho màu sắc) của mỗi dấu chấm. Ví dụ:

Nếu 5,5 0,0,0 3,0,1 1,1,2 1,2,2 4,2,1 4,4,0được chuyển cho bạn, nó sẽ đại diện cho:

0..1.
.2...
.2..1
....0

Và nên trả lại 1.


Dưới đây là một số vấn đề kiểm tra:

5,2 2,0,1 0,1,2 4,1,2 đại diện:

..1..
2...2

và không thể giải quyết được vì chỉ có 1 1.

4,2 0,0,0 3,0,0 0,1,0 3,1,0 đại diện:

0..0
0..0

và không thể giải quyết được vì nó bao gồm hơn 2 0giây.

8,6 0,0,1 7,5,1 đại diện:

1.......
........
........
........
........
.......1

và không thể giải quyết được (vì bạn không thể sử dụng mọi ô vuông).

2,5 0,0,1 2,0,6 4,0,6 0,1,4 3,1,4 4,1,1 đại diện:

1.6.6
4..41

và không thể giải quyết được vì bạn không thể kết nối 1s.

6,3 1,0,4 5,0,1 0,1,4 1,1,3 5,1,3 0,2,2 3,2,2 5,2,1 đại diện:

.4...1
43...3
2..2.1

và không thể giải quyết được vì bạn không thể kết nối 1s (hoặc 3s), vì hai đường dẫn nhất thiết phải giao nhau.

5,2 0,0,1 3,0,1 0,1,3 4,1,1 đại diện:

1..1.
3...3

và không thể giải quyết được vì bạn không thể sử dụng tất cả các hình vuông trong việc xây dựng một đường dẫn.

2,2 0,0,0 1,1,0 đại diện:

1.
.1

và không thể giải quyết được vì bạn không thể sử dụng tất cả các hình vuông ở đây

Dưới đây là một số bài kiểm tra khác:

5,5 0,3,0 0,4,1 1,2,2 1,3,1 2,0,0 3,0,4 3,1,2 3,3,5 3,4,4 4,4,5 nên trả lại 1

13,13 1,1,0 9,1,1 10,1,2 11,1,3 1,2,4 2,2,5 5,2,6 7,2,7 3,3,0 5,4,6 6,4,1 9,6,3 4,7,8 5,8,9 12,8,8 11,9,10 2,10,4 4,10,2 9,10,5 11,10,7 1,11,9 12,12,10 nên trả lại 1

7,7 0,0,0 0,1,1 1,1,2 2,1,3 4,2,4 0,3,1 5,3,3 0,4,4 2,4,5 5,4,2 0,5,0 1,5,5 3,5,6 3,7,6 nên trả về 0


Đây là một mã golf, và các quy tắc tiêu chuẩn được áp dụng.


2
Liệu một giải pháp phải "thực tế" đúng hay chỉ đúng về mặt lý thuyết? Chẳng hạn, không gian trạng thái có thể được chia thành việc gán một trong 6 cấu hình đầu vào-đầu vào có thể cho mỗi ô trống. Khả năng thanh toán được xác định dễ dàng bằng cách thử tất cả các kết hợp 6 ^ N và quay lại 1nếu bất kỳ một trong số chúng truy cập vào tất cả các ô và kết nối tất cả các thiết bị đầu cuối. Rõ ràng cách tiếp cận này sẽ không hoàn thành trong một khoảng thời gian hợp lý cho bất cứ điều gì ngoại trừ nhỏ nhất N(số lượng ô trống), nhưng chúng tôi vẫn có một đảm bảo toán học rằng thuật toán cuối cùng sẽ trả về giá trị chính xác.
COTO

1
Có lẽ nếu bạn đưa ra hai bộ lưới chơi khổng lồ (một công khai để kiểm tra, một riêng để xác thực) bằng thuật toán chung và coi người chiến thắng là bài nộp xác định chính xác khả năng thanh toán của các lưới nhất trong một số riêng tư trong một số lượng thời gian hợp lý trên mỗi lưới, với kích thước chương trình là một máy bẻ khóa nếu hai lần gửi có tiện ích như nhau. Tôi chắc chắn sẽ thử sức mình với điều đó.
COTO

1
@NathanMerrill: Vấn đề có thể giảm xuống SAT và do đó NP khó.
COTO

3
@NathanMerrill giảm một vấn đề thành SAT có nghĩa là vấn đề nằm ở NP, không phải là NP-hard - nó giảm SAT thành vấn đề cho thấy độ cứng NP của vấn đề. Trang bạn liên kết đến có một liên kết đến bằng chứng về tính đầy đủ của NP.
tông_box

1
@VisualMelon Chữ số màu là từ sai. Mỗi màu được đại diện bởi một số khác nhau, không phải chữ số.
Nathan Merrill

Câu trả lời:


3

Haskell

import Data.List.Split
import qualified Data.Sequence as Q
import Data.List
import Control.Monad

data A a = S a | E a | P a | X deriving Eq

sc = foldr1 (Q.><)
sp b x y p = Q.update y (Q.update x p $ b `Q.index` y) b
dt b c | S c `elem` sc b = E c
       | otherwise = S c
ad b [x, y, c] = sp b x y (dt b c)

ep b [x, y, c] = do
  let nps = filter ob [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]
      ns = map gp nps
  [b | E c `elem` ns] ++ do
    (x', y') <- filter ((== X) . gp) nps
    ep (sp b x' y' (P c)) [x', y', c]
  where ob (u, v) = 0 <= u && u < length (b `Q.index` 0) && 0 <= v && v < length b
        gp (u, v) = b `Q.index` v `Q.index` u

rd i = let [c, r] : ps = (map read . splitOn ",") <$> words i :: [[Int]]
           e = Q.replicate r $ Q.replicate c X
           cs = map last ps
           ss = nubBy (\[_,_,c1] [_,_,c2] -> c1 == c2) ps
           b = foldl ad e ps
           bs = foldM ep b ss
       in if even (length cs) && length ss == length cs `div` 2 &&
             (all (\[j,k] -> j==k) . chunksOf 2 . sort $ cs) &&
             any (null . Q.elemIndicesL X . sc) bs
           then 1
           else 0

main = rd <$> getContents >>= print

Chìa khóa

  • sc: Seq concat
  • sp: đặt vị trí
  • dt: loại dấu chấm (nghĩa là bắt đầu hoặc kết thúc dòng)
  • quảng cáo: thêm dấu chấm
  • ep: mở rộng đường dẫn
  • nd: chạy dấu chấm (thuật toán thuần túy chính)

2
Cảm ơn bạn đã gửi và chào mừng đến với trao đổi ngăn xếp PPCG. Đây là một thử thách golf mã, có nghĩa là mục đích là để viết chương trình ngắn nhất để giải quyết thử thách. Bạn đang dẫn đầu, bởi vì bạn có câu trả lời duy nhất, nhưng bạn nên cố gắng rút ngắn chương trình của mình càng nhiều càng tốt.
isaacg

Tôi thực sự ấn tượng rằng bạn đã trả lời câu hỏi này sau tất cả thời gian này. Ngoài ra, vấn đề này không chỉ là thử thách về mã, nhưng tôi đã sử dụng môn đánh gôn, vì rất khó để đưa ra một cơ sở tính điểm khác.
Nathan Merrill

Vâng, tôi đã không lo lắng quá nhiều về khía cạnh "golf"; Tôi đang cố gắng học Haskell và có vẻ như đó là một vấn đề thú vị :-)
Matt
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.