2017-05-08 44 views
0

我有一個9x9的難題(列表列表)。他的9條線中的每一條都有9個帶數字的列表。我的目標是在拼圖上找到一個非單一列表。Prolog - 在列表中找到一個非單列表

choose([[H|T]|R], Pos):- choose([[H|T]|R], 1, 1, Pos). 
choose([[H|T]|R], 9, C, Pos):- 
    length(H,X), 
    X =:= 1, 
    C1 is C+1, 
    choose([T|R], 1, C1, Pos). 

choose([[H|T]|R], L, C, Pos):- 
    length(H,X), 
    X =:= 1, 
    L1 is L+1, 
    choose([T|R],L1, C, Pos). 
choose(_,L,C, (L,C)). 

儘管此代碼是不是格外好看,它應該是工作,但由於某種原因,它不... 有誰知道一個更好的辦法來解決這個問題?

編輯:

與該輸入:

choose([[[1],[9],[7],[4],[3],[8],[5],[2],[6]], 
[[2],[6],[5],[7],[1],[9],[3],[8],[4]], 
[[4],[3,8],[3,8],[6],[2],[5],[1,9],[1,7],[7,9]], 
[[8],[2,5],[1,9],[2,5],[6],[1,7],[4],[3],[5,7,9]], 
[[5,7,9],[2,3,5],[1,3,9],[8],[4],[1,7],[2,9],[6],[5,7,9]], 
[[5,7],[4],[6],[2,5],[9],[3],[1,2],[1,7],[8]], 
[[5,9],[5,8],[8,9],[3],[7],[2],[6],[4],[1]], 
[[6],[1],[2],[9],[8],[4],[7],[5],[3]], 
[[3],[7],[4],[1],[5],[6],[8],[9],[2]]], Pos). 

The output should be Pos = (3,2) but it is Pos = (1,2) 

謝謝!

+1

你可以張貼一些示例的查詢做工作,不工作(也與預期結果)的一些例子查詢?另外,你真的很想在你的數學中使用clpfd,特別是對於像sudoku這樣的搗亂遊戲,把'': - (use_module(library(clpfd)))''放在文件的頂部,然後改變''X =: = 1「到」X#= 1「,」L1是L + 1「到」L1#= L + 1「。注意這不是一個虛假或者神祕的建議,clpfd應該總是用於prolog中的數學運算,=:=並且通過比較嚴重限制... c.f. https://github.com/triska/clpfd/blob/master/README.md – Kintalken

+1

我編輯了一個例子 – Joao

+0

'選擇(_,L,C,(L,C))''需要某種條件第一個論點。否則,它會成功執行任何第一個參數,這在邏輯上看起來是錯誤的。 – lurker

回答

2

更簡單的東西,基於nth1/3 ...

choose(Mat, (Row,Col)) :- 
    nth1(Row, Mat, Cells), 
    nth1(Col, Cells, C), 
    nth1(Rc, Cells, C), 
    Rc > Col. 

產量

?- choose([[[1],[9],[7],[4],[3],[8],[5],[2],[6]], 
|  [[2],[6],[5],[7],[1],[9],[3],[8],[4]], 
|  [[4],[3,8],[3,8],[6],[2],[5],[1,9],[1,7],[7,9]], 
|  [[8],[2,5],[1,9],[2,5],[6],[1,7],[4],[3],[5,7,9]], 
|  [[5,7,9],[2,3,5],[1,3,9],[8],[4],[1,7],[2,9],[6],[5,7,9]], 
|  [[5,7],[4],[6],[2,5],[9],[3],[1,2],[1,7],[8]], 
|  [[5,9],[5,8],[8,9],[3],[7],[2],[6],[4],[1]], 
|  [[6],[1],[2],[9],[8],[4],[7],[5],[3]], 
|  [[3],[7],[4],[1],[5],[6],[8],[9],[2]]], Pos). 
Pos = (3, 2) ; 
Pos = (4, 2) ; 
Pos = (5, 1) ; 
false. 

編輯

在Prolog中

,參數(元數)的數量識別謂詞,以及符號(函子)。該片段的有用的改進上面可以

choose(Mat, (Row,Col)) :- 
    choose(Mat, Row, Col,_). 

choose(Mat, Row, C1,C2) :- 
    nth1(Row, Mat, Cols), 
    nth1(C1, Cols, Value), 
    nth1(C2, Cols, Value), 
    C2 > C1. 

即,選擇/ 2實現調用選擇/ 4,這給了我們第二個「不是單」的列。讓我們在一個4x4矩陣

?- choose([ 
| [1,2,3,4], 
| [5,6,5,8], 
| [9,0,1,9], 
| [3,3,5,6]], X). 
X = (2, 1) ; 
X = (3, 1) ; 
X = (4, 1) ; 
false. 

似乎它的工作測試...

+0

很好的解決方案!使用nth似乎更容易,而不是試圖找出遞歸解決方案。爲什麼第n個解決方案比較差?性能?非邏輯? (在我看來,第nth是(如果有的話)可能更好的表現和更容易合理)。 – Kintalken

+0

謝謝!但不應該第二個答案是Pos =(3,3)?我嘗試了一個4x4的矩陣,它沒有正常工作 – Joao

+0

@JoaoNunoPedro:看我的編輯... – CapelliC