जीएनयू प्रोलॉग, 493 बाइट्स
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),[_]).
एक अतिरिक्त विधेय जो परीक्षण के लिए उपयोगी हो सकता है (प्रस्तुत करने का हिस्सा नहीं):
d([]).
d([H|T]):-format("~s~n",[H]),d(T).
व्यावहारिक रूप से इस कार्य को हल करने के लिए प्रोलॉग की निश्चित भाषा सही है। यह कार्यक्रम काफी हद तक माइनस्वीपर के नियमों को बताता है और जीएनयू प्रोलॉग के अड़चन समाधान को वहां से समस्या को हल करने देता है।
z
और i
यूटिलिटी फ़ंक्शंस हैं ( z
एक तरह का फोल्ड-ऑपरेशन होता है, लेकिन 2 के बजाय तीन आसन्न तत्वों के सेट पर; n तत्वों i
की 3 सूचियों को n 3-ट्यूपल्स की सूची में स्थानांतरित करता है )। हम आंतरिक रूप से एक सेल को स्टोर करते हैं , जहां x एक खदान के लिए 1 और नॉनमाइन के लिए 0 है, और y समीपवर्ती खानों की संख्या है; इस बाधा को बोर्ड पर व्यक्त करता है। बोर्ड की हर पंक्ति पर लागू होता है; और यह देखने के लिए कि क्या एक वैध बोर्ड है।x/y
c
r
c
z(r,M)
M
दुर्भाग्य से, इस काम को सीधे करने के लिए आवश्यक इनपुट प्रारूप अनुचित है, इसलिए मुझे एक पार्सर भी शामिल करना पड़ा (जो कि शायद वास्तविक नियम इंजन की तुलना में अधिक कोड के लिए होता है, और अधिकांश समय डिबगिंग में खर्च होता है; माइनस्वीपर नियम इंजन बहुत अच्छा काम करता है; पहली बार, लेकिन पार्सर थिंकोस से भरा था)। q
एक चरित्र कोड और हमारे प्रारूप के बीच एक एकल सेल धर्मान्तरित । बोर्ड की एक पंक्ति को परिवर्तित करता है (एक सेल को छोड़कर जो एक खदान के रूप में जाना जाता है, लेकिन एक सीमा के रूप में लाइन के प्रत्येक किनारे पर अज्ञात खानों की संख्या के साथ);x/y
l
p
पूरे बोर्ड को परिवर्तित करता है (नीचे की सीमा सहित, लेकिन शीर्ष को छोड़कर)। इन सभी कार्यों को आगे या पीछे चलाया जा सकता है, इस प्रकार बोर्ड को पार्स और सुंदर प्रिंट दोनों किया जा सकता है। (तीसरे तर्क के साथ कुछ कष्टप्रद झंझट है p
, जो बोर्ड की चौड़ाई को निर्दिष्ट करता है, इसका कारण यह है कि प्रोलॉग में एक मैट्रिक्स प्रकार नहीं है, और अगर मैं बोर्ड को आयताकार होने के लिए विवश नहीं करता हूं, तो कार्यक्रम में जाएगा एक अनंत लूप बोर्ड के चारों ओर उत्तरोत्तर व्यापक सीमाओं की कोशिश कर रहा है।)
m
मुख्य Minesweeper हल फ़ंक्शन है। यह इनपुट स्ट्रिंग को पार्स करता है, एक बोर्ड को एक सही बॉर्डर के साथ उत्पन्न करता है (बोर्ड p
के अधिकांश को बदलने के लिए पुनरावर्ती मामले का उपयोग करके , फिर शीर्ष सीमा को उत्पन्न करने के लिए सीधे आधार मामले को कॉल करता है, जिसमें नीचे की सीमा के समान संरचना है)। तब यह कॉल करता हैz(r,[R|M])
Minesweeper रूल्स इंजन को चलाने के लिए, जो (इस कॉल पैटर्न के साथ) एक जेनरेटर बन जाता है जो केवल वैध बोर्ड बनाता है। इस बिंदु पर, बोर्ड को अभी भी बाधाओं के एक सेट के रूप में व्यक्त किया गया है, जो संभवतः हमारे लिए अजीब है; हम शायद बाधाओं का एक सेट हो सकता है जो एक से अधिक बोर्ड का प्रतिनिधित्व कर सकता है। इसके अतिरिक्त, हमने अभी तक कहीं भी निर्दिष्ट नहीं किया है कि प्रत्येक वर्ग में अधिकतम एक खदान है। जैसे, हमें प्रत्येक वर्ग के स्पष्ट रूप से "वेवफॉर्म को ढहाने" की आवश्यकता है, इसे विशेष रूप से या तो एक (एकल) मेरा या एक नॉनलाइन होना चाहिए, और ऐसा करने का सबसे आसान तरीका यह है कि इसे पार्सर बैकवर्ड ( var(V)
ऑन पर) के माध्यम से चलाया जाए q(63,V)
केस को ?
पीछे की तरफ से चल रहे केस को रोकने के लिए डिज़ाइन किया गया है , और इस तरह बोर्ड को डिप्रेस करने पर यह पूरी तरह से ज्ञात होने पर मजबूर करता है)। अंत में, हम पार्स बोर्ड से लौटते हैंm
; m
इस प्रकार एक जनरेटर बन जाता है जो आंशिक रूप से अज्ञात बोर्ड लेता है और इसके अनुरूप सभी ज्ञात बोर्डों को उत्पन्न करता है।
यह वास्तव में माइनस्वीपर को हल करने के लिए पर्याप्त है, लेकिन प्रश्न स्पष्ट रूप से यह जांचने के लिए कहता है कि क्या सभी समाधान खोजने के बजाय एक ही समाधान है। जैसे, मैंने एक अतिरिक्त विधेय लिखा, s
जो जनरेटर m
को एक सेट में परिवर्तित करता है , और फिर दावा करता है कि सेट में ठीक एक तत्व है। इसका मतलब है कि s
truthy (वापस आ जाएगी yes
) अगर वहाँ वास्तव में ठीक एक समाधान है, या falsey (है no
) अगर वहाँ एक से अधिक या एक से कम है।
d
समाधान का हिस्सा नहीं है, और बायटेकाउंट में शामिल नहीं है; यह स्ट्रिंग्स की एक सूची को मुद्रित करने के लिए एक फ़ंक्शन है, हालांकि यह एक मैट्रिक्स था, जो m
एएससीआईआई कोड की एक सूची के रूप में स्ट्रिंग द्वारा उत्पन्न बोर्डों का निरीक्षण करने के लिए संभव बनाता है (जीएनयू प्रोलॉग स्ट्रिंग्स को प्रिंट करता है, क्योंकि यह दो समान रूप से व्यवहार करता है; यह प्रारूप पढ़ने के लिए काफी कठिन है)। यह परीक्षण के दौरान उपयोगी है, या यदि आप m
एक व्यावहारिक माइनस्वीपर सॉल्वर के रूप में उपयोग करना चाहते हैं (क्योंकि यह एक बाधा सॉल्वर का उपयोग करता है, तो यह अत्यधिक कुशल है)।
2?
कोई समाधान नहीं है, जिसका अर्थ है कि यह माइनस्वीपर के एक वास्तविक खेल से नहीं आ सकता है। इसलिए इसे "माइनस्वीपर बोर्ड" नहीं माना जाता है ... हाँ?)