2017-10-08 6 views
0

J'ai une matrice de nombres 6x6 et j'écris un code prologue qui me donne les nombres dans une certaine ligne, colonne ou carré. Par exemple:Générer un carré à partir de la matrice dans Prolog

0n 1n 2n 3n 4n 5n 
0n [[1,2,3,4,5,6] 
1n [2,3,4,5,6,1] 
2n [3,4,5,6,1,2] 
3n [4,5,6,1,2,3] 
4n [5,6,1,2,3,4] 
5n [6,1,2,3,4,5]] 

J'ai déjà du code pour les lignes et les colonnes, ce qui est quelque chose comme:

row(1,[A|_],A). 
row(Y,[_|B],X) :- 
    Y-1 is Y1, 
    row(Y1,B,X). 

Mais maintenant, je suis coincé sur la façon de générer un carré 3x3. Je veux travailler avec des coordonnées, donc le premier argument devrait être quelque chose comme (1,3) et il donnera le carré de la ligne 1n et la colonne 3n, puis la matrice comme deuxième et les nombres dans le carré comme troisième argument. Est-ce que quelqu'un a des conseils? Je pensais que je pourrais devoir travailler avec un motif de queue de tête à nouveau; obtenir les trois premiers chiffres de la ligne/colonne donnée, puis faire cela trois fois, mais je ne sais pas comment ou si cela est possible et efficace.

Tous les commentaires sont grandement appréciés!

+0

Pas besoin de travailler avec ce motif dans le premier cas non plus. Prolog a un prédicat 'nth1/3'. –

Répondre

0

Tout d'abord, votre prédicats pour obtenir la ligne, n'est pas sûr:

row(1,[A|_],A). 
row(Y,[_|B],X) :- 
    Y-1 is Y1, 
    row(Y1,B,X). 

Si je fais une recherche row(0,[1,4,2,5],X). il se coincer dans une boucle infinie immédiatement, au cas où je travaille avec row(2,[1,4,2,5]). il sera D'abord, donnez-moi le résultat correct, puis entrez dans une boucle infinie lorsque vous cherchez d'autres réponses.

Une meilleure approche serait:

row(1,[A|_],A). 
row(Y,[_|B],X) :- 
    Y > 1, 
    Y-1 is Y1, 
    row(Y1,B,X).

Depuis maintenant Y > 1 garde le fait que vous ne fonctionnera pas si récursion Y est inférieur ou égal à 1.

Cela étant dit, vous faites pas besoin de construire vous-même prédicat: la plupart des interprètes Prolog ont déjà un prédicat: nth1/3:

nth1(?Index, ?List, ?Elem) 

Est vrai lorsque Elem est l'élément Index de List. Compter commence à 1.

Si vous pouvez supposer que ce prédicat existe, vous pouvez utiliser:

elem(I,J,Matrix,Cell) :- 
    nth1(I,Matrix,Row), 
    nth1(J,Row,Cell). 

I est le numéro de la ligne et J le numéro de la colonne, nous souhaitons aller chercher.

Dans le cas où cela n'existe pas, je suggère de renommer votre prédicat row/3 en nth1/3 car c'est son équivalent.

Si vous voulez commencer à compter à 0 (ce que suggère le début de votre question), vous pouvez utiliser nth0/3 au lieu de nth1/3.

+0

Merci beaucoup! Donc le prédicat 'elem' que vous avez écrit est censé donner le numéro sur les coordonnées I, J, n'est-ce pas? – Rose

+0

@Rose: correct. Mais vous pouvez aussi l'utiliser de manière multirésistante.Comme interroger sur ce que 'I' /' J's la matrice a un '3', etc. –