2009-04-17 10 views
3

Comment exprimer {2n + 3m + 1 | n, m∈N} sous forme de liste? N est l'ensemble des nombres naturels, y compris 0.comment exprimer {2n + 3m + 1 | n, m∈N} sous forme de liste de compréhension? (N est l'ensemble des nombres naturels incluant 0)

+1

Cela semble être une question de devoirs, mais ne sont pas étiquetés en tant que tel. Veuillez lire la FAQ correspondante: http://stackoverflow.com/questions/230510/homework-on-stackoverflow – nominolo

+1

Ceci est sous-spécifié.Voulez-vous définir la sémantique (c'est-à-dire, pas de doublons) dans votre réponse? L'ordre est-il important? –

Répondre

7

N'est-ce pas {2n + 3m + 1 | n, m ∈ ℕ} = ℕ - {0,2}?

+1

non, 2 n'est pas dans la compréhension de l'ensemble. – nominolo

+0

et 2. Vous ne pouvez pas obtenir 1 à partir de 2 * n + 3 * m – FryGuy

+3

ouais, vous avez raison. mais en dehors de ces deux, tout x> 2 ∈ N peut être exprimé comme 2n + 3m + 1 – vartec

10

Peu de temps:

1:[3..] 
+0

Il a été demandé d'utiliser la compréhension de la liste. – Romildo

4

[2*n + 3*m +1 | m <- [0..], n <- [0..]] ne fonctionnera pas parce qu'il commence par m = 0 et passe par tous les n, et a ensuite m = 1 et passe par tous les n, etc. Mais la partie est infinie m = 0 , donc vous n'obtiendrez jamais à m = 1 ou 2 ou 3, etc. Donc [2*n + 3*m +1 | m <- [0..], n <- [0..]] est exactement le même que [2*n + 3*0 +1 | n <- [0..]].

Pour les générer tous, vous devez réaliser, comme les utilisateurs vartec et Hynek -Pichi- Vychodil, que l'ensemble de nombres que vous voulez est juste les nombres naturels - {0,2}. Ou vous devez en quelque sorte énumérer toutes les paires (m, n) telles que m, n sont non négatives. Une façon de le faire est de suivre chacune des "diagonales" où m + n est la même chose. Donc, nous commençons par les numéros où m + n = 0, puis ceux où m + n = 1, etc. Chacune de ces diagonales a un nombre fini de paires, de sorte que vous passerez toujours à la suivante, et toutes les paires (m, n) seront finalement être compté.

Si nous laissons i = m + n et j = m, puis [(m, n) | m <- [0..], n <- [0..]] devient [(j, i - j) | i <- [0..], j <- [0..i]]

Donc, pour vous, vous pouvez juste faire

[2*(i-j) + 3*j +1 | i <- [0..], j <- [0..i]] 

(Bien sûr, cette méthode produira également des doublons pour vous, car il existe plusieurs (m, n) paires qui génèrent le même nombre dans votre expression.)

+0

dunno ce que je buvais quand j'ai posté cette réponse: P merci pour l'explication si :) et je vais supprimer mon poste inutile – Sujoy

+0

Vous pourriez toujours «nub» la liste afin d'éliminer les doublons, même si ce n'est pas strictement une liste compréhension seulement, et il va utiliser des quantités démesurées de la mémoire. – ephemient

6

La fonction Haskell suivante vous donnera toutes les paires de deux listes, même si l'une ou les deux sont infinies. Chaque paire apparaît exactement une fois:

allPairs :: [a] -> [b] -> [(a, b)] 
allPairs _ [] = [] 
allPairs [] _ = [] 
allPairs (a:as) (b:bs) = 
    (a, b) : ([(a, b) | b <- bs] `merge` 
      [(a, b) | a <- as] `merge` 
      allPairs as bs) 
    where merge (x:xs) l = x : merge l xs 
     merge []  l = l 

Vous pouvez alors écrire votre liste comme

[2 * n + 3 * m + 1 | (n,m) <- allPairs [0..] [0..] ] 

Pour avoir une idée de comment cela fonctionne, dessiner un quart de plan infini, et regardez les résultats de

take 100 $ allPairs [0..] [0..] 
0

Vous pouvez essayer d'énumérer toutes les paires d'entiers. Ce code est basé dans l'énumération décrit à University of California Berkeley (ne comprend pas 0)

data Pair=Pair Int Int deriving Show 

instance Enum Pair where 
    toEnum n=let l k=truncate (1/2 + sqrt(2.0*fromIntegral k-1)) 
       m k=k-(l k-1)*(l k) `div` 2 
      in 
       Pair (m n) (1+(l n)-(m n)) 
    fromEnum (Pair x y)=x+((x+y-1)*(x+y-2)) `div` 2 

Mais vous pouvez utiliser une autre énumération.

Ensuite, vous pouvez faire:

[2*n+3*m+1|Pair n m<-map toEnum [1..]] 
0

mon 0.2:

trans = concat [ f n | n <- [1..]] 
where 
    mklst x = (\(a,b) -> a++b).unzip.(take x).repeat 
    f n | n `mod` 2 == 0 = r:(mklst n (u,l)) 
     | otherwise  = u:(mklst n (r,d)) 
    u = \(a,b)->(a,b+1) 
    d = \(a,b)->(a,b-1) 
    l = \(a,b)->(a-1,b) 
    r = \(a,b)->(a+1,b) 

mkpairs acc (f:fs) = acc':mkpairs acc' fs 
        where acc' = f acc 
allpairs = (0,0):mkpairs (0,0) trans   
result = [2*n + 3*m + 1 | (n,m) <- allpairs] 
Questions connexes