2009-04-17 10 views
3

Wie kann ich {2n + 3m + 1 | n, m∈N} im Listenverständnis ausdrücken? N ist die Menge natürlicher Zahlen, einschließlich 0.Wie man {2n + 3m + 1 | n, m∈N} im Listenverständnis ausdrückt? (N ist die Menge natürlicher Zahlen einschließlich 0)

+1

Dies scheint eine Hausaufgaben Frage zu sein, ist aber nicht als solche gekennzeichnet. Bitte lesen Sie die entsprechenden FAQ: http://stackoverflow.com/questions/230510/homework-on-stackoverflow – nominolo

+1

Dies ist unterspezifiziert.Möchten Sie Semantik (d. H. Keine Duplikate) in Ihrer Antwort festlegen? Besteht Ordnung? –

Antwort

7

Ist nicht {2n + 3m + 1 | n, m ∈ ℕ} = ℕ - {0,2}?

+1

nein, 2 ist nicht im Satzverständnis. – nominolo

+0

und 2. Sie können nicht 1 von 2 bekommen * n + 3 * m – FryGuy

+3

ja, du hast Recht. aber abgesehen von diesen beiden kann jedes x> 2 ∈ N als 2n + 3m + 1 – vartec

10

Kurz:

1:[3..] 
+0

ausgedrückt werden. Es wurde gebeten, Listenverständnis zu verwenden. – Romildo

4

[2*n + 3*m +1 | m <- [0..], n <- [0..]] wird nicht funktionieren, weil es mit m = 0 beginnt und geht durch alle n, und dann hat m = 1 und geht durch alle n, etc. Aber nur die m = 0 Teil ist unendlich , so werden Sie nie zu m = 1 oder 2 oder 3 usw. gelangen. So ist [2*n + 3*m +1 | m <- [0..], n <- [0..]] genau dasselbe wie [2*n + 3*0 +1 | n <- [0..]].

Um alle von ihnen zu generieren, müssen Sie entweder erkennen, wie Benutzer vartec und Hynek -Pichi- Vychodil, dass die Menge der Zahlen, die Sie wollen, nur die natürlichen Zahlen - {0,2} ist. Oder Sie müssen irgendwie alle Paare (m, n) so aufzählen, dass m, n nichtnegativ sind. Ein Weg, dies zu tun ist, entlang jeder der "Diagonalen" zu gehen, wo m + n das gleiche ist. Also beginnen wir mit den Zahlen, wo m + n = 0, und dann die, wo m + n = 1, etc. Jede dieser Diagonalen hat eine endliche Anzahl von Paaren, so dass Sie immer weiter zum nächsten, und alle Paare (m, n) werden schließlich gezählt werden.

Wenn wir i = m + n und j = m lassen, dann wird [(m, n) | m <- [0..], n <- [0..]][(j, i - j) | i <- [0..], j <- [0..i]]

Also für Sie, können Sie einfach

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

(Natürlich wird diese Methode auch Duplikate für Sie produzieren, weil es mehrere sind (m, n) Paare, die die gleiche Zahl in Ihrem Ausdruck erzeugen.)

+0

weiß ich nicht, was ich getrunken habe, als ich diese Antwort gepostet habe: P danke für die Erklärung obwohl :) und ich werde meinen nutzlosen Beitrag löschen – Sujoy

+0

Sie könnten immer 'nub' die Liste, um Dubletten zu beseitigen, obwohl es dann nicht streng eine Liste ist Verständnis nur, und es wird übermäßige Mengen an Speicher verwenden. – ephemient

6

Die folgende Haskell-Funktion liefert Ihnen alle Paare aus zwei Listen, auch wenn eine oder beide unendlich sind. Jedes Paar genau einmal:

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 

könnten Sie dann Ihre Liste schreiben, wie

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

Um ein Gefühl dafür zu bekommen, wie es funktioniert, eine unendliche Viertel Ebene zeichnen, und Blick auf die Ergebnisse von

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

Sie können versuchen, alle Ganzzahlpaare aufzulisten. Dieser Code in der Aufzählung bei University of California Berkeley beschrieben basiert (nicht enthalten 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 

Aber Sie eine andere Aufzählung verwenden können.

Dann können Sie tun:

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

meine 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]