Exercise 5.1
sum2 :: Int
sum2 = sum [ x^2 | x <- [1..100] ]
Exercise 5.2
replicate :: Int -> a -> [a]
replicate n x = [ x | _ <- [1..n] ]
Exercise 5.3
pyths :: Int -> [(Int, Int, Int)]
pyths n = [ (x, y, z) | x <- [1..n], y <- [1..n], z <- [1..n], z^2 == x^2 + y^2 ]
Exercise 5.4
factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]
perfects :: Int -> [Int]
perfects n = [p | p <- [1..n], p == sum (factors p) - p]
A cleaner version uses a different implementation of factors, that returns only the factors which are different than the number itself:
factors' :: Int -> [Int]
factors' n = [x | x <- [1..n], n `mod` x == 0, x <= n `div` 2]
perfects' :: Int -> [Int]
perfects' n = [p | p <- [1..n], p == sum (factors' p)]
Exercise 5.5
xys :: [(Int, Int)]
xys = [(x,y)| x <- [1, 2, 3], y <- [4, 5, 6]]
xys' :: [(Int, Int)]
xys' = concat [[(x,y) | y <- [4,5,6]] | x <- [1,2,3]]
Exercise 5.6
find :: Eq a => a -> [(a, b)] -> [b]
find k t = [v| (k', v) <- t, k == k']
positions' :: Eq a => a -> [a] -> [Int]
positions' x xs = find x (zip xs [0..n]) where n = length xs - 1
Exercise 5.7
scalarproduct :: [Int] -> [Int] -> Int
scalarproduct xs ys = sum [ fst xy * snd xy | xy <- zip xs ys ]
Exercise 5.8
The idea is that when we calculate the table of frequencies we shouldn't differentiate between lowercase and uppercase letters. Then, once the shift factor is calculated, we crack the code by shifting both lowercases and uppercases.
1. Changes for calculating the frequencies:
-- Converts all letters to lowercases:
toLowers :: String -> String
toLowers cs = [toLower c | c <- cs]
-- Generates the same table as freqs does, but ignoring the capitalization:
freqs' :: String -> [Float]
freqs' cs = [ percent (count c cs') n | c <- ['a'..'z'] ]
where
n = lowers cs'
cs' = toLowers cs
2. Redefinitions of the functions shift and encode to make them case-insensitive:
let2intU :: Char -> Int
let2intU c = ord c - ord 'A'
int2letU :: Int -> Char
int2letU n = chr (ord 'A' + n)
shift' :: Int -> Char -> Char
shift' n c | isLower c = int2let ((let2int c + n) `mod` 26)
| isUpper c = int2letU ((let2intU c + n) `mod` 26)
| otherwise = c
encode' :: Int -> String -> String
encode' n cs = [ shift' n c | c <- cs ]
3. Use the newly defined encode' to crack the code, when the frequency table is calculated by the case-insensitive function freqs':
crack' :: String -> String
crack' xs = encode' (-factor) xs
where
factor = head (positions (minimum chitab) chitab)
chitab = [ chisqr (rotate n table') table | n <- [0..25] ]
table' = freqs' xs
Niciun comentariu:
Trimiteți un comentariu