zurück zur Homepage
Softwareprojekte
Links zu anderen Pages
Nützliche Dinge, die man immer mal brauchen kann im Netz
Bilder, Stories und sonstiger Quatsch
Fotogallerie
Gästebuch
exit
SiteMap
zurück

Gofer

...als Beispiel für eine fubktionale Programmiersprache:
Win95-DOS-Shell C:\DosProg\SPRACHEN\Gofer>set editor=c:\windows\command\edit.com

Win95-DOS-Shell C:\DosProg\SPRACHEN\Gofer>gofer app.gof
Gofer Version 2.28b  Copyright (c) Mark P Jones 1991-1993

Reading script file "standard.prelude":
Reading script file "app.gof":

Gofer session for:
standard.prelude
app.gof
Type :? for help
? :e app.gof
 
 
 
 

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

Gofer session for:
standard.prelude
app.gof
? maxi [5,2,9,6,77,4,54,23,46,3,64,78,32,12,544,63]
544
(69 reductions, 135 cells)
? binkoeff_a 10 3
120
(788 reductions, 1627 cells)
? testabwechselndab "abababababababababababababa"
True
(332 reductions, 875 cells)
? normal (ratmul (66,42) (53,28))
(583,196)
(51 reductions, 101 cells)
? :q
[Leaving Gofer]

Win95-DOS-Shell C:\DosProg\SPRACHEN\Gofer>













(c) Jan Beinersdorf 1998 bis in alle Ewigkeit... http://www.nasentier.de
Ich übernehme keinerlei Haftung für Links auf dieser oder irgendeiner anderen Seite meiner Homepage, die in eine andere Domain verzweigen. Ich bin nicht dafür verantwortlich, was andere Leute auf ihren Seiten an evtl. anstößigem, unmoralischen oder gar illegalem Inhalt anbieten. Zum Zeitpunkt der Linksetzung waren diese Seiten OK.