2012-10-09 23 views
-4

問題一般來說:我們有8 * 8的地圖,我們必須用1到6的數字來填充空的方格。但是在每一列和原始數字中只能遇到1次。每一行和列都留空。來自兩側的數字,上下顯示我們的第一個數字,這應該出現(但它可以出現在兩個空方塊之後)。在gnu上的EndView遊戲Prolog

所以,現在我有了這個代碼,它最終在4 * 4地圖的swi-prolog上工作。

:- module(ab, [ab/0]). 
:- [library(clpfd)]. 

gen_row(Ls):-length(Ls, 4), Ls ins 0..3. 

transpose(Ms, Ts) :- 
    %must_be(list(list), Ms), 
    ( Ms = [] -> Ts = [] 
    ; Ms = [F|_], 
     transpose(F, Ms, Ts) 
    ). 

transpose([], _, []). 
transpose([_|Rs], Ms, [Ts|Tss]) :- 
    lists_firsts_rests(Ms, Ts, Ms1), 
    transpose(Rs, Ms1, Tss). 

lists_firsts_rests([], [], []). 
lists_firsts_rests([[F|Os]|Rest], [F|Fs], [Os|Oss]) :- 
    lists_firsts_rests(Rest, Fs, Oss). 

ab :- 
Rows = [R1,R2,R3,R4], 
maplist(gen_row, Rows), 
transpose(Rows, [C1,C2,C3,C4]), 

maplist(all_distinct, [R1,R2,R3,R4]), 
maplist(all_distinct, [C1,C2,C3,C4]), 

start(R2, 3), 
start(R3, 3), 
finish(R3, 2), 

start(C3, 1), 
finish(C2, 2), 

maplist(writeln, [R1,R2,R3,R4]). 

finish(X, V) :- 
reverse(X, Y), 
start(Y, V). 

start([0,Y|_], Y). 
start([Y|_], Y). 

但是,它不支持2個空的地方爲更大的區域,如8 * 8 puzzle.Any提示的問題?

+1

仙兒,你應該期待您的問題將被downvoted和關閉。 StackOverflow的政策致力於'全球'的用處。你必須單獨解決你的詳細問題... – CapelliC

+0

fd_all_different是* GNU Prolog *,在* SWI Prolog中使用all_different * – CapelliC

+0

我得到了這個,我在GNU Prolog上編寫,但它仍然不起作用。我不能得到與兩個零又名空的空間的東西。在這種情況下,我們不能使用「假設的唯一性」 – Oona

回答

0

您必須從other question獲得轉置/ 2並將all_distinct/1替換爲fd_all_distinct/2。

此外,獲得writeln這裏maplist(write, [R1,R2,R3,R4]).

編輯一個簡單的解決辦法是延長有限域的「編碼」代替寫,保留數字爲空白,而不只是0,並將回答已發佈的邏輯延伸至other question

對於類似於我打電話third_end_view,並且將是(在的Prolog)

/* File: third_end_view_puzzle.pl 
    Author: Carlo,,, 
    Created: Oct 10 2012 
    Purpose: help to solve extended Second End View puzzle 
      https://stackoverflow.com/q/12797708/874024 
*/ 

:- include(transpose) . 

third_end_view_puzzle :- 

    length(Rows, 8), 
    maplist(gen_row(8), Rows), 
    transpose(Rows, Cols), 

    maplist(fd_all_different, Rows), 
    maplist(fd_all_different, Cols), 

    Rows = [R1,R2,R3,R4,R5,R6,R7,R8], 
    Cols = [C1,C2,C3,C4,C5,C6,C7,C8], 

    start(R1, 4), 
    start(R2, 2), 
    start(R3, 3), 
    start(R4, 5), 
    start(R5, 3), 
    finish(R1, 6), 
    finish(R2, 4), 
    finish(R3, 2), 
    finish(R5, 1), 
    finish(R7, 2), 


    start(C2, 3), 
    start(C3, 4), 
    start(C4, 3), 
    start(C5, 5), 
% start(C6, 4), 
    start(C7, 1), 
% finish(C1, 3), 
% finish(C2, 2), 
    finish(C3, 5), 
    finish(C4, 5), 
    finish(C5, 6), 
    finish(C6, 1), 
    finish(C7, 4), 

    maplist(fd_labeling, Rows), 
    nl, 
    maplist(out_row, Rows). 

gen_row(N, Ls) :- 
    length(Ls, N), 
    fd_domain(Ls, 1, N). 

out_row([]) :- nl. 
out_row([H|T]) :- 
    (H >= 7 -> write('-') ; write(H)), 
    write(' '), 
    out_row(T). 

% constraint: Num is max third in that direction 
start(Vars, Num) :- 
    Vars = [A,B,C|_], 
    A #= Num #\/ (A #>= 7 #/\ B #= Num) #\/ (A #>= 7 #/\ B #>= 7 #/\ C#= Num). 

finish(Var, Num) :- 
    reverse(Var, Rev), start(Rev, Num). 

我使用了一個簡單的條件,沒有具體化,以「從第三方向視圖」陳述。

如前所述,您會發現某些約束條件(已註釋掉)會使難題無法解決。

測試:

| ?- third_end_view_puzzle. 

4 3 - - 5 2 1 6 
2 1 - 3 - 5 6 4 
3 5 4 1 - 6 2 - 
5 4 6 2 1 3 - - 
- - 3 6 2 4 5 1 
1 6 2 4 3 - - 5 
6 - 1 5 4 - 3 2 
- 2 5 - 6 1 4 3 

true ? 
+0

但是,我將在8 * 8的endView上看到2個空的地方呢? – Oona

+0

用* exact *問題語句編輯您的問題,然後我會告訴您解決方案。但是,你應該向我們展示你的努力,迄今... – CapelliC

+0

Thaks,我已編輯的問題,現在繼續與它合作。 – Oona