2010-10-31 9 views
0
t = True 
f = False 
anzNachbarn :: [[Bool]] -> (Integer,Integer) -> Integer 
anzNachbarn a (x,y) 
     | x < 0 || y < 0=-1 
     | otherwise ... here comes the comparison 

Ceci est une matrice exemple:comparaison Bool Valeur dans Matrix

[[True,False,False], 
[True,False,False], 
[False,True,False]] 

ici je besoin d'un algorithme, où il calcule (pour donné position x et y dans la matrice) ses voisins (seulement "vrai" neighboors) et l'augmenter de 1 pour chaque vrai voisin.

Par exemple: anzNachbarn [[Vrai, Faux, Faux], [Vrai, Faux, Faux], [Faux, Vrai, Faux]] (0,1)

2 retours en arrière.

: Modifier

J'ai encore une question comment puis-je mettre en œuvre maintenant chaque composant de la matrice de résultat, le nombre d'éléments nommés avec des champs vrais voisins indique le composant correspondant de la matrice d'argument s'applique à

[[Vrai, Faux, Faux],

[Vrai, Faux, Faux],

[Faux, Vrai, Faux]]

la fonction func renvoie la matrice de résultats [[1,2,0], [2,3,1], [2,1,1]] avec la signature func :: [[Bool]] -> [[ Entier]] avez-vous une idée à ce sujet?

Répondre

1

C'est laid, mais semble fonctionner ...

anzNachbarn :: [[Bool]] -> (Int,Int) → Integer 
anzNachbarn a (x,y) 
    | x < 0 || y < 0 = -1 
    | otherwise = sum [v x' y' | x' <- [max 0 (x-1)..x+1], 
           y' <- [max 0 (y-1)..y+1], 
           x ≠ x' || y ≠ y' ] 
    where v i j = if j >= length a 
         || i >= length (a !! 0) 
         || not (a !! j !! i) 
        then 0 else 1 

[Modifier]

Afin de convertir tout le tableau, vous pouvez écrire le tout aussi laid

conv a = [line y | y <- [0 .. (length a) - 1]] 
    where line y = [anzNachbarn a (x,y) | x <- [0 .. ((length (a !! 0) - 1)]] 

Notez que la performance de ceci est terrible.

+0

comment puis-je changer l'index (Int, Int) en programme (Integer, Integer) s'exécute vrai – marco

+0

J'ai encore une question comment puis-je maintenant implémenter chaque composant de la matrice de résultat, le nombre de noms avec les champs Vrai voisins indique le composant correspondant de la matrice d'arguments S'applique à [[Vrai, Faux, Faux], [Vrai, Faux, Faux], [Faux, Vrai, Faux]], la fonction transforme la matrice de résultats [[1,2,0], [2,3,1], [2,1,1]] avec la signature func :: [[Bool]] -> [[Integer]] – marco

+0

Le problème avec Integer est, ça !! attend un Int. Donc, si vous écrivez 'a !! (DeIntegral j) !! (fromIntegral je) 'Je pense que cela devrait fonctionner avec Integer. – Landei

3

Dans cette situation, vous souhaitez certainement utiliser un tableau (à partir de Data.Array), car la recherche d'un élément dans une liste par son index est très lente.

Voici une mise en œuvre rapide à l'aide Array:

countNeighbors :: Array (Int, Int) Bool -> (Int, Int) -> Int 
countNeighbors board (x, y) = length 
    [ (x', y') 
    | x' <- [x - 1, x, x + 1] 
    , y' <- [y - 1, y, y + 1] 
    , x' /= x || y' /= y 
    , inRange (bounds board) (x', y') 
    , board ! (x', y') 
    ] 

Ceci est une compréhension de liste avec deux générateurs et trois gardes. Les générateurs nous donnent simplement les indices des neuf positions dans un carré de trois par trois centré à (x, y) (vous aurez besoin d'un changement mineur si vous ne voulez pas que les voisins aux coins soient considérés). Le premier protecteur (x' /= y') ignore (x, y) lui-même. La seconde jette des positions qui ne sont pas dans les limites du tableau. Le dernier garde jette les positions qui sont dans le tableau mais ont une valeur de False.

Nous avons maintenant une liste d'indices pour les voisins avec True valeurs. La longueur de cette liste est le nombre souhaité.

+0

merci pour votre aide mais j'en ai besoin sans tableau – marco

+0

Le gardien 'x '/ = y'' supprime toutes les valeurs le long de la diagonale, au lieu d'ignorer la valeur donnée. Je pense que vous vouliez dire 'x'/= x || y '/ = y'. – Paul

+0

@Paul: Vous avez raison bien sûr. J'avais tapé ceci trop rapidement, mais c'est réglé maintenant. –