www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

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

Logo - DracheHaskell-Forum

franzigoth1

Gepostet:
06.12.2007 16:19

Summe von Quadraten ausgeben  
Hi,.....

Man kann ja jede Zahl aus dem quadrat von vier zahlen bilden.

Ich soll nun eine Funktion implementieren, die diese Zahlen ausgibt, also wenn man die Zahl 51 eingibt, dann soll Haskell [1,5,5] ausgeben, denn die Summe der Quadrate von 5, 5 und 1 ergeben ja 51.

Hat einer eine Idee, brauche hier hilfe.....
Zum Seitenanfang ICQ    
 
Siracusa

Gepostet:
06.12.2007 22:10

   
Hallo,

hier könnte man sich eine Funktion anlegen, die vier Zahlen und das Resultat übergeben bekommt, und testet, ob durch Aufsummierung der Quadrate der vier Zahlen das Resultat herauskommt. Wenn ja, werden die Zahlen als Liste zurückgegeben. Wenn nicht, wird durch rekursiven Aufruf dieser Funktion erneut versucht das Resultat zu berechnen, allerdings mit veränderten Zahlen (oder zumindest mit einer Zahl verändert). Ist vielleicht nicht ganz einfach die Zahlen so zu ändern, damit nicht eine Zahl ins Unendliche läuft und die anderen gleich bleiben, aber auch alle möglichen Kombinationen von Zahlen mal drankommen. An der Stelle mußt du dir was cleveres überlegen. :-) die Cantorsche Tupelfunktion könnte da vielleicht helfen.


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
franzigoth1

Gepostet:
10.12.2007 17:06

   
Danke für die Idee, mal sehen ob ich es hinbekomme....
Zum Seitenanfang ICQ    
 
franzigoth1

Gepostet:
25.12.2007 13:51

Lösungsansatz?  
Hi...

Ich hab mich mal mit dem Problem auseinander gesetzt und folgene Implemtierung ausgetüfftelt:

sq::Int->[Int]
sq n = li (sq' n)

li::[Int]->[Int]
li [] = []
li (t:r)
| r == [] = [t]
| r /= [] = li r ++ [t]

sq'::Int->[Int]
sq' n
| n == 0 = [0]
| otherwise = f1 n 1

f1::Int->Int->[Int]
f1 n i
| i*i == n =
| i*i < n = f1 n (i+1)
| i*i > n = [i-1] ++ f1 (n-(i-1)*(i-1)) 1

Es funktioniert, nur bei größeren Zahlen gibt er 5 statt 4 Zahlen aus.
Weiß einer Rat, wie man das verhindern kann?????
Zum Seitenanfang ICQ    
 
Siracusa

Gepostet:
27.12.2007 16:08

   
Hallo,

tut mir leid, ich verstehe deinen Ansatz nicht. Kannst du erklären, wofür die einzelnen Funktionen da sind? Außerdem ist die Funktion f1 unvollständig, das dürfte nicht mal kompiliert werden. Offenbar gestaltest du die Anzahl der Zahlen in der Liste variabel. Wenn immer die gleiche Anzahl herauskommen soll, könntest du z.B. mit 3er-Tupeln arbeiten und erst ganz am Schluß in eine Liste umwandeln.


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
franzigoth1

Gepostet:
28.12.2007 13:56

Frage  
mit §er-Tupeln arbeiten?
Was genau ist denn das?
Zum Seitenanfang ICQ    
 
franzigoth1

Gepostet:
28.12.2007 14:03

Erklährung der Implementierung  
sq::Int->[Int]
sq n = li (sq' n) -- gibt Ergebnis aus.

li::[Int]->[Int] -- Erzeugt Liste aus denn Ergebnissen von sq'.
li [] = []
li (t:r)
| r == [] = [t]
| r /= [] = li r ++ [t]

sq'::Int->[Int]
sq' n
| n == 0 = [0]
| otherwise = f1 n 1

f1::Int->Int->[Int]
f1 n i
| i*i == n = -- ist die QuadratZahl i gleich die eingegebene Zahl n, das ist i die gesuchte Zahl
| i*i < n = f1 n (i+1) -- ist die QuadratZahl i kleiner als die eingegebene Zahl n, dann soll i um eins erweitert werden und nochmals überprüft werden
| i*i > n = [i-1] ++ f1 (n-(i-1)*(i-1)) 1 -- ist die QuadratZahl i größer als die eingegebene Zahl n, dann soll (i-1) in die gesuchte Liste mit eingegeben werden und das Ergebnis von (i-1)*(i-1) soll von der Zahl n devidiert werden und die neue Zahl n wird dann wieder überprüft
Zum Seitenanfang ICQ    
 
Siracusa

Gepostet:
28.12.2007 14:16

   
Eine Liste mit drei Elementen sieht so aus: [x,y,z]. Ein Tupel mit drei Elementen so: (x,y,z). Offenbar wird deine Liste an einigen Stellen um Elemente verlängert, wo es nicht gewollt ist. Wenn du nur Tupel verwendest, kannst du keine zusätzlichen Elemente hinzufügen, das Tupel enthält immer genau drei Elemente. Der Vorteil ist hier, daß du dich bei der Änderung eines bestimmten Wertes nicht in der Position vertuen kannst. Soll bspw. das dritte Element verändert werden, kannst du das so schreiben:
foo :: (Int, Int, Int) -> (Int, Int, Int)
foo (x,y,z) = (x, y, z+1)

Bei einer Liste mit variabler Länge könnte es sein, daß das dritte Element noch nichtmal existiert, was dann u.U. zu einem Laufzeitfehler führt.

Da deine Funktion ja zum Schluß wieder eine Liste zurückgeben soll, muß das Tupel wieder in eine Liste umgewandelt werden:
zuListe :: (Int, Int, Int) -> [Int]
zuListe (x,y,z) = [x,y,z]


Edit 1:
Mir ist grad aufgefallen, daß ja maximal vier Zahlen herauskommen sollen, d.h. du müßtest dann überall 4er-Tupel verwenden. ;-)

Edit 2:
Ich hatte weiter oben geschrieben, deine f1-Funktion sei nicht kompilierbar. Da hat wohl die Forum-Software ein [ i ] (ohne Leerzeichen) verschluckt. :-D


Viele Grüße,

Siracusa
Zum Seitenanfang