www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

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

Logo - DracheHaskell-Forum

  1 2 nächste Seite

bs-sb

Gepostet:
17.06.2006 18:09

Haskell: list comprehension  
Hallo!
Bin neu hier und hoffe, dass mir irgendwer weiterhelfen kann mit den folgenden Aufgaben. Sie sollen mit Hilfe von list comprehension und ggf. Listenfunktionen gelöst werden. Ich bedanke mich schonmal für jede Lösung bzw. jeden Tipp.


a. Schreiben Sie eine Funktion, die aus einem Übergegebenen String alle Vokale entfernt
und diesen (neuen) String zurückgibt.


b. Ein Tripel (x, y, z) nennt sich pythagoräisch, wenn x2+y2 = z2 gilt. Definieren Sie
eine Funktion, die eine natürliche Zahl n bekommt und die Liste aller pythagoräischen
Tripel (x, y, z) mit x, y, z  n zurückgibt.

pyth 11
>> [(3,4,5),(4,3,5),(6,8,10),(8,6,10)]


c. Eine positive ganze Zahl nennt sich perfekt, wenn sie gleich der Summe ihrer Teiler
(ausgenommen der Zahl selbst und jeder Teiler muss in der Summe genau einmal
vorkommen) ist. Definieren Sie eine Funktion, die alle solchen perfekten Zahlen bis
zu einer bestimmten Zahl n in einer Liste ausgibt.

perfekt 500
>> [6, 28, 496]


d. Definieren Sie eine Funktion, die das Skalarprodukt zweier Vektoren berechnet.
Die Vektoren sollen als Listen der Länge n gegeben sein und der Funktion als
Argumente übergeben werden.


e. Definieren Sie eine Funktion, die alle Permutationen der Zahlen 1, ..., n als Liste
zurückgibt.

permutation 3
>> [[1,2,3],[2,1,3],[2,3,1],[1,3,2],[3,1,2],[3,2,1]]
Zum Seitenanfang    
 
Jacke

Gepostet:
18.06.2006 09:58

   
so das wären soweit erstmal die lösungen...c mache ich nachher ich will aber erstmal bizz helfen
a)

vokale x = (filter (/='a')(filter (/='a') (filter (/='e') (filter (/='u') (filter (/='o') x)))))

b)

pythagTriples n=[(x,y,z)| z<- [2..n] , y <- [2.. z-1] , x <- [2..y-1], (x*x+y*y==z*z)]++[(y,x,z)| z<- [2..n] , y <- [2.. z-1] , x <- [2..y-1], (x*x+y*y==z*z)]


d)

skalar [] []=[]
skalar (vektor1) (vektor2)=[(v1*v2*(cos (v1*v2) ) ) | v1<-vektor1, v2<-vektor2]



e)

perms :: [a ] ->[[a ]]
perms [ ] = [[ ]]
perms x = [a : y0 | (a,y) <- remove x , y0 <- perms y ]


remove :: [a] -> [(a,[a])]
remove [ ] = [ ]
remove (a:x) = (a,x) : [(b,a:y) | (b,y) <- remove x ]

permutation n =perms [1..n]


gruß jacke :-)
Zum Seitenanfang    
 
Jacke

Gepostet:
18.06.2006 12:50

   
so und hier die letzte aufgabe

teiler :: Int -> [Int]
teiler n = [x | x<-[1..(n`div`2)], n`mod`x==0]

isPerfect :: Int -> Bool
isPerfect n = if ((foldl (+) 0 (teiler n)) == n) then True else False

perfekt :: Int -> [Int]
perfekt n = [x | x<-[1..n], isPerfect x]


Smilie


kannst mich gerne zu den lösungen ausfragen

gruß jacke
Zum Seitenanfang    
 
bs-sb

Gepostet:
22.06.2006 21:11

   
super, tausend dank.

hab leider schon wieder das nächste problem:

1.)

Entwerfen Sie eine Datenstruktur Stack zur Speicherung von 2-Tupeln von Integern und die dazu gehörigen Funktionen

newstack – bekommt eine Zahl n und erzeugt einen (0,0)-initialisierten Stack der Höhe n,

push – bekommt als Argumente ein Element und einen Stack und legt das Element oben auf den Stack,

pop – bekommt als Argument einen Stack und gibt zurück das oberste Element des Stacks und den Stack, der um dieses Element verringert wurde.

Gegeben sei weiterhin die Funktionsdefinition
mystack n = (push (1,2) . push (2,2) . push (2,3)) (newstack n).
Geben Sie den Typ der Funktion an und begründen Sie diesen.



2.)

Entwerfen Sie eine Datenstruktur Bruch zur Speicherung von Brüchen mit separatem Zähler und Nenner. Lassen Sie Haskell Ihren Datentyp in die Klassen Eq und Show automatisch einfügen.

1. Entwerfen Sie die Funktionen reziproke, summe und division zur Reziprokbildung, Addition und Division von Brüchen. Denken Sie daran, Brüche immer zu kürzen!

2. Definieren Sie eine Funktion ausgabe zur formatierten Darstellung eines Bruches auf dem Bildschirm. Beispiel:
ausgabe Bruch 110 5586
>> 55
>>----
>>2793

3. Ordnen Sie Ihren Datentyp Bruch in die Typklassen Ord und Num ein und definieren Sie die Operationen <, > und *. Benutzen Sie für die * Operation die Funktion division aus Punkt 1.

4. Testen Sie die beiden Brüche Bruch 1 5 und Bruch 2 10 auf ==, < und >. Erklären das auftretende Phänomen und machen Sie einen Lösungsvorschlag.
Zum Seitenanfang    
 
Siracusa

Gepostet:
23.06.2006 01:29

   
Hi,

zu 1.) Am einfachsten ist es, wenn du den Stack als eine Liste von Integer-Paaren implementierst. Die Stackspitze ist dabei das erste Element in der Liste (ganz links).

newstack – solltest du leicht über list comprehensions hinbekommen
push – hängt einfach das neue Element links an die Liste
pop – löscht das linke Element der Liste und gibt es als Funktionswert zurück

zu 2.) Deine Datenstruktur könnte z.B. so aussehen: data Bruch = Bruch Integer Integer. Bruch 17 27 wäre dann der Bruch 17/27.
reziproke - hier brauchst du nur Zähler und Nenner vertauscht zurückgeben
summe - erst beide Brüche auf den gleichen Nenner bringen (erweitern) und dann die neuen Zähler addieren

Soweit erstmal ein paar Hinweise.

Viele Grüße,

Siracusa
Zum Seitenanfang    
 
Jacke

Gepostet:
23.06.2006 09:03

   
für die Showfunktion von Bruch ist hier noch ein gutes Beispiel

http://www.jammni.de/php/forum.php?forum=6&posting=1991

gruß jacke
Zum Seitenanfang    
 
bs-sb

Gepostet:
25.06.2006 00:10

   
hmmm, kann da mal einer von euch lieben drüber schauen? irgendwie haut das alles nicht so hin wie erhofft.
schonmal danke und liebe grüße, bs-sb


data Pair a b = MkPair a b
MkPair :: a -> b -> Pair a b
MkPair a b = (a, b)

data Stack (a, b) = MkPair Integer Integer

newstack :: Integer -> Stack
newstack n
| n >= 2 = [(0, 0)] ++ newstack (n - 1)
| n == 1 = [(0, 0)]

push :: Pair -> Stack -> Stack
push (a, b) [x] = [x]++[(a, b)]

pop :: Stack -> Pair -> Stack
pop (x : xs)
| xs == [] = x
| xs != [] = [x]++pop xs

---------------------------------

data Bruch = Bruch Integer Integer
deriving (Eq, Show, Ord, Num)

reziproke :: Bruch -> Bruch
reziproke (x, y) = x > 0 = (y, x)

summe :: Bruch -> Bruch -> Bruch
summe (a, b) (c, d)
| a == 0 = (c, d)
| c == 0 = (a, b)
| otherwise gleichmachen (a, b) (c, d) && (a+c, d)

division :: Bruch -> Bruch -> Bruch
division (a, b) (c, d) = gleichmachen ((a / c), (b / d))

multiplikation :: Bruch -> Bruch -> Bruch
multiplikation (a, b) (c, d) = division (a, b) (d, c)

kleiner :: Bruch -> Bruch -> Bool
kleiner (a, b) (c, d) = gleichmachen (a, b) (c, d) && a <= c

groesser :: Bruch -> Bruch -> Bool
groesser (a, b) (c, d) = gleichmachen (a, b) (c, d) && a >= c

gleichmachen :: Bruch -> Bruch -> Bruch
gleichmachen (a, b) (c, d) = (a * d, b * d) (c * b, d*b)
Zum Seitenanfang    
 
Jacke

Gepostet:
25.06.2006 15:20

   
ich kümmer mich heute abend drum...(versprochen) geh aber jetzt lieber schwimmenSmilie
Zum Seitenanfang    
 
Siracusa

Gepostet:
25.06.2006 19:28

   
Derweil mal ein paar Anmerkungen von mir.

Was mir aufgefallen ist: Du verwendest Datenkonstruktoren für den Stack, für die Paare und für die Brüche, benutzt sie aber in deinen Funktionen nicht.

data Bruch = Bruch Integer Integer
deriving (Eq, Show, Ord, Num)

reziproke :: Bruch -> Bruch
reziproke (x, y) = x > 0 = (y, x)

Oben definierst du wie ein Bruch aussehen soll, nämlich so: Bruch 2 3.
Dann willst du, daß an reziproke ein Bruch übergeben wird und auch ein Bruch zurückgegeben wird. reziproke erwartet also einen Ausdruck (Bruch a b). In der untersten Zeile soll aber auf ein Paar von Zahlen gematcht werden, was zu einem Konflikt führt. reziproke müßte also etwa so aussehen (undefined ist im Haskell-Prelude vordefiniert):
reziproke :: Bruch -> Bruch
reziproke (Bruch z n)
| z /= 0 = Bruch n z
| otherwise = undefined

Ähnliche Fehler finden sich auch bei den Stackfunktionen, wo du einen Stack explizit als Stack-Datenstruktur definierst, aber schlicht wie eine Liste behandelst.


gleichmachen :: Bruch -> Bruch -> Bruch
gleichmachen (a, b) (c, d) = (a * d, b * d) (c * b, d*b)

Hier willst du zwei Werte als Funktionsergebnis zurückgeben. Das funktioniert so nicht, das Ergebnis muß immer genau ein Wert sein. Du kannst aber beide Brüche zu einem Paar zusammenfassen und das dann als Ergebnis zurückgeben.

kleiner :: Bruch -> Bruch -> Bool
kleiner (a, b) (c, d) = gleichmachen (a, b) (c, d) && a <= c

Das geht so nicht! Du mußt dir erstmal neue lokale Variablen einführen, die mit den zwei "gleichgemachten" Brüchen belegt werden. Dann kannst du die neuen Variablen vergleichen. Also so (wenn gleichmachen ein Paar von Brüchen zurückgibt):
kleiner :: Bruch -> Bruch -> Bool
kleiner (Bruch a b) (Bruch c d) = a' < c'
where
(Bruch a' b', Bruch c' d') = gleichmachen (Bruch a b) (Bruch c d)

Das where beschreibt die neu eingeführten, lokalen Variabeln genauer.

Dann noch ein paar Kleinigkeiten:
* Du definierst MkPair gleich zweimal, erst bei data Pair und dann nochmal bei data Stack. Außerdem brauchst du eine Funktion MkPair nicht, da du den Datenkonstruktor MkPair bereits definiert hast.
* In Haskell ist das ungleich nicht != sondern /=
* Verwende doch bitte in Zukunft Code-Tags wenn du Quellcode postest, also sowas hier: (code) ... (/code) nur mit eckigen statt runden Klammern, damit dein Quellcode auch schön formatiert ist.

Viele Grüße,

Siracusa
Zum Seitenanfang    
 
Jacke

Gepostet:
25.06.2006 20:23

   
ich seh schon alles schon gelöst
danke siricusa Smilie

gruß jacke
Zum Seitenanfang    
 

  1 2 nächste Seite