GNU Prolog, 493 byte
z(_,[_,_]).
z(F,[A,B,C|T]):-call(F,A,B,C),z(F,[B,C|T]).
i([],[],[],[]).
i([H|A],[I|B],[J|C],[H-I-J|T]):-i(A,B,C,T).
c(A/_-B/_-C/_,D/_-_/T-E/_,F/_-G/_-H/_):-T#=A+B+C+D+E+F+G+H.
r(A,B,C):-i(A,B,C,L),z(c,L).
q(63,V):-var(V).
q(42,1/_).
q(X,0/Y):-Y#=X-48.
l([],[0/_]).
l([H|T],[E|U]):-q(H,E),l(T,U).
p([],[[0/_,0/_]],0).
p([],[[0/_|T]],N):-M#=N-1,p([],[T],M).
p([H|T],[[0/_|E]|U],N):-p(T,U,N),l(H,E).
m([H|A],B):-length(H,N),p([],[R],N),p([H|A],M,N),z(r,[R|M]),p(B,M,N).
s(A):-setof(B,m(A,B),[_]).
Một vị từ bổ sung có thể hữu ích để thử nghiệm (không phải là một phần của nội dung gửi):
d([]).
d([H|T]):-format("~s~n",[H]),d(T).
Prolog chắc chắn là ngôn ngữ phù hợp để giải quyết nhiệm vụ này từ quan điểm thực tế. Chương trình này khá nhiều chỉ nêu các quy tắc của Minesweeper và cho phép người giải quyết ràng buộc của GNU Prolog giải quyết vấn đề từ đó.
z
và i
là các hàm tiện ích ( z
thực hiện một loại hoạt động giống như nếp gấp nhưng trên bộ ba phần tử liền kề chứ không phải 2; i
chuyển 3 danh sách n phần tử thành danh sách n 3 tuple). Chúng tôi lưu trữ nội bộ một ô như , trong đó x là 1 cho một mỏ và 0 cho một nonmine và y là số lượng các mỏ liền kề; thể hiện sự hạn chế này trên bảng. áp dụng cho mọi hàng của hội đồng quản trị; và vì vậy hãy kiểm tra xemx/y
c
r
c
z(r,M)
M
là một hội đồng hợp lệ.
Thật không may, định dạng đầu vào cần thiết để thực hiện công việc này trực tiếp là không hợp lý, vì vậy tôi cũng phải bao gồm một trình phân tích cú pháp (có thể chiếm nhiều mã hơn công cụ quy tắc thực tế và phần lớn thời gian để gỡ lỗi; công cụ quy tắc Minesweeper hoạt động khá nhiều lần đầu tiên, nhưng trình phân tích cú pháp đầy thinkos). q
chuyển đổi một ô duy nhất giữa một mã ký tự và chúng tôi chuyển đổi toàn bộ bảng (bao gồm cả viền dưới cùng, nhưng không bao gồm ô trên cùng). Tất cả các chức năng này có thể được chạy tiến hoặc lùi, do đó có thể phân tích cú pháp và in đẹp bảng. (Có một số vặn vẹo khó chịu xung quanh với đối số thứ ba đểx/y
định dạng . l
chuyển đổi một dòng của bảng (để lại một ô được biết là không phải là mỏ, nhưng với một số lượng không xác định của các mỏ lân cận, ở mỗi cạnh của dòng là một đường viền);p
p
, trong đó chỉ định chiều rộng của bảng; điều này là do Prolog không có loại ma trận và nếu tôi không buộc bảng thành hình chữ nhật, chương trình sẽ đi vào một vòng lặp vô hạn để thử các đường viền rộng hơn xung quanh bảng.)
m
là chức năng giải quyết Minesweeper chính. Nó phân tích chuỗi đầu vào, tạo ra một bảng có đường viền chính xác (thông qua việc sử dụng trường hợp đệ quyp
để chuyển đổi hầu hết bảng, sau đó gọi trực tiếp trường hợp cơ sở để tạo đường viền trên cùng, có cùng cấu trúc với đường viền dưới). Sau đó, nó gọiz(r,[R|M])
để chạy công cụ quy tắc Minesweeper, mà (với mẫu cuộc gọi này) trở thành một trình tạo chỉ tạo các bảng hợp lệ. Tại thời điểm này, hội đồng quản trị vẫn được thể hiện dưới dạng một tập hợp các ràng buộc, điều này có khả năng gây khó xử cho chúng tôi; có lẽ chúng ta có thể có một tập các ràng buộc có thể đại diện cho nhiều bảng. Ngoài ra, chúng tôi chưa chỉ định bất cứ nơi nào mà mỗi ô vuông chứa tối đa một mỏ. Như vậy, chúng ta cần phải "thu gọn dạng sóng" một cách rõ ràng của từng ô vuông, yêu cầu nó phải cụ thể là một (một) mỏ hoặc một nonmine, và cách dễ nhất để làm điều này là chạy nó qua trình phân tích cú pháp ngược ( var(V)
trên trường hợp chạy ngược lại, và do đó làm suy yếu bảng buộc nó phải được biết đầy đủ). Cuối cùng, chúng tôi trả lại bảng được phân tích cú pháp từq(63,V)
trường hợp được thiết kế để ngăn chặn ; do đó trở thành một máy phát điện có một bảng chưa biết một phần và tạo ra tất cả các bảng đã biết phù hợp với nó.?
m
m
Điều đó thực sự đủ để giải quyết Minesweeper, nhưng câu hỏi rõ ràng yêu cầu kiểm tra xem có chính xác một giải pháp hay không, thay vì tìm tất cả các giải pháp. Như vậy, tôi đã viết một biến vị ngữ bổ sung s
đơn giản là chuyển đổi trình tạo m
thành một tập hợp, và sau đó xác nhận rằng tập hợp đó có chính xác một phần tử. Điều này có nghĩa là s
sẽ trả về truey ( yes
) nếu thực sự có chính xác một giải pháp, hoặc falsey ( no
) nếu có nhiều hơn một hoặc ít hơn một.
d
không phải là một phần của giải pháp và không được bao gồm trong bytecount; đó là một chức năng để in một danh sách các chuỗi như thể nó là một ma trận, cho phép kiểm tra các bảng được tạo bởi m
(theo mặc định, GNU Prolog in các chuỗi như một danh sách các mã ASCII, vì nó xử lý hai từ đồng nghĩa; khá khó đọc). Nó hữu ích trong quá trình thử nghiệm hoặc nếu bạn muốn sử dụng m
như một bộ giải Minesweeper thực tế (bởi vì nó sử dụng một bộ giải ràng buộc, nó rất hiệu quả).
2?
không có giải pháp, điều đó có nghĩa là nó không thể đến từ một trò chơi thực tế của Minesweeper. Do đó, nó không được coi là "bảng Minesweeper" ... vâng?)