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

BigD

Gepostet:
02.04.2006 14:38

Programm was die quersumme berchnet.  
Hallo ich bin noch ziemlich neu mit Haskell zugange und habe daher noch nicht wirklich einen plan davon.
Ich muss jetzt für die Schule ein programm schreiben, dass unter anderem die quersumme einer Zahl berechnen muss.
Ich habe zwar ein Programm gefunden das funktioniert, aber ich versteh es nicht wirklich. Daher wäre es sehr nett, wenn es mir jemand erklären könnte, oder jemand ein einfacheres Programm hätte.
Hier ist das was ich nicht ganz verstehe:

machefeld :: Int -> [Int] -> [Int]
machefeld a b
|(div a 10) == 0 = b++[a]
|otherwise = machefeld (div a 10)(b++[(mod a 10)])

quersumme1 :: [Int] -> Int -> Int
quersumme1 a b
|a == [] = b
|otherwise = quersumme1 (tail a) ((head a) + b)

quersumme :: Int -> Int
quersumme a
|(div a 10) == 0 = a
|otherwise = quersumme (quersumme1 (machefeld a []) 0)


Ich sag schonmal vielen Dank für die Hilfe.
Zum Seitenanfang    
 
Jacke

Gepostet:
02.04.2006 21:18

   
ich erklär einfach mal deinen code
also:


machefeld :: Int -> [Int] -> [Int]
1 machefeld a b
2 |(div a 10) == 0 = b++[a]
3 |otherwise = machefeld (div a 10)(b++[(mod a 10)])

in zeile 2 wird geprüft ob a einstelllig ist...ist nur einmal der fall
in zeile 3 wird machefeld rekursiv wieder mit dem wert von der integerdivision durch 10 und der neuen liste b aufgerufen,
zu b wurde der wert von a modulo 10 hinzugefügt
ein beispiel damits klarer wird

erster aufruf
machefeld 123 []

geht in zeile 3
machefeld 12 [3]

geht in zeile 3
machefeld 1 [3,2]

geht in zeile 1
ausgabe [3,2,1]


1 quersumme1 :: [Int] -> Int -> Int
2 quersumme1 a b
3 |a == [] = b
4 |otherwise = quersumme1 (tail a) ((head a) + b)

quersumme1 ist ne hilfsfunktion und kriegt ne liste von zahlen als eingabe...
b ist die zwischensumme der quersumme...

nen beispiel
erster aufruf
quersumme1 [3,2,1] 0

geht in zeile 4
quersumme1 [2,1] 3

geht in zeile 4
quersumme1 [1] 5

geht in zeile 3
ausgabe 6



1 quersumme :: Int -> Int
2 quersumme a
3 |(div a 10) == 0 = a
4 |otherwise = quersumme (quersumme1 (machefeld a []) 0)

quersumme ist die hauptfunktion
in zeile 3 wird geprüft ob die zahl a einstellig is , wenn nicht wird die quersumme mithilfe der funktionen
machefeld und quersumme1 ausgerechnet
nen beispiel:
erster aufruf
quersumme 123

geht in zeile 4
quersumme (quersumme1 (machefeld 123 []) 0)

machefeld macht ein fled aus a
quersumme (quersumme1 ([3,2,1]) 0)

quersumme1 errechnet die quersumme aus 3,2,1
quersumme 6
jetzt wird zeile 3 von quersumme aufgerufen:
ausgabe 6




wenn du noch fragen hast, frag ruhig,...:-)
Zum Seitenanfang    
 
Hose

Gepostet:
02.04.2006 22:09

   
Hallo,

meiner Meinung nach ist das Programm doch unnötig umständlich geschrieben, denn es geht wesentlich einfacher:


quersumme x
| x == 0 = 0
| otherwise = x `mod` 10 + quersumme (x `div` 10)


Beim Aufruf von quersumme x wird geprüft, ob x=0. Falls ja, wird 0 als Ergebnis zurückgegeben. Sonst wird die letzte Ziffer der Zahl abgetrennt und dazu die Quersumme vom vorderen Teil der Zahl addiert.

Beispiel:
quersumme 123
= (123 mod 10) + quersumme (123 div 10)
= 3 + quersumme 12
= 3 + (12 mod 10) quersumme (12 div 10)
= 3 + 2 + quersumme 1
= 3 + 2 + (1 mod 10) + quersumme (1 div 10)
= 3 + 2 + 1 + quersumme 0
= 3 + 2 + 1 + 0 = 6

Viele Grüße!
Zum Seitenanfang    
 
Jacke

Gepostet:
02.04.2006 22:45

   
ok geht wirklich einfacher hast recht..:D

gruß jacke

Zum Seitenanfang    
 
BigD

Gepostet:
02.04.2006 23:21

   
Vielen Dank für eure Hilfe.
Ich hätte da noch ne weitere Frage zu diesen Programm.
Das Ergebnis der Quersumme soll nämlich darauf geprüft werden, ob es eine Schnapszahl ist oder nicht.
Sprich ob die quersumme einstellig ist bzw. eine zahl aus gleichen ziffern (zB. 77, 999,....)ist oder eben nicht.
Wie kann man das denn hinbekommen.
Vielen Dank schonmal für die Hilfe.
Zum Seitenanfang    
 
Jacke

Gepostet:
03.04.2006 09:06

   

schnapszahl ::Int->Bool
schnapszahl zahl= allequal (machefeld zahl [])
where allequal (x:xs)= and [(x==y) | y<-xs]


machefeld :: Int -> [Int] -> [Int]
machefeld a b
|(div a 10) == 0 = b++[a]
|otherwise = machefeld (div a 10)(b++[(mod a 10)])




--and prüft ob in ner liste alle true sind ...das mit den eckigen klammern ist list comprehension...und prüft ob alle zahlen in der liste gleich der ersten zahl sind...
und machefled macht ne liste aus der zahl
Zum Seitenanfang    
 
BigD

Gepostet:
03.04.2006 22:14

   
Danke erstmal.
Kannst du mir vieleicht mal einige Zeilen genauer erklären?

Was macht dieser Teil hier:

schnapszahl zahl= allequal (machefeld zahl [])
where allequal (x:xs)= and [(x==y) | y<-xs]

wofür steht das "zahl"
(steht das "zahl" nur für die zahl die untersucht werden soll? - Sprich die quersumme?)
was bringt das "allequal"
(ist das ein fester Begriff in Haskell?)

Vielen Dank schonmal.
Zum Seitenanfang    
 
BigD

Gepostet:
03.04.2006 23:00

   
Ich habe noch eine Frage:
Wie kann ich es denn schaffen, dass die quersumme einer Zahl überprüft wird ob sie, die quersumme, eine Schnapszahl ist?
Also wie kann ich die beiden Programme zusammenführen?
Zum Seitenanfang    
 
Jacke

Gepostet:
03.04.2006 23:50

   
zur ersten frage : zahl ist ne variable ...hätte ich auch blub nennen können..und ist in der tat die zahl die untersucht werden soll

allequal ist ne extra funktion die ich mir definiert habe...so wie machefeld zum beispiel...nach where kann man auch eigene funktionen definieren...allequal hab ich sogenannt weil es in haskell eine ähnliche funktion gibt und damit ich die anlogie dazu verdeutliche...ist aber auch nur nen name , kann man auch total anders nennen... "and" hingegen ist wirklich eine richtige haskellfunktion ...die prüft ob alle elemente eine liste true sind
und das [x==y |y<-xs] erzeugt ne liste von bools...dabei wird immer mit dem ersten x aus der lsite verglichen... und es kommt sowas raus wie [True,True,False]..oder ebend [True,True,True..]
wenn alle zahel gleich sind...and [True,True,False] liefert False und and [True,True] liefert True

so würde schnapszahl auch gehen...aber mit where ist es kompakter

schnapszahl zahl= allequal (machefeld zahl [])


allequal (x:xs)= and [(x==y) | y<-xs]


zu deiner zweiten frage :

das macht man dann so:
neuesprog ::Int -> Bool
neuesprog zahl = schnapszahl (quersumme zahl)

gruß jacke
Zum Seitenanfang    
 
BigD

Gepostet:
04.04.2006 17:35

   
Vielen Dank für die Hilfe, aber etwas ist mir noch nicht ganz klar:

was macht die Funktion "allequal"?
Zum Seitenanfang    
 

  1 2 nächste Seite