www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

thomas-07

Gepostet:
14.05.2013 16:42

List Comprehension  
Hallo zusammen,

ich bin neu hier im Forum und hoffe, dass Ihr mir helfen könnt.
Danke ertmal an allen, die dieses Forum ermöglicht haben und beleben...

Nun zu meinem Problem:
Ich habe folgenden drei Aufgaben mit list Comprehension zu lösen:

Die Aufgabe a) habe ich bereits gelöst.

-- a) Die Liste aller Quadratzahlen n2 (n ∈ N), die durch 6, aber nicht durch 5 teilbar sind.
quadratzahlen :: [Int]
quadratzahlen = [n*n | n<-[0..], mod (n*n) 6 == 0, mod (n*n) 5 == 1]


Die Aufgabe b) habe ich versucht, aber ich bekomme immer Compiler Fehler.

-- b) Die Liste aller Paare (x, y), mit x, y ∈ N, wobei
-- – x ist das Produkt zweier natürlichen Zahlen (d.h. x = a · b, mit a, b ∈ N), und
-- – x ist echt größer als 5 aber echt kleiner als 500, und
-- – y ist eine Quadratzahl (d.h. y = c2 für c ∈ N) nicht größer als 1000, und
-- – x ist ein Teiler von y.
listePaare :: [(Int, Int)]
listePaare = [(x,y) | x<-[0..], y<-[0..], x<-[0..]*[0..], x > 5, x < 500, (y*y) < 1001, mod y x == 0]



Die Aufgabe c) verstehe ich nicht ganz, was genau verlangt ist und wie ich es angehen soll:
-- c) Die Liste xs aller Tupel (x, y, z) mit x, y, z ∈ N, so dass die Tupel in einer fairen Reihenfolge
-- erzeugt werden. Fair bedeutet hierbei, dass (a,b,c) ‘elem‘ xs für jedes Tupel von Zahlen
-- (a,b,c) nach endlicher Zeit terminiert.

Könnt Ihr mir bitte helfen?

Danke vorab

Viele Grüße
Thomas
Zum Seitenanfang    
 
Landei

Gepostet:
16.05.2013 08:47

   
Du hast die erste Aufgabe falsch gelöst: Wenn eine Zahl nicht durch 5 teilbar ist, heißt das nicht, dass sie den Rest 1 lassen muss, die Bedingung mod (n*n) 5 == 1 ist also zu restriktiv:


quadratzahlen = [n*n | n<-[0..], n^2 `mod` 6 == 0, n^2 `mod` 5 /= 0]


Die Aufgabenstellung von b) ist fraglich, weil "x ist das Produkt zweier natürlichen Zahlen" keine Einschränkung darstellt, z.B. 5 = 1*5. Ich gehe mal davon aus, dass a und b größer 1 sein sollen. x<-[0..]*[0..] kann nicht funktionieren, es ist kein * für Listen definiert. Man kann natürlich x aus zwei Listen für a und b berechnen, das Problem dabei ist aber, dass man Duplikate bekommt und schwer einzugrenzen ist, wo man aufhören soll, um die Bedingungen zu erfüllen. Es ist besser, eine Liste für x zu bilden, und zu schauen, dass es einen nichttrivialen Teiler gibt:


[x | x <- [6..499], any (\d -> x `mod` d == 0) [2..(x-1)]]


Eine Liste der Quadratzahlen bis 1000:

[y | d <- [1..31], let y=d*d]


Und nun alles zusammen:

f = [(x,y) | d <- [1..31], let y=d*d, x <- [6..499], y `mod` x == 0, any (\d -> x `mod` d == 0) [2..(x-1)]]


Wäre etwas übersichtlicher, wenn man es auf mehrere Funktionen aufteilen würde. Bei der Bedingung x = a*b habe ich wie gesagt nur geraten, und das geht sicher auch eleganter (ohne any).

Zur letzten Aufgabe schau dir mal an, wie Georg Cantor dazumal bewiesen hat, dass es endlich viele Brüche gibt ( http://de.wikipedia.org/wiki/Cantors_erstes_Diagonalargument ). Du kannst das gleiche für 3 statt 2 Dimensionen verwenden.

Zum Seitenanfang