Haskell Funktion Frage?

1 Antwort

Ein Beispielprogramm, um zu prüfen, ob ein Wert un-/gerade ist:

isEven :: Integer -> Integer -> Bool
isEven x y =  x `mod` y == 0

main = do
  print(isEven 5 2) --False
  print(isEven 4 2) --True

Folgend noch ein Beispiel, bei der eine andere Funktion die obige Funktion nutzt:

isPrime :: Integer -> Bool
isPrime x = x > 1 && not(isEven x 2)

Aber das wäre in der Logik natürlich noch falsch.

Zunächst sollte man schauen, was eine Primzahl ist und wie sie sich berechnen lässt.

  1. Eine Primzahl ist größer als 1.
  2. Eine Primzahl ist nur durch sich selbst (und 1) ganzzahlig teilbar.

Das heißt, man könnte schon einmal diesen Fall formulieren:

isPrime :: Int -> Bool
isPrime 2 = True
isPrime x | x > 1 = not(isEven x 2) && --call function to calculate prime factors...
          | otherwise = False

Im Falle, dass das Argument 2 ist, kann man sofort True zurückgeben, denn dies stellt die kleinste mögliche Primzahl dar. Alle nachkommenden geraden Zahlen sind keine Primzahlen, da sie durch 2, 1 und sich selbst ohne Rest teilbar sind.

Im Falle dass x <= 1, wird der otherwise-Fall ausgeführt, also False zurückgegeben.

Folgend wäre es notwendig, alle ungeraden Zahlen zu prüfen. Die 9 bspw. ist eine ungerade Zahl, die durch 1, 3 und 9 teilbar ist und somit keine Primzahl darstellen würde. Du müsstest beginnend bei 3 (die 1 und 2 brauchen wir ja nicht beachten, denn durch 1 ist die Division immer möglich und die geraden Zahlen wurden bereits herausgefiltert) zählend bis zur Quadratwurzel von x prüfen, ob eine ganzzahlige Division möglich ist.

Für das Beispiel 9 also:

Von 3 bis sqrt(9) = 3
9 % 3 = 0

Oder für die 23:

Von 3 bis sqrt(23) = ~4
23 % 3 = 2
23 % 4 = 3

Oder für die 41:

Von 3 bis sqrt(41) = ~6
41 % 3 = 2
41 % 4 = 1
41 % 5 = 1
41 % 6 = 5

Zahlen über der Quadratwurzel kann man ausschließen. Eine Zahl (x) hat keine echten Teiler, die größer als √x sind.

Diese Implementation wäre also der nächste Schritt. Dazu könntest du dir eine weitere Funktion schreiben und die im obigen Snippet an die Stelle meines Kommentars setzen.

Im Grunde hast du hierbei eine Iteration (bzw. Rekursion). Deine Funktion müsste sich so lange selbst aufrufen und einen Check mit isEven durchführen, bis das Ergebnis wahr ist oder ein Maximum erreicht wurde. Bei jedem Aufruf wird der Teiler um 1 erhöht.