Frage

Ich habe dieses komplexe Iterationen -Programm, das ich in Ti Basic geschrieben habe, um eine grundlegende Iteration mit einer komplexen Zahl durchzuführen und dann die Größe des Ergebnisses zu geben:

INPUT “SEED?”, C
INPUT “ITERATIONS?”, N
C→Z
For (I,1,N)
Z^2 + C → Z
DISP Z
DISP “MAGNITUDE”, sqrt ((real(Z)^2 + imag(Z)^2))
PAUSE
END

Ich möchte eine Haskell -Version davon machen, um meinen Lehrer in einer Aufgabe zu begeistern. Ich lerne immer noch nur und bin so weit gekommen:

fractal ::(RealFloat a) =>
          (Complex a) -> (Integer a) -> [Complex a]
fractal c n | n == a = z : fractal (z^2 + c)
   | otherwise = error "Finished"

Was ich nicht weiß, wie ich es nur iterieren kann n Zeiten, also wollte ich es zählen lassen a und dann vergleichen Sie es mit n um zu sehen, ob es fertig war.

Wie würde ich das vorgehen?

War es hilfreich?

Lösung

Die Antwort von NewaccT zeigt den Weg:

fractal c n = take n $ iterate (\z -> z^2 + c) c

Iterate Generiert die unendliche Liste der wiederholten Anwendungen. Ex:

iterate (2*) 1 == [1, 2, 4, 8, 16, 32, ...]

In Bezug auf das IO müssen Sie einige monadische Berechnungen durchführen.

import Data.Complex
import Control.Monad

fractal c n = take n $ iterate (\z -> z^2 + c) c

main :: IO ()
main = do
    -- Print and read (you could even omit the type signatures here)
    putStr "Seed: "
    c <- readLn :: IO (Complex Double)

    putStr "Number of iterations: "
    n <- readLn :: IO Int

    -- Working with each element the result list
    forM_ (fractal c n) $ \current -> do
        putStrLn $ show current
        putStrLn $ "Magnitude: " ++ (show $ magnitude current)

Da der Komplex standardmäßig von und zu Zeichenfolgen konvertierbar ist, können Sie verwenden readLn sie aus der Konsole zu lesen (Format ist Re :+ Im).

Bearbeiten: Nur zum Spaß könnte man die monadische Syntax und die Signaturen eingeben, die das gesamte Programm dazu komprimieren würden:

main = 
    (putStr "Seed: ") >> readLn >>= \c -> 
    (putStr "Number of iterations: ") >> readLn >>= \n -> 
    forM_ (take n $ iterate (\z -> z^2 + c) c) $ \current ->
    putStrLn $ show current ++ "\nMagnitude: " ++ (show $ magnitude current)

Bearbeiten Nr. 2: Einige Links im Zusammenhang mit den Sätzen von Plotten und Mandelbrot.

Andere Tipps

Nun, Sie können immer eine unendliche Liste von Ergebnissen von wiederholten Anwendungen generieren und die erste nehmen n von ihnen benutzen take. Und die iterate Funktion ist nützlich, um eine unendliche Liste von Ergebnissen wiederholter Anwendungen zu generieren.

Wenn Sie eine Liste von Werten möchten:

fractalList c n = fractalListHelper c c n
                  where 
                     fractalListHelper z c 0 = []
                     fractalListHelper z c n = z : fractalListHelper (z^2 + c) c (n-1)

Wenn Sie sich nur um das letzte Ergebnis kümmern:

fractal c n = fractalHelper c c n
                  where
                    fractalHelper z c 0 = z
                    fractalHelper z c n = fractalHelper (z^2 + c) c (n-1)

Grundsätzlich benötigen Sie in beiden Fällen eine Helferfunktion für die Zählung und Akkumulation. Jetzt bin ich mir sicher, dass es eine bessere/weniger ausführliche Möglichkeit gibt, dies zu tun, aber ich bin selbst ein Haskell -Neuling.

Bearbeiten: Nur für Kicks, ein FILDR-One-Liner:

fractalFold c n = foldr (\c z -> z^2 + c) c (take n (repeat c)) 

(Obwohl das (Take N (Repeat C)) etwas unnötig erscheint, muss es einen noch besseren Weg geben)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top