2017-10-11 3 views
1

J'ai de nouveau besoin de votre expertise, je me retrouve aux prises avec Haskell en raison de mon manque d'expérience. J'ai une liste (inac) et j'ai besoin de vérifier les numéros dans cette liste afin qu'il n'y en ait aucun dans un rayon de 5 chiffres, comme par exemple, j'ai le numéro 300 dans ma liste je vérifie s'il y a le numéro 295 et 305, s'il n'y a pas alors 300 va dans une autre liste (rInac)Vérification du rayon du numéro de liste

dig :: Int -> [Int] 
dig 0 = [] 
dig n = dig (n `div` 10) ++ [n `mod` 10] 

inac :: [Int] 
inac = [x | x <- [1..999], x `mod` sum (dig x) == 0] 

rInac :: [Int] 
rInac = [x | x <- inac, rAux x] 

rAux :: Int -> Bool 
rAux n = n `elem` inac 

en ce moment, je ne vérifier que les chiffres (n) appartiennent à la liste, mon problème est, je ne suis pas sûr de la façon de faire la chose 5 rayon ... Merci d'avance!

+0

Je ne pense pas qu'une liste soit une bonne infrastructure de données pour cela, puisque la recherche est inefficace ici. –

+0

@WillemVanOnsem inac et rInac doivent être une liste, maintenant la vérification je ne sais pas comment le faire ... – Wireless

Répondre

0

Vous pouvez utiliser la fonction any pour déterminer si une liste contient une valeur qui satisfait un certain prédicat. Par exemple:

any odd [1,2,3,4] -- True 
any odd [2,4]  -- False 

Tout ce que vous avez à faire est une fonction sous-jacente qui déterminerait si le nombre se trouve dans un rayon de 5:

rAux :: Int -> Bool 
rAux n = any isWithinFive inac 
    where 
     isWithinFive x = x >= n-5 && x <= n+5 

Cependant, cela vous rapportera un viderInac liste. Parce que chaque nombre est dans le rayon 5 de lui-même, ce prédicat contiendra pour chaque nombre dans la liste inac. Je pense que ce que vous vraiment voulez est de vérifier l'existence d'un nombre à 5 du nombre donné, mais à l'exclusion du nombre donné lui-même:

rAux :: Int -> Bool 
rAux n = any isWithinFive inac 
    where 
     isWithinFive x = x /= n && x >= n-5 && x <= n+5 
+0

Hey, donc j'ai couru ce que vous avez écrit là-bas, dans les deux sens, et n'a pas eu ce que je m'attendais , Je me suis peut-être mal expliqué, j'ai la liste d'inactivité qui a une série de nombres, et de ces nombres sur inac, je veux vérifier lesquels sont isolés, signifiant, je veux vérifier ceux d'inac qui ne font pas Avoir un autre numéro d'inactivité 5 chiffres avant et après, et les amener à la liste rInac. (La liste d'inactivité a des nombres spécifiques et il est supposé y avoir 30 nombres rInac) – Wireless

+0

Si vous voulez que la liste ne contienne que des nombres isolés, alors vous devriez inclure seulement ceux qui n'ont pas de voisins proches. Vous pouvez utiliser la fonction 'not 'pour annuler une condition. –

0

En supposant que votre liste est triée, d'un type bornées (par exemple comme Int), et vous êtes à l'aise que ses valeurs n'aborderont jamais les limites (environ +/- 2^63 sur une machine 64 bits) le code suivant devrait être assez intuitif et efficace (ie, O (n) dans un espace constant si l'optimiseur GHC fait son travail):

gapped :: Int -> [Int] -> [Int] 
gapped g a = map fst $ filter test $ zip a $ zip (minBound:a) (tail a ++ [maxBound]) 
    where 
    test (x, (l, u)) = l+g < x && x < u-g 

Par exemple, en utilisant votre autre code, gapped 5 inac: rendements

[90.126.162.171.180.300.342.351.432.531.540.576.612.660.666.684.690.756.792.810.840.846.864.888.954.960.966.972.990.999]

Est-ce que la réponse que vous recherchiez?