GNU Prolog, 493 bayt
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),[_]).
Sınama için yararlı olabilecek bir ekstra tahmin (gönderimin bir parçası değil):
d([]).
d([H|T]):-format("~s~n",[H]),d(T).
Prolog kesinlikle bu görevi pratik bakış açısıyla çözmek için doğru dildir. Bu program hemen hemen Mayın Tarlası kurallarını belirtir ve GNU Prolog'un kısıtlayıcı çözücüsünün sorunu oradan çözmesini sağlar.
z
ve i
işlevler: ( z
yapar işlem kat benzeri ancak üç bitişik elemanların yerine 2 setlerinde bir tür; i
aktarır 3 listeleri , n bir liste halinde elemanları , n 3-tuple). Dahili olarak bir hücreyi , x için bir mayın için 1, bir madenin için 0 olmadığı ve y'nin bitişik mayın sayısı olduğu; tahtadaki bu kısıtı ifade eder. yönetim kurulunun her satırı için geçerlidir ; ve böylece geçerli bir tahta olup olmadığını kontrol eder .x/y
c
r
c
z(r,M)
M
Ne yazık ki, bu çalışmayı doğrudan yapmak için gereken giriş biçimi makul değildir, bu yüzden bir çözümleyici de (muhtemelen gerçek kural motorundan daha fazla kod hesaba katar ve hata ayıklamak için harcanan zamanın çoğunu; Mayın Tarlası kuralları motoru oldukça işe yaradı) ilk kez, ancak çözümleyici thinkos doluydu). q
Tek bir hücreyi karakter koduyla formatımız arasında dönüştürür. panelin bir çizgisini dönüştürür (bir maden olmadığı, ancak bilinmeyen sayıda komşu mayın ile, çizginin her kenarına kenarlık olarak bırakılan bir hücreyi terk eder);x/y
l
p
tahtanın tamamını dönüştürür (alt kenarlık dahil, ancak üstteki hariç). Bu işlevlerin tümü ileriye veya geriye doğru çalıştırılabilir, böylece tahtayı hem ayrıştırıp hem de güzel şekilde yazdırabilirsiniz. ( p
Tahtanın genişliğini belirten üçüncü argümanla etrafında sinir bozucu bazı kıpırdama var ; bunun nedeni Prolog'un bir matris türüne sahip olmamasıdır ve tahtayı dikdörtgen biçiminde kısıtlamıyorsam, programın içine girer. tahta etrafında giderek daha geniş sınırları deneyen sonsuz bir döngü.)
m
Ana Mayın Tarlası çözme işlevidir. Giriş dizesini doğru bir kenarlıklı bir tahta oluşturarak ayrıştırır (özyinelemeli p
tahtanın çoğunu dönüştürmek için özyinelemeli halini kullanarak , sonra da alt kenarlık ile aynı yapıya sahip üst sınırı oluşturmak için taban kasasını doğrudan çağırır). Sonra çağırırz(r,[R|M])
Mayın Tarlası kuralları motorunu çalıştırmak için, (bu çağrı modeliyle) yalnızca geçerli panolar üreten bir jeneratör olur. Bu noktada, kurul hala bizim için potansiyel olarak zor olan bir dizi kısıt olarak ifade edilmektedir; belki birden fazla tahtayı temsil edebilecek tek bir kısıtlama kümesine sahip olabiliriz. Ek olarak, her karenin en fazla bir mayın içerdiği herhangi bir yeri henüz belirtmedik. Bu nedenle, açıkça her bir karenin dalga biçimini "daraltmamız" gerekir, bunun özel olarak (tek) bir mayın veya bir mayın olmamasını gerektirir ve bunu yapmanın en kolay yolu, onu ayrıştırıcıdan geriye doğru çalıştırmaktır var(V)
. q(63,V)
kasa, ?
kasanın geriye doğru hareket etmesini önleyecek şekilde tasarlanmıştır ve bu nedenle tahtanın devre dışı bırakılması onu tamamen bilinmeye zorlar). Son olarak, ayrıştırılmış tahtayım
; m
Böylece, kısmen bilinmeyen bir tahta alan ve onunla tutarlı olarak bilinen tüm tahtaları üreten bir jeneratör haline gelir.
Bu Mayın Tarlası'nı çözmek için gerçekten yeterli, ancak soru açıkça tüm çözümleri bulmak yerine tam olarak bir çözüm olup olmadığını kontrol etmenizi istiyor. Dolayısıyla s
, jeneratörü m
bir kümeye dönüştüren fazladan bir yazı yazdım ve kümenin tam olarak bir elemente sahip olduğunu iddia ediyorum . Bu , tam olarak bir çözüm varsa s
truthy ( yes
) no
, birden fazla veya birden fazla varsa falsey ( ) anlamına gelir .
d
çözümün bir parçası değildir ve bayt sayısında bulunmaz; bu, bir matrismiş gibi dizelerin bir listesini yazdırmak için bir işlevdir; bu, tarafından oluşturulan panoları incelemeyi mümkün kılar m
(GNU Prolog, dizeleri ASCII kodlarının bir listesi olarak yazdırır; okumak oldukça zordur). Test sırasında veya m
pratik bir Mayın Tarlası çözücüsü olarak kullanmak istiyorsanız (kısıtlayıcı bir çözücü kullandığından, oldukça verimlidir) faydalıdır .
2?
, hiçbir çözümü yoktur, bu gerçek bir Mayın Tarlası oyunundan gelemeyeceği anlamına gelir. Bu nedenle "Mayın Tarlası panosu" olarak kabul edilmez ... evet?)