module Arithmetik where
import Prelude hiding (sum,and,foldr,foldl)
pow1 b 0 = 1
pow1 b e = b * pow1 b (e-1)
pow2 b 0 = 1
pow2 b e
| even e = pow2 (b * b) (e `div` 2)
| otherwise = b * pow2 (b * b) (e `div` 2)
pow3acc acc b 0 = acc
pow3acc acc b e
| even e = pow3acc acc (b * b) (e `div` 2)
| otherwise = pow3acc (b * acc) (b * b) (e `div` 2)
pow3 b e
| e < 0 = error "Negativer Exponent"
| otherwise = pow3acc 1 b e
--pow3 = pow3acc 1
--sum [] = 0
--sum (x:xs) = x + sum xs
and [] = True
and (x:xs) = x && and xs
sum xs = sumacc 0 xs
where sumacc acc [] = acc
sumacc acc (x:xs) = (sumacc $! (acc + x)) xs
--root :: Int -> Int -> Integer
root :: (Integral a1, Integral a) => a -> a1 -> a1
root e r
| e < 1 = error "Zu kleiner Wurzelexponent"
| r < 0 = error "Negativer Radikand"
| otherwise = searchRoot 0 (r+1)
where searchRoot a b
| b - a == 1 = a
-- | x == r = m
| x > r = searchRoot a m
| otherwise = searchRoot m b
where x = pow3 m e
m = (a + b) `div` 2
--null [] = True
--null _ = False
isPrime n
-- | n < 2 = error "Zu kleine Zahl"
| n < 2 = False
| otherwise = null (filter (\k -> n `mod` k == 0) [2..(root 2 n)])
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys)
| x <= y = x : merge xs (y:ys)
| otherwise = y : merge (x:xs) ys
mergeSort [] = []
mergeSort [x] = [x]
--mergeSort xs = merge (mergeSort (take k xs)) (mergeSort (drop k xs))
-- where k = length xs `div` 2
mergeSort xs = merge (mergeSort a) (mergeSort b)
where (a,b) = splitAt k xs
k = length xs `div` 2
--isSorted [] = True
--isSorted [x] = True
isSorted (x:y:xs) = x <= y && isSorted (y:xs)
isSorted _ = True
--isSorted (x:xs@(y:_)) = x <= y && isSorted xs
mergeSortedIsSorted :: Ord a => [a] -> Bool
--mergeSortedIsSorted xs = isSorted (mergeSort xs)
--mergeSortedIsSorted xs = (isSorted . mergeSort) xs
mergeSortedIsSorted = isSorted . mergeSort
-- quickCheck
-- verboseCheck
-- aus Test.QuickCheck
foldr f y [] = y
foldr f y (x:xs) = x `f` foldr f y xs
foldl f y [] = y
foldl f y (x:xs) = foldl f (y `f` x) xs
sumr = foldr (+) 0
productr = foldr (*) 1
andr = foldr (&&) True
andl = foldl (&&) True