www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

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

Logo - DracheHaskell-Forum

Blubberbrause

Gepostet:
30.11.2009 14:21

Leichte Programmieraufgabe - Komme nicht klar  
Hallo,

mir wurde folgende Programmieraufgabe gestellt:"Die Funktion smallestDifference3 erhält drei beliebige Int–Werte als Eingabe und soll den kleinsten Absolutbetrag einer Differenz aus zwei der drei Eingabewerte ausgeben."

Die Signatur geht also von Int -> Int -> Int -> Int (Ausgabe ist ja die Differenz, also Int). Habe mir folgende Fälle überlegt:

1) Alle 3 Int Werte sind gleich z.B. "0 0 0" oder "3 3 3" dann ist der Absolutbetrag der Differenz immer 0. Das als Haskellcode würde das hier ergeben:
smallestdifference3 :: Int -> Int -> Int -> Int
smallestdifference3 x y z
|((x == y) && (x == z)) = 0


Der Code funktioniert bis hierher ganz gut.

2) Jetz geht es schon um mehrere Betrachtung. Erstmal mein Code, dann die Schwäche dahinter und mein Problem:
smallestdifference3 :: Int -> Int -> Int -> Int
smallestdifference3 x y z
|((x == y) && (x == z)) = 0

|((a >= b) && (a >= c) && (b >= c)) = a - b


Betrachten wir mehrere Beispiele:

a) 7 5 1 --> 7 ist größer/gleich 5 und 7 ist größer/gleich 1 und b ist größer/gleich 1, somit würde er 7 - 5 rechnen und damit wäre das Ergebnis für dieses Beispiel korrekt, weil 2 die kleinste absolute Differenz ist.

b) 7 2 1 --> an dieser Stelle rechnet er auch wieder a - b aber dieses Mal ist das Ergebniss falsch.


Mein Lösungsansatz war folgendes: Ich möchte die zweite Bedingung ausweiten. Ungefähr in der Art:
 |((((a >= b) && (a >= c) && (b >= c)) = a - b) >= (((a >= b) && (a >= c) && (b >= c)) = b - c)) = c

<-----erster bekannter teil für fall a-----> größer/gleich <-------sieht genaus aus wie a nur wird beispiel b berechnet----->? Falls True dann gib c aus

Ich weiss zumindest dass, die Syntax falsch ist, weil zum einen Booleanwerte mit richtigen Werten vermischt werden aber wie könnte ich den Ansatz in Haskell Code verpacken? Ich hatte noch die Idee Zusatzfunktionen einzubauen, die vorher genau diese beiden Fälle berechnen aber dann kamen auch nur Fehlermeldungen:
smallestdifference3 :: Int -> Int -> Int -> Int
t1 :: Int -> Int -> Int -> Int
t1 a b c
|((a >= b) && (a >= c) && (b >= c)) = a - b
t2 :: Int -> Int -> Int -> Int
t2 a b c
|((a >= b) && (a >= c) && (b >= c)) = b - c

smallestdifference3 x y z
|((x == y) && (x == z)) = 0

|(t1 >= t2) = z



Kann mir jmd helfen oder ist mein Ansatz völlig Bananne? Ps: Bin totaler Anfänger im Programmieren..also auch Haskel.
Zum Seitenanfang    
 
Siracusa

Gepostet:
30.11.2009 16:19

   
Hallo,

also ich denke du machst es dir unnötig schwer. Bei x, y, z gibt es ja nur 3 mögliche Differenzen, x-y, y-z und z-x (abgesehen von den zusätzlichen "Spiegelungen"). Absolutbeträge kannst du mit der Funktion abs berechnen. Und außerdem gibt es eine Funktion minimum, die aus einer Liste von Zahlen das Minimum zurückgibt. Mit den drei Infos solltest du das ganze jetzt als Einzeiler formulieren können.

Übrigens findest du hier http://ww2.cs.mu.oz.au/172/Haskell/tourofprelude.html eine praktische Übersicht über die Funktionen aus dem Haskell Prelude, also der Standard-Hilfsfunktionen.


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
Blubberbrause

Gepostet:
30.11.2009 20:47

   
Vielen Dank für die Hilfe,

für viele sind solche Aufgaben Kinderspiele nur ich bin absoluter Anfänger aber ich glaube ich hab es hinbekommen:

smallestdifference3 :: Int -> Int -> Int -> Int
absolut a b = abs( abs(a) - abs(b))
absolut b c = abs( abs(b) - abs(c))

smallestdifference3 a b c = min (absolut a b) (absolut b c)


Ein Paar Überprüfungen als Ausgabe
Haskell 98 mode: Restart with command line option -98 to enable extensions

Type :? for help
Main> smallestdifference3 7 5 1
2
Main> smallestdifference3 7 2 1
1
Main> smallestdifference3 0 0 0
0
Main> smallestdifference3 5 4 7
1
Main> smallestdifference3 3 1 2
1
Main> smallestdifference3 (-10) 5 (-3)
2
Main>


Ich denke ich habe nichts übersehen und das ist ja nun wirklich fast ein Einzeiler. Falls ich was übersehen haben sollte gibt mir bitte Bescheid. Ansonsten nochmal vielen Dank.

Gruß

Zum Seitenanfang    
 
Blubberbrause

Gepostet:
30.11.2009 21:37

   
Fehler: Ich muss natürlich noch den Fall a - c beachten, weil ansonsten kommt in so einem Fall hier:
Main> smallestdifference3 (-6) 3 5
2

schwachsinn raus. 1 müsste an dieser Stelle richtig sein aber wenn ich mich nicht irre kann min nur 2 Argumente übernehmen also sowas klappt nicht

smallestdifference3  :: Int -> Int -> Int -> Int
-- Signatur enthaelt 3 Int-Werte als Eingabe und ein Int-Wert als Ausgabe

absolut a b = abs( abs(a) - abs(b))
absolut b c = abs( abs(b) - abs(c))
absolut a c = abs( abs(a) - abs(c))
-- Hilfsfunktionen, die aus der Standardbibliothek Prelude die Funktion abs nutzt, um Nummerische
-- Werte als Absolutbetrag zurueckzugeben. Wir berechnen damit den Absolutbetrag von a - b und b - c

smallestdifference3 a b c = min (absolut a b) (absolut b c) (absolut a c)
-- Wir nutzen die Funktion min aus der Standardbibliothek, um das Minimum zweiter Elemente
-- zu bestimmen. Innerhalb der 2 Argumente rufen wir nocheinmal unsere Hilfsfunktionen absolut auf


Wenn ich auf die Funktion "minimum" zurückgreife würde das gehen? Entschuldigt meine Übersehen.
Zum Seitenanfang    
 
Siracusa

Gepostet:
01.12.2009 04:20

   
Hi nochmal,

abs ( abs x - abs y) müsste aber andere Ergebniss liefern als gefordert, oder? Weil für x = -2 und y = 2 kommt ja 0 raus, die Differenz ist doch aber 4. Meiner Meinung nach müsste es jeweils abs (x-y) heißen.

Und min x y z funktioniert nicht, min erwartet nur zwei Argumente. Du kannst aus den Werten aber eine Liste machen und dann die Funktion minimum verwenden, z.B. minimum [2,4,1,5] = 1.


*EDIT*

Mir fiel grad auf, deine absolute-Funktion macht in allen drei Zeilen exakt das gleiche, nur die Variablennamen sind anders. Du kannst die letzten beidne Zeilen von absolute also weglassen, die werden eh nie ausgeführt.


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
Blubberbrause

Gepostet:
01.12.2009 15:29

   
Hi,

deine Anmerkung "Mir fiel grad auf, deine absolute-Funktion macht in allen drei Zeilen exakt das gleiche, nur die Variablennamen sind anders. Du kannst die letzten beidne Zeilen von absolute also weglassen, die werden eh nie ausgeführt." hatte ich zunächst nicht verstanden aber nun ist es mir mitlerweile klar. Wenn ich eine Funktion deklariere dann reicht es in meinem Fall aus nur "absolut a b" zu schreiben, weil Haskell Automatisch die richtigen Nummerischen Werte einsetzt, sofern ich sie denn aufrufe. D.h.: Rufe ich "absolut b c" auf dann werden auch die Werte von der Eingabe b c übergeben, obwohl ich die Funktion als "absolut a b" deklariert hatte. Die Anzahl muss lediglich übereinstimmen! Das macht das Programmieren natürlich wesentlich einfacher. Vielen Dank für den Tipp!

Des weiteren ist deine erste Anmerkung "abs ( abs x - abs y) müsste aber andere Ergebniss liefern als gefordert, oder?" natürlich korrekt. Genauso ist es auch gefordert. Ich denke der nachfolgende Code ist endgültig und bisher konnte ich kein Gegenbeispiel finden, um nachzuweisen, dass der Code falsch ist.

{- Aufgabe 1b: Die Funktion smallestDifference3 erhaelt drei beliebige Int–Werte 
als Eingabe und soll den kleinsten Absolutbetrag einer Differenz aus zwei der drei
Eingabewerte ausgeben.-}

smallestdifference3 :: Int -> Int -> Int -> Int
-- Signatur enthaelt 3 Int-Werte als Eingabe und ein Int-Wert als Ausgabe

absolut a b = abs( a - b )
-- Hilfsfunktionen, die aus der Standardbibliothek Prelude die Funktion abs nutzt,
-- um Nummerische Werte als Absolutbetrag zurueckzugeben. Wir berechnen damit den
-- Absolutbetrag von allen Werten untereinander. Wichtig: Man muss an dieser Stelle
-- garnicht alle Kombinationen aufschreiben (a-b), (b-c) und (a-c), denn wenn man
-- die Funktion mit den entsprechenden Werten (z.B. absolut b d) aufruft berechnet
-- er automatisch, die passenden Nummerischen Werte.

mincheck a b c = min (absolut a b) (absolut b c)
-- Wir nutzen die Hilfsfunktion mincheck, da wir fuer den kleinsten Betrag aller Differenzen 3
-- Vergleiche auf einmal machen muessen. Die Funktion min kann aber nur 2 Argumente auf einmal
-- verwenden. Um Listen zu entgehen verwenden wir die Hilfsfunktion, um das Minimum zwischen den
-- Absolutbetrag der Differenz a - b und b - c zu erhalten. Dabei ruft die Hilfsfunktion absolut
-- die Funktion min seperat auf.

smallestdifference3 a b c = min (mincheck a b c) (absolut a c)
-- Hauptfunktion. Nutzt Hilfsfunktionen mincheck und absolut, um den minimalen Absolutbetrag einer
-- Differenz aus 3 Int-Werten zu berechnen.


Falls dir dennoch noch was auffällt kannste es gerne schreiben.
Zum Seitenanfang    
 
Siracusa

Gepostet:
01.12.2009 20:53

   
Sieht richtig aus. :-)


Viele Grüße,

Siracusa
Zum Seitenanfang