Using a list comprehension, give an expression that calculates the sum 12 + 22 + … + 1002 of the first one hundred integer squares.
sum100ConsecSquares :: Int
= sum [x^2 | x <- [1..100]] sum100ConsecSquares
Suppose that a coordinate grid of size m × n is given by the list of all pairs (x,y) of integers such that 0 ≤ x ≤ m and 0 ≤ y ≤ n. Using a list comprehension, define a function
grid :: Int -> Int -> [(Int,Int)]
that returns a coordinate grid of a given size. For example:> grid 1 2 0,0),(0,1),(0,2),(1,0),(1,1),(1,2)] [(
grid :: Int -> Int -> [(Int,Int)]
= [(x,y) | x <- [0..m], y <- [0..n]] grid m n
Using a list comprehension and the function grid above, define a function
square :: Int -> [(Int,Int)]
that returns a coordinate square of size n, excluding the diagonal from (0,0) to (n,n). For example:> square 2 0,1),(0,2),(1,0),(1,2),(2,0),(2,1)] [(
grid :: Int -> Int -> [(Int,Int)]
= [(x,y) | x <- [0..m], y <- [0..n]]
grid m n
square :: Int -> [(Int,Int)]
= [(x,y) | (x,y) <- grid n n, x /= y] square n
In a similar way to the function length, show how the library function
replicate :: Int -> a -> [a]
that produces a list of identical elements can be defined using a list comprehension. For example:> replicate 3 True True,True,True] [
replicate :: Int -> a -> [a]
replicate n x = [x | _ <- [1..n]]
A triple (x,y,z) of positive integers is Pythagorean if it satisfies the equation x2 + y2 = z2. Using a list comprehension with three generators, define a function
pyths :: Int -> [(Int,Int,Int)]
that returns the list of all such triples whose components are at most a given limit. For example:> pyths 10 3,4,5),(4,3,5),(6,8,10),(8,6,10)] [(
By adding in the constraints that a ≤ b ≤ c we can uniquely generate Pythagorean triplets which are unique up to rotation.
pyths :: Int -> [(Int,Int,Int)]
= [(a,b,c) | c <- [1..n],
pyths n <- [1..c],
b <- [1..b],
a ^2 + b^2 == c^2] a
A positive integer is perfect if it equals the sum of all of its factors, excluding the number itself. Using a list comprehension and the function factors, define a function
perfects :: Int -> [Int]
that returns the list of all perfect numbers up to a given limit. For example:> perfects 500 6,28,496] [
factors :: Int -> [Int]
= [x | x <- [1..n], n `mod` x == 0]
factors n
perfects :: Int -> [Int]
= [x | x <- [1..n],
perfects n == sum (factors x) - ] x
Show how the list comprehension
[(x,y) | x <- [1,2], y <- [3,4]]
with two generators can be re-expressed using two comprehensions with single generators. Hint: nest one comprehension within the other and make use of the library functionconcat :: [[a]] -> [a]
.
list1 :: [(Int,Int)] = concat [[(x,y) | y <- [3,4]] | x <- [1,2]] list1
Redefine the function
positions
using the functionfind
.
find :: Eq a => a -> [(a,b)] -> [b]
= [v | (k',v) <- t, k == k']
find k t
positions :: Eq a => a -> [a] -> [Int]
= [i | (x',i) <- zip xs [0..], x == x']
positions x xs
positions' :: Eq a => a -> [a] -> [Int]
= find x (zip xs [0..]) positions' x xs
The scalar product of two lists of integers
xs
andys
of length n is given by the sum of the products of corresponding integers:$$\sum_{i=0}^{n-1} xs_i \cdot ys_i$$
In a similar manner to
chisqr
, show how a list comprehension can be used to define a functionscalarproduct :: [Int] -> [Int] -> Int
that returns the scalar product of two lists. For example:> scalarproduct [1,2,3] [4,5,6] 32
chisqr :: [Float] -> [Float] -> Float
= sum [((o-e)^2)/e | (o,e) <- zip os es]
chisqr os es
scalarproduct :: [Int] -> [Int] -> Int
= sum [x*y | (x,y) <- zip xs ys] scalarproduct xs ys
Modify the Caesar cipher program to also handle upper-case letters.
-- We assume that the input is not only upper case letters.
import Data.Char
-- Returns a list of indices of the specifed value
positions :: Eq a => a -> [a] -> [Int]
= [i | (x',i) <- zip xs [0..], x == x']
positions x xs
-- Returns the number of lowercase characters
lowers :: String -> Int
= length [x | x <- xs, 'a' <= x && x <= 'z']
lowers xs
-- Returns the number of occurences
count :: Char -> String -> Int
= length [x' | x' <- xs, x == x']
count x xs
-- Converts a character into an integral value
-- Specifically, it maps [a..z]++[A..Z] to the interval [0..51]
let2int :: Char -> Int
| 'a' <= c && c <= 'z' = ord c - ord 'a'
let2int c | 'A' <= c && c <= 'Z' = ord c - ord 'A' + 26
| otherwise = ord c
-- Converts an integral value into a character
int2let :: Int -> Char
| n <= 25 = chr (ord 'a' + n)
int2let n | n <= 51 = chr (ord 'A' - 26 + n)
| otherwise = chr n
shift :: Int -> Char -> Char
shift n c | isLower c = int2let ((let2int c + n) `mod` 26)
| isUpper c = int2let (((let2int c + n - 26) `mod` 26) + 26)
| otherwise = c
encode :: Int -> String -> String
= [shift n x | x <- xs]
encode n xs
-- Frequency distribution of lowercase english letters
table :: [Float]
= [8.1, 1.5, 2.8, 4.2, 12.7, 2.2, 2.0, 6.1, 7.0,
table 0.2, 0.8, 4.0, 2.4, 6.7, 7.5, 1.9, 0.1, 6.0,
6.3, 9.0, 2.8, 1.0, 2.4, 0.2, 2.0, 0.1]
percent :: Int -> Int -> Float
= (fromIntegral n / fromIntegral m) * 100
percent n m
-- Only necessary to count the number of lowercase letters present.
freqs :: String -> [Float]
= [percent (count x xs) n | x <- ['a'..'z']]
freqs xs where n = lowers xs
chisqr :: [Float] -> [Float] -> Float
= sum [((o-e)^2)/e | (o,e) <- zip os es]
chisqr os es
rotate :: Int -> [a] -> [a]
= drop n xs ++ take n xs
rotate n xs
crack :: String -> String
= encode (-factor) xs
crack xs where
= head (positions (minimum chitab) chitab)
factor = [chisqr (rotate n table') table | n <- [0..25]]
chitab = freqs xs table'