<jupyter_start><jupyter_text>Labs 2 **1. Zdefiniować i sprawdzić działanie funkcji:**<jupyter_code>fiveToPower_ :: Integer -> Integer
fiveToPower_ x = 5^x

fiveToPower_ 3
_ToPower5 :: Num a => a -> a
_ToPower5 x = x^5

_ToPower5 2
subtrNFrom5 :: Num a => a -> a
subtrNFrom5 x = 5 - x

subtrNFrom5 3
subtr5From_ :: Num a => a -> a
subtr5From_ x = x - 5

subtr5From_ 6<jupyter_output><empty_output><jupyter_text>**2. Zdefiniować funkcję flip2 będącą odpowiednikiem funkcji flip.**<jupyter_code>flip2 :: (a -> b -> c) -> b -> a -> c
flip2 f x y = f y x

flip2 (^) 1 5<jupyter_output><empty_output><jupyter_text>**3. Zdefiniować funkcję isPalindrome.**<jupyter_code>isPalindrome :: [Char] -> Bool
isPalindrome x = x == reverse x

isPalindrome "ABBCBBA"<jupyter_output><empty_output><jupyter_text>**4. Zdefiniować funkcję getElemAtIdx wykorzystując funkcje poznane powyżej (np. drop , head , tail).**<jupyter_code>getElemAtIdx :: Int -> [a] -> a
getElemAtIdx idx xs = head(drop idx xs)

getElemAtIdx 2 [1,5,87,1,5]<jupyter_output><empty_output><jupyter_text>**5. Zdefiniować funkcję capitalize.**<jupyter_code>capitalize :: [Char] -> [Char]
capitalize w = toEnum(fromEnum (head w) - 32) : tail w

capitalize "hello"<jupyter_output><empty_output><jupyter_text>**6. Napisać wyrażenie obliczające, ile jest w przedziale [1,100] trójek liczb całkowitych reprezentujących długości boków trójkąta prostokątnego.**<jupyter_code>length [(a,b,c) | a <- [1..100], b <- [a..100], c <- [b..100], a^2+b^2==c^2]<jupyter_output><empty_output><jupyter_text>**7. Czy poniższa definicja funkcji (sprawdzającej, czy liczba jest pierwsza) jest poprawna?**<jupyter_code>isPrime :: Integral t => t -> Bool
isPrime n = [i | i <- [2..n-1], n `mod` i == 0] == []

isPrime 0
isPrime 8
isPrime 17
-- The implementation is not correct because 0 is not a prime number.<jupyter_output><empty_output><jupyter_text>**Czy jest to efektywna implementacja?**<jupyter_code>-- More effective implementation.
isPrime' :: Integral t => t -> Bool
isPrime' 0 = False
isPrime' 1 = False
isPrime' n = [i | i <- [2..n-1], n `mod` i == 0] == []

isPrime' 0
isPrime' 8
isPrime' 17<jupyter_output><empty_output><jupyter_text>**8. Napisać wyrażenie obliczające, ile jest w przedziale [1,10000] liczb pierwszych.**<jupyter_code>length [a | a <- [1..10000], isPrime' a]<jupyter_output><empty_output><jupyter_text>**9. Wykorzystując wynik poprzedniego ćwiczenia napisać funkcję, która podaje, ile jest liczb pierwszych w przedziale [1,n] , gdzie n jest parametrem funkcji.**<jupyter_code>primeNumbers :: Integral t => t -> Int
primeNumbers 0 = 0
primeNumbers 1 = 0
primeNumbers n = length [a | a <- [2..n-1], isPrime a]

primeNumbers 10<jupyter_output><empty_output><jupyter_text>**10. Napisać definicję funkcji allEqual.**<jupyter_code>allEqual :: Eq a => [a] -> Bool
allEqual [] = True
allEqual [x] = True
allEqual (x:xs) = all (==x) xs

allEqual [1,1,1]
allEqual [1,2,1]<jupyter_output><empty_output><jupyter_text>**11. Napisać definicję funkcji fib.**<jupyter_code>fib :: (Num a, Eq a) => a -> a
fib n = if n == 0 || n == 1 then n
        else fib (n - 2) + fib (n - 1)

fib 10<jupyter_output><empty_output><jupyter_text>**12. Napisać definicję funkcji fib na podstawie poniższej (korekursywnej) definicji ciągu Fibonacciego.**<jupyter_code>fibs = 0 : 1 : zipWith (+) fibs (tail fibs) :: [Int]

fibs !! 20<jupyter_output><empty_output><jupyter_text>**13. Napisać rekurencyjną definicje funkcji: prod'.**<jupyter_code>prod' :: Num a => [a] -> a
prod' [] = 1
prod' (x:xs) = x * prod' xs

prod' [1,2,3,4]<jupyter_output><empty_output><jupyter_text>**14. Napisać rekurencyjną definicje funkcji: length'.**<jupyter_code>length' :: [a] -> Int
length' [] = 0
length' (x:xs) = 1 + length' xs

length' [1,2,3,4]<jupyter_output><empty_output><jupyter_text>**15. Napisać rekurencyjną definicje funkcji: or'.**<jupyter_code>or' :: [Bool] -> Bool
or' [] = False
or' (x:xs) = x || or' xs

or' [True, False]<jupyter_output><empty_output><jupyter_text>**16. Napisać rekurencyjną definicje funkcji: and'.**<jupyter_code>and' :: [Bool] -> Bool
and' [] = True
and' (x:xs) = x && and' xs

and' [False, True]<jupyter_output><empty_output><jupyter_text>**17. Napisać rekurencyjną definicje funkcji: elem'.**<jupyter_code>elem' :: Eq a => a -> [a] -> Bool
elem' a [] = False
elem' a (x:xs)
    | a == x = True
    | otherwise = a `elem'` xs
    
elem' 3 [1,2,3,4]<jupyter_output><empty_output><jupyter_text>**18. Napisać rekurencyjną definicje funkcji: doubleAll.**<jupyter_code>doubleAll :: Num t => [t] -> [t]
doubleAll [] = []
doubleAll (x:xs) = 2*x : doubleAll xs

doubleAll [1,2,3,4]<jupyter_output><empty_output><jupyter_text>**19. Napisać rekurencyjną definicje funkcji: squareAll.**<jupyter_code>squareAll :: Num t => [t] -> [t]
squareAll [] = []
squareAll (x:xs) = x^2 : squareAll xs

squareAll [1,2,3,4]<jupyter_output><empty_output><jupyter_text>**20. Napisać rekurencyjną definicje funkcji: selectEven.**<jupyter_code>selectEven :: Integral t => [t] -> [t]
selectEven [] = []
selectEven (x:xs)
    | x `mod` 2 == 0 = x : selectEven xs
    | otherwise = selectEven xs
    
selectEven [1,2,3,4]<jupyter_output><empty_output><jupyter_text>**21. Napisać funkcję obliczającą średnią arytmetyczną elementów listy.**<jupyter_code>arithmeticMean :: (Real a, Fractional b) => [a] -> b
arithmeticMean [] = 0
arithmeticMean xs = realToFrac(sum xs) / fromIntegral(length' xs)

arithmeticMean [1,2,3,4]<jupyter_output><empty_output><jupyter_text>**22. Napisać definicje funkcji prod'2 wykorzystujące ‘akumulator’ i funkcję pomocniczą/wewnętrzną.**<jupyter_code>-- 1st solution
prod'2 :: Num a => [a] -> a
prod'2 xs = loop 1 xs
    where loop acc []     = acc
          loop acc (x:xs) = loop (x*acc) xs

prod'2 [1,2,3,4]
-- 2nd solution
prod''2 :: Num a => [a] -> a
prod''2 = loop 1
    where loop acc []     = acc
          loop acc (x:xs) = loop (x*acc) xs

prod''2 [1,2,3,4]<jupyter_output><empty_output><jupyter_text>**23. Napisać definicje funkcji length'2 wykorzystujące ‘akumulator’ i funkcję pomocniczą/wewnętrzną.**<jupyter_code>-- 1st solution
length'2 :: [a] -> Int
length'2 xs = loop 0 xs
    where loop acc []     = acc
          loop acc (x:xs) = loop (1+acc) xs

length'2 [1..4]
-- 2nd solution
length''2 :: [a] -> Int
length''2 = loop 0
    where loop acc []     = acc
          loop acc (x:xs) = loop (1+acc) xs

length''2 [1..4]<jupyter_output><empty_output><jupyter_text>**24. Napisać nową definicje funkcji sum.**<jupyter_code>{-# LANGUAGE BangPatterns #-}
sum'4 :: Num a => [a] -> a
sum'4 = loop 0
    where loop !acc []     = acc
          loop !acc (x:xs) = loop (x + acc) xs
      
sum'4 [1..10]<jupyter_output><empty_output><jupyter_text>**25. Napisać funkcję qSort i sprawdzić jej działanie.**<jupyter_code>qSort :: Ord a => [a] -> [a]
qSort [] = []
qSort (x:xs) = qSort (leftPart xs) ++ [x] ++ qSort(rightPart xs)
 where leftPart xs = [y | y <- xs, y <= x]
       rightPart xs = [y | y <- xs, y > x]

qSort [5, 2, 7, 3, 9,0]<jupyter_output><empty_output><jupyter_text>**26. Zmodyfikować funkcje wewnętrzne leftPart i rightPart tak, aby zamiast list comprehensions wykorzystać funkcję filter (z biblioteki standardowej).**<jupyter_code>qSort' :: Ord a => [a] -> [a]
qSort' [] = []
qSort' (x:xs) = qSort (leftPart xs) ++ [x] ++ qSort(rightPart xs)
 where leftPart xs = filter(<= x) xs
       rightPart xs = filter(> x) xs

qSort' [5, 2, 7, 3, 9,0]<jupyter_output><empty_output><jupyter_text>**27. Zdefiniować funkcję mSort (implementacja algorytmu MergeSort).**<jupyter_code>merge :: Ord a => [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) | x <= y    = x:merge xs (y:ys)
                    | otherwise = y:merge (x:xs) ys

mSort :: Ord a => [a] -> [a]
mSort [] = []
mSort [a] = [a]
mSort xs = merge (mSort(firstHalf xs)) (mSort(secondHalf xs))
    where firstHalf xs  = take (div (length xs) 2) xs
          secondHalf xs = drop (div (length xs) 2) xs
          
mSort [7, 2, 4, 9, 11, 0]<jupyter_output><empty_output><jupyter_text>**28. Zdefiniować funkcję iSort (implementacja algorytmu Insertion Sort).**<jupyter_code>insert :: Ord a => a -> [a] -> [a]
insert x [] = [x]
insert x (y:ys) | x < y     = x:y:ys
                | otherwise = y:insert x ys

iSort :: Ord a => [a] -> [a]
iSort [] = []
iSort (x:xs) = insert x (iSort xs)

iSort [7, 2, 4, 9, 11, 0]<jupyter_output><empty_output><jupyter_text>**29. Naspiać dwie wersje funkcji concat :: [[a]] -> [a]****- concat' - z wykorzystaniem list comprehension,**<jupyter_code>concat' :: [[a]] -> [a]
concat' xs = [y | x <- xs, y <- x]

concat' [[1,2,3], [4,5], [6], [7,8]]<jupyter_output><empty_output><jupyter_text>**- concat'' z wykorzystaniem rekursji.**<jupyter_code>concat'' :: [[a]] -> [a]
concat'' [] = []
concat'' (x:xs) = x ++ concat'' xs

concat'' [[1,2,3], [4,5], [6], [7,8]]<jupyter_output><empty_output><jupyter_text>**30. Napisać definicje funkcji isSorted.**<jupyter_code>isSorted :: (Ord a) => [a] -> Bool
isSorted [] = True
isSorted [x] = True
isSorted (x:y:xs) = x <= y && isSorted(y:xs)

isSorted [1,2,3,9,5]
isSorted [1,2,2,3]<jupyter_output><empty_output><jupyter_text>**31. Napisać definicje funkcji isSorted.**<jupyter_code>reverse' :: [a] -> [a]
reverse' [] = []
reverse' (x:xs) = reverse' xs ++ [x]

reverse' [1,2,3]<jupyter_output><empty_output><jupyter_text>**32. Napisać definicje funkcji zip.**<jupyter_code>zip' :: [a] -> [b] -> [(a,b)]
zip' _ [] = []
zip' [] _ = []
zip' (x:xs) (y:ys) = (x,y):zip' xs ys

zip' [1,2] [3,4]<jupyter_output><empty_output><jupyter_text>**33. Napisać definicje funkcji unzip.**<jupyter_code>unzip' :: [(a, b)] -> ([a],[b])
unzip' [] = ([], [])
unzip' xs = (map fst xs, map snd xs)

unzip' [(1,2), (3,4)]<jupyter_output><empty_output><jupyter_text>**34. Napisać definicje funkcji zip3.**<jupyter_code>zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' _ _ [] = []
zip3' _ [] _ = []
zip3' [] _ _ = []
zip3' (x:xs) (y:ys) (z:zs) = (x,y,z):zip3' xs ys zs

zip3' [1,2] [3,4] [5,6]<jupyter_output><empty_output><jupyter_text>**35. Napisać definicje funkcji subList.**<jupyter_code>subList :: Eq a => [a] -> [a] -> Bool
subList [] [] = True
subList _ [] = False
subList [] _ = True
subList (x:xs) (y:ys)
    | x == y = subList xs ys
    | otherwise = subList (x:xs) ys
    
subList [1,2] [3,1,2,4]<jupyter_output><empty_output><jupyter_text>**36. Napisać definicję funkcji sprawdzającej, czy pierwszy element listy jest podzielnikiem drugiego.**<jupyter_code>fstDivSec :: Integral a => [a] -> Bool
fstDivSec (x:y:_) | y `mod` x == 0 = True
fstDivSec _                        = False

fstDivSec [2,4,3,4]<jupyter_output><empty_output><jupyter_text>**37. Napisać definicję funkcji sprawdzającej, czy pierwszy element listy jest podzielnikiem trzeciego.**<jupyter_code>fstDivThr :: Integral a => [a] -> Bool
fstDivThr (x:y:z:_) | z `mod` x == 0 = True
                    | otherwise = False

fstDivThr [2,1,16,7,9]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1791701016762847, 'fraction_numerical': 0.03160208848584776, 'mean_word_length': 4.578947368421052, 'pattern_counts': {'":': 0, '<': 173, '<?xml version=': 0, '>': 242, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '39', 'dir': 'jupyter-structured-clean-dedup', 'id': '528608', 'license': 'MIT', 'n_tokens_mistral': 4914, 'n_tokens_neox': 4697, 'n_words': 1075, 'path': 'Lab_2/Lab_2.ipynb', 'repo_name': 'Szymon-Budziak/Functional_programming_exercises_solutions', 'size': '10917'}