-- Script File "Applications.gof"
by Jan Beinersdorf 1998
------------------------------------------------------------------------------
-- append wie in der AWÜbung Blatt 3
append :: [Char]->[Char]->[Char]
append [] bs = bs
append (a:as) bs = a : append as bs
------------------------------------------------------------------------------
-- rev wie in der AWÜbung Blatt 3
rev_uebung :: [Char]->[Char]
rev_uebung [] = []
rev_uebung (a:as) = append (rev_uebung as) [a]
------------------------------------------------------------------------------
-- rev wie ich es gemacht hätte
rev_jan :: [Char]->[Char]->[Char]
rev_jan [] bs = bs
rev_jan (a:as) bs = rev_jan as (a:bs)
rev :: [Char]->[Char]
rev x = rev_jan x []
------------------------------------------------------------------------------
-- ggT wie in AWÜbung Blatt 2
-- nämlich euklidisch
ggT :: Int->Int->Int
ggT a b = if a<b then ggT a (b-a)
else if a>b then ggT (a-b) b
else a
------------------------------------------------------------------------------
-- maximum (Versuch für Übung Blatt 3)
-- Aufgabe 13a
-- Abgabe zum 20.11.1998
-- Einschränkung: Nur für Zahlen > sehr_klein
-- Lösung: sehr_klein noch kleiner machen!
sehr_klein = -9999
-- Startwert
maxi_sub :: [Int]->Int->Int
maxi_sub [] m = m
-- wenn die Liste leer ist, habe ich das Element gefunden
maxi_sub (xs:x) m = if m<xs then maxi_sub x xs
-- ist das erste Element größer als der bisher angenommene Wert,
teste ob der
-- Rest größer ist als dieses
else maxi_sub x m
-- ansonsten teste, ob der bisherige Wert vielleicht kleiner ist als der
Rest
maxi :: [Int]->Int
maxi [] = error("Leere Listen haben kein Maximum...")
-- Benutzerfehler ausschließen
maxi x = maxi_sub x sehr_klein
-- ansosnten Unterprogramm mit Startwerten rufen
------------------------------------------------------------------------------
-- maxi2 (Versuch für Übung Blatt 3)
-- Aufgabe 13b
-- (s.o.) (Gleiche Einschrõnkung)
maxi2_sub :: [Int]->[Int]->[Int]
maxi2_sub [] mm = mm
-- Elemente gefunden, wenn Liste leer
maxi2_sub (xs:x) mm = if xs>(head mm) then maxi2_sub
x (xs:(init mm))
-- Wenn erstes Element größer als das bisherige Maximum, vergleiche
den Rest
-- mit dem neuen Maximum und verscheibe das bisherige Maximum an die Position
-- des zweitgrößten Elementes
else if and [xs < (head mm),xs >
(last mm)] then maxi2_sub x ((head mm):[xs]) -- ansonsten wenn das
erste E. größer ist als des
-- bisherige, vergleiche den Rest mit dem alten Maximum und dem neuen
-- zweitgrößten
else maxi2_sub x mm
-- ansonsten teste den Rest
maxi2 :: [Int]->[Int]
maxi2 [] = error("Leere Listen haben kein Maximum...")
-- Benutzerfehler ausschließen
maxi2 x = maxi2_sub x [sehr_klein,sehr_klein]
-- Unterprogramm mit den Startwerten aufrufen
------------------------------------------------------------------------------
-- testabab (Versuch zu Übungsblatt 3)
-- Aufgabe 14b
-- Abgabe zum 20.11.98
testab_sub :: [Char]->Int->Bool
testab_sub [] n = if n==0 then True else False
-- Wenn n=0 dann ist es eine abab..-liste, sonst nicht
testab_sub (xs:x) n = if xs=='a' then testab_sub
x (n+1)
-- Wenn das erste Element ein a ist, addiere zu n 1 und teste weiter
else testab_sub x (n-1)
-- ansonsten subtrahiere 1 von n und teste weiter
testabab :: [Char]->Bool
testabab [] = error("Ohne Eingabe (leere Liste) keine
Ausgabe!")
-- Benutzerdummheit abfedern
testabab x = testab_sub x 0
-- ansonsten Unterprogramm mit Startwerten aufrufen
------------------------------------------------------------------------------
-- testabwechselndab
-- Aufgabe 14a
-- Abgabe 20.11.98
testabw_sub :: [Char]->Char->Bool
testabw_sub [] c = True
-- Wenn ich bis hierher gekommen bin, dann ist es eine solche Liste
testabw_sub (xs:x) c = if or [and[(xs=='a'),(c=='b')],and[(xs=='b'),(c=='a')]]
then testabw_sub x xs -- War der letzte Buchstabe ein
b und der jetzige ein a
-- (oder umgekehrt), denn besteht die Chance (also weiter testen)
else False
-- ansonsten war's das, und es ist keine solche Liste
testabwechselndab :: [Char]->Bool
testabwechselndab [] = error("Liste ist leer!")
-- Keine leeren Listen bitte!
testabwechselndab (xs:x) = if (x==[]) then False
else testabw_sub x xs
-- Unterprog. aufrufen mit Startwerten (nämlich dem Rest der Liste
als Liste
-- und dem ersten Element als letztem Buchstaben)
------------------------------------------------------------------------------
-- aber nur, wenn x nicht eine Einelementige Liste war.
-- testgleichab
-- Aufgabe 14c
-- Abgabe 20.11.98
-- NEU: Jetzt auch für bb..aa-Listen!
testgl_sub :: [Char]->Int->Char->Bool->Bool
testgl_sub [] n c b = if (n==0) then True else False
-- Ist die Liste leer und die Anzahl der a gleich der der b (n=0), dann
schon,
-- ansonsten nicht
testgl_sub (xs:x) n c b = if and[(xs=='a'),(c=='a')]
then testgl_sub x (n+1) xs b -- Ist das jetztige E. ein a und das vorherige
ein a, dann addiere 1 zu n
else if and[(xs=='b'),(c=='b')] then testgl_sub
x (n-1) xs b
-- ansonsten ist das jetztige E. ein b und das vorherige auch, dann subtrahiere
-- 1 von n
else if and[or[and[(xs=='b'),(c=='a')],and[(xs=='a'),(c=='b')]],not(b)]
then testgl_sub x n xs True -- ansonsten ist das jetztige E. ein
b und das vorherige
-- ein a (oder umgekehrt) (Wechsel) und zuvor hat noch kein Wechsel stattgefunden,
-- dann mach einfach weiter
else False
-- ansonsten gab es schon einen Wechsel und somit ist es keine solche Liste
-- folgende
Zeile bitte ignorieren; ist nur ein Überbleibsel vom debuggen...
-- else
error("Schwere Hirnverletzung bei 0123:456789ab im Modul testgl_sub...
bitte springen Sie schreiend aus dem Fenster!")
-- ansonsten war
-- irgendwo ein Fehler und wir beenden das ganze lieber, um den Schaden
nicht
-- noch größer zu machen-}
testgleichab :: [Char]->Bool
testgleichab [] = error("Ich wuerd' ja gern, aber
die Liste ist leer!") --
Leere Listen gelten nicht
testgleichab (xs:x) = if (x==[]) then False else
testgl_sub x 0 xs False -- Ansonsten
mit den Startwerten die Unterprozedur rufen (false zeigt an, daß
-- noch kein Wechsel stattgefunden hat.
-- aber nur, wenn x nicht nur einelementig war...
------------------------------------------------------------------------------
-- fib Fibunacci-Zahlen
-- nach meiner Lösung AWÜ 3
-- Berechnung benötigt 10 Stunden... mindestens!
-- (Vergleiche mit fib.pas)
fib :: Int->Int
fib 0 = 0
fib 1 = 1
fib n = ( fib (n-2) + fib (n-1) )
------------------------------------------------------------------------------
-- member
-- nach meiner Lösung AWÜ 3
member :: (Int,[Int])->Bool
member (n,[]) = False
member (n,(xs:x)) = if (n==xs) then True else member
(n,x)
------------------------------------------------------------------------------
-- Lisa Listas Programm aus AWÜ 3
mc :: Int->Int
mc n = if (n>100) then (n-10) else mc(mc(n+11))
------------------------------------------------------------------------------
-- Falsch und Wahr
-- Übungsblatt 3
-- Aufgabe 15
-- Abgabe 20.11.98
-- Was soll ich da eigentlich machen??
data Ausdruck = Var String
| Falsch
| Wahr
| Nicht Ausdruck
| Und Ausdruck Ausdruck
| Oder Ausdruck Ausdruck
size :: Ausdruck->Int
size (Var x) = 1
size Falsch =
1
size Wahr
= 1
size (Nicht e) = 1 + size(e)
size (Und e1 e2) = 1 + size(e1) + size(e2)
size (Oder e1 e2) = 1 + size(e1) + size(e2)
folgt x y = Oder (Nicht x) y
val x = False
x = Var "x"
y = Var "y"
z = Var "z"
t1 = (Nicht y `folgt` z) `Oder` ((x `Und` Falsch)
`folgt` z)
-- bis hierher nur abgeschrieben vom Ü-Blatt
interp :: (String -> Bool) -> (Ausdruck -> Bool)
interp s Falsch
= False
-- Falsche Aussagen sind False
interp s Wahr
= True
-- genau wie Wahre eben True sind
interp s (Var b) =
s b
--
interp s (Nicht e) = not (interp
s e)
-- Nicht ist not
interp s (Und e1 e2) = (&&) (interp
s e1) (interp s e2)
-- Und ist and
interp s (Oder e1 e2) = (||) (interp s e1) (interp
s e2)
-- Oder ist or
------------------------------------------------------------------------------
-- Programmieraufgabe 26
-- Abgabe: 11. Dez. 1998
-- Teil a)
type Rational = (Int,Int)
normal :: Rational->Rational
normal (z,n) = if n>0 then ( z / gcd z n,n / gcd
z n )
-- die normalisierte Darstellung ist der vollständig gekürzte
Bruch
else ( -z / gcd z n,-n / gcd z n )
-- allerdings bei negativem Nenner auch noch mit "verdrehtem" Vorzeichen
recip :: Rational->Rational
recip (z,n) = (n,z)
-- eben der Kehrwert
-- Teil b)
ratadd :: Rational->Rational->Rational
ratadd (z1,n1) (z2,n2) = (z1*n2+z2*n1,n1*n2)
-- erweitern und dann addieren
ratsub :: Rational->Rational->Rational
ratsub (z1,n1) (z2,n2) = (z1*n2-z2*n1,n1*n2)
-- erweitern und dann subtrahieren
ratmul :: Rational->Rational->Rational
ratmul (z1,n1) (z2,n2) = (z1*z2,n1*n2)
-- multiplizieren halt
ratdiv :: Rational->Rational->Rational
ratdiv (z1,n1) (z2,n2) = ratmul (z1,n1) (recip (z2,n2))
-- mit dem Kehrwert multiplizieren
-- Teil c)
zaehler :: Rational->Int
zaehler (z,n) = z
nenner :: Rational->Int
nenner (z,n) = n
ratint :: Rational->Int
ratint (z,n) = if nenner(normal (z,n))==1 then zaehler(normal
(z,n)) else error("Keine ganze Zahl")
-- und den möglicherweise auftretenden Rest lassen wir unter den Tisch
fallen
intrat :: Int->Rational
intrat z = (z,1)
-- 1 ist 1/1
-- Teil d)
rateq :: Rational->Rational->Bool
rateq (z1,n1) (z2,n2) = rateq_sub (normal(z1,n1))
(normal(z2,n2))
-- erstmal normalisieren
rateq_sub :: Rational->Rational->Bool
rateq_sub (z1,n1) (z2,n2) = if and [z1==z2,n1==n2]
then True else False --
und dann Zähler und Nenner vergleichen
ratl :: Rational->Rational->Bool
ratl (z1,n1) (z2,n2) = if (z1*n2)<(z2*n1) then
True else False
-- mit den Nennern erweitern und dann die Zähler vergleichen
ratleq :: Rational->Rational->Bool
ratleq (z1,n1) (z2,n2) = or[rateq (z1,n1) (z2,n2),ratl
(z1,n1) (z2,n2)] -- gleich
oder größer
ratg :: Rational->Rational->Bool
ratg (z1,n1) (z2,n2) = if (z1*n2)>(z2*n1) then True
else False
-- s.o.
ratgeq :: Rational->Rational->Bool
ratgeq (z1,n1) (z2,n2) = or[rateq (z1,n1) (z2,n2),ratg
(z1,n1) (z2,n2)] -- s.o.
------------------------------------------------------------------------------
-- Programmieraufgabe 27
-- Abgabe: 11. Dez. 1998
-- Teil a)
binkoeff_a :: Int->Int->Int
binkoeff_a n 0 = 1
binkoeff_a n k = if n==k then 1
else binkoeff_a (n-1) (k-1) + binkoeff_a (n-1) k
-- Teil b)
fac :: Int->Int
fac 0 = 1
fac n = fac (n-1) * n
binkoeff_b :: Int->Int->Int
binkoeff_b n k =
ratint (ratmul (1,fac k)
(normal (ratmul (fac n,1) (1,fac (n-k)))))
{-
fac n 1
1
ratint ( normal ( ----- * ---------
) * ----- )
1 fac (k-n)
fac k -}
-- eof |