2009-03-16 7 views
0

Haftungsausschluss: Ich bin neu bei Haskell und ich erinnere mich nicht viel über FP von der Universität, also kann es mehr als ein oder zwei Fehler in meinem Code geben. Dies ist auch mein Code für Euler Problem 3.Haskell: Rekursion mit Array-Argumenten

Ich versuche, eine Funktion mit zwei Arrays als Argumente und ein Array als Ergebnis rekursiv aufzurufen.

Das Ziel:

  • n annehmen 10 für diese Frage
  • eine Liste aller natürlichen Zahlen von 1 bis n erstellen (Variable 'allNumbers' ist Code)
  • erstellen eine weitere Liste von alle natürlichen Zahlen von 1 bis n (Variable ist 'allFactors' ist Code)
  • nimm das erste Element in 'allFactors' und multipliziere den Rest der Anzahl von 'allFactors' mit dieser Zahl. (dies erzeugt ein Array von Zahlen)
  • entfernen Sie alle diese Nummern von 'allNumbers'
  • fahren Sie von 1 bis n fort, bis 'allFactors' leer ist.

Hier ist mein Code:

mkList :: Int -> [Int] 
mkList n = [1..n-1] 

modArray :: Int -> Int -> [Int] 
modArray a b = [ x*b | x <- [1..a], x `mod` b == 0] 

modArrayAll :: [Int] -> [Int] -> [Int] 
modArrayAll [] [] = [] 
modArrayAll (x:xs) (y:ys) = (e) 
    where 
     m = head(ys) 
     n = length(xs) 
     e = (modArrayAll xs ys) \\ modArray n m 

(in Haupt)

let allNumbers = mkList (first + 1) 
let allFactors = mkList (first + 1) 
let mainList2 = modArrayAll allNumbers allFactors 

Dies in einer Null-Liste führt. Allerdings, wenn ich habe:

e = xs \\ modArray n m --WORKS for one iteration 

ich die ungeraden Zahlen alle bekommen von 1 bis 10.

Meine Frage: Warum ist das nicht die Art und Weise arbeiten würde ich es erwarten? Ich würde erwarten, dass der rekursive Stack die leere Array-Bedingung treffen würde und einfach ein leeres Array zurückgeben würde, das nicht aus dem aufrufenden Array entfernt würde, und es würde nur die Primzahlen zurückgeben?

Antwort

5

kopierte ich Ihr Ziel Anmerkungen:

-- assume n is 10 for this question 
n=10 

-- create a list of all natural numbers from 1 to n (variable is 'allNumbers' is code) 
allNumbers = [1..n] 

-- create another list of all natural numbers from 1 to n (variable is 'allFactors' is code) 
allFactors = [2..n] -- i suspect you really wanted this rather than [1..n] 

-- take the first element in 'allFactors' and 
-- multiply the rest of the numbers of 'allFactors' by this number. 
-- (this generates an array of numbers) 
-- continue from 1 to n until 'allFactors' is empty 
factorProducts = [ x*y | x <- allFactors, y <- allFactors] 

-- remove all these numbers from 'allNumbers' 
whatYouWanted = allNumbers \\ factorProducts 

Im Moment scheinen Sie immer noch in einer ziemlich zwingend notwendig Haltung zu denken. Versuchen Sie, mehr darüber nachzudenken, was Sie wollen, nicht wie Sie es bekommen :)

+0

Danke für die Rückmeldung. Was ich will, sind alle Primfaktoren von 'n'. Ich habe einen anderen Algorithmus in Python ausprobiert. Also, ich bin nicht ganz sicher, wie man das in Haskell (es ist schon eine Weile) – cbrulak

+0

Vielen Dank für das Feedback. Ich habe meinen Code neu geschrieben und ich denke, es ist besser. – cbrulak

1

modArray n m erstellt eine Liste von Vielfachen von m, die Sie dann aus der "Hauptliste" von Ganzzahlen entfernen. Aber modArray n m enthält 1*m, so dass jede Nummer entfernt wird, weil es ein "Vielfaches" von sich selbst ist. In Ihrem Testfall erhalten Sie nur die ungeraden Zahlen, während Sie möchten, dass 2 immer noch in der Ergebnisliste enthalten ist. Zusätzlich ist 1 in Ihrer Liste von Faktoren enthalten, die alle Zahlen eliminiert, da sie alle Vielfache von 1 sind.

Der abschließende Fall der Rekursion ist modArrayAll [] [] = [], so dass dort eine leere Liste zurückgegeben wird. Dann in den umliegenden rekursiven Aufrufen dieser Rückgabewert wird hier verwendet:

(modArrayAll xs ys) \\ modArray n m 

Diese weitere Elemente zu entfernen versucht (die zurück von modArray n m) aus der bereits leeren Liste zurück von modArrayAll xs ys. Es werden keine neuen Elemente hinzugefügt und die Ergebnisliste bleibt leer. Mit Ihrem Algorithmus wollen Sie die [] -case, um die ganze Liste der Zahlen, nicht eine leere zurückgeben. Dann kann die \\ modArray n m in den umgebenden rekursiven Funktionsaufrufen mehr und mehr der Nicht-Primfaktoren herausfiltern.