
Discrete math with computers_3
.pdf382 |
APPENDIX C. SOLUTIONS TO SELECTED EXERCISES |
7.
member0 :: String -> Bool
member0 string = or (map (== ’0’) string)
8.
foldr max 0 [1,5,3]
=1 ‘max‘ (5 ‘max‘ (3 ‘max‘ 0))
=1 ‘max‘ (5 ‘max‘ 3)
=1 ‘max‘ 5
=5
9.
addJust :: Maybe Int -> Maybe Int -> Maybe Int addJust (Just a) (Just b) = Just (a + b) addJust (Just a) Nothing = Just a
addJust Nothing (Just a) = Just a addJust Nothing Nothing = Nothing
addMaybe :: [Maybe Int] -> [Maybe Int] -> [Maybe Int] addMaybe lst1 lst2 = zipWith addJust lst1 lst2
10.
data Metals = Copper | Silver | Gold | Tin | Platinum | Bronze deriving (Eq, Show)
11. The coins can be represented by a list containing one or more elements of the following type:
data Coins = OneP Int | TwoP Int | FiveP Int | TenP Int | TwentyP Int
| FiftyP Int | HundredP Int deriving (Eq, Show)
12.
data Universal = BOOL Bool | INT Int | CHAR Char deriving (Eq, Show)
13. A separate constructor is needed to indicate the number of elements that are present, so we introduce five constructors Tuple0, etc. It would not be correct to use a list type, for two reasons: the individual elements should be allowed to have di erent types, and the number of elements must be limited to four.
C.1. INTRODUCTION TO HASKELL |
383 |
data Tuples a b c d = Tuple0 | Tuple1 a | Tuple2 a b | Tuple3 a b c | Tuple4 a b c d deriving (Eq, Show)
15.
showMaybe :: Show a => Maybe a -> String showMaybe Nothing = []
showMaybe (Just a) = show a
16.
bitwiseAnd :: [Int] -> [Int] -> [Int]
bitwiseAnd word1 word2 = zipWith bitAnd word1 word2
17.
[True, False] |
"2" ++ "a" |
[(3,True), (9,False)] |
2 == 3 |
’a’ > ’b’ |
[[1],[2],[3]] |
18.The types of the two paired elements must be the same, according to the type signature given. In addition, the type of the first component of the pair was defined as being of the Num class, while the function f was applied to a pair with a Boolean as its first element.
19.There are two possible constructors in the type, and the function definition handles only one of them. If the other is used, an error occurs.
20.
[a | (Just a) <- xs]
21.
largerThanN :: [Int] -> Int -> [Int] largerThanN lst n = [e | e <- lst, e > n]
22.
f :: [Int] -> Int -> [Int]
f lst v = [n | n <- [0..length lst - 1], lst!!n == v]
23.
[e | e <- [1..20],
[x | x <- [1..e], x * x == e] == []]
24. We define an auxiliary function that compares the current letter with the one we are looking for, and increments the running count if it matches. The main iteration over the string is performed by the foldr.
384 |
APPENDIX C. SOLUTIONS TO SELECTED EXERCISES |
count :: (Eq a, Num b) => a -> a -> b -> b count letter x acc
= if letter == x then acc + 1 else acc
countLetters :: Char -> String -> Int countLetters c lst = foldr (count c) 0 lst
25.
remove :: Char -> Char -> [Char] -> [Char] remove ch x acc
= if x == ch then acc else x:acc
removeEachLetter :: Char -> [Char] -> [Char] removeEachLetter ch lst
= foldr (remove ch) [] lst
26.
rearrange :: [a] -> a -> [a] rearrange lst x = x:lst
rev :: [a] -> [a]
rev lst = foldl rearrange [] lst
27.
takeLast :: Maybe a -> a -> Maybe a takeLast Nothing x = Just x takeLast (Just y) x = Just x
maybeLast :: [a] -> Maybe a
maybeLast lst = foldl takeLast Nothing lst
C.3 Recursion
1.
copy :: [a] -> [a] copy [] = []
copy (x:xs) = x : copy xs
2.
inverse :: [(a,b)] -> [(b,a)] inverse [] = []
inverse ((a,b):xs) = (b,a) : inverse xs
C.3. RECURSION |
385 |
3.
merge :: Ord a => [a] -> [a] -> [a] merge [] bs = bs
merge as [] = as merge (a:as) (b:bs) =
if a < b
then a : merge as (b:bs) else b : merge (a:as) bs
4.
(!!):: Int -> [a] -> Maybe a
(!!)n [] = Nothing
(!!)0 (x:xs) = Just x
(!!)n (x:xs) = (!!) (n-1) xs
5.
lookup :: Eq a => a -> [(a,b)] -> Maybe b lookup a [] = Nothing
lookup a ((a’,b):ps)
= if a==a’ then Just b else lookup a ps
6.
countElts |
:: Eq a => a -> [a] -> Int |
||
countElts |
e [] |
= |
0 |
countElts |
e (x:xs) = |
|
|
if e == |
x |
|
|
then 1 + countElts e xs else countElts e xs
7.
removeAll :: Eq a => a -> [a] -> [a] removeAll e [] = []
removeAll e (x:xs) = if e == x
then removeAll e xs else x : removeAll e xs
8.
f :: [a] -> [a] f [] = []
f (x:xs) = g xs
g :: [a] -> [a] g [] = []
g (x:xs) = x:f xs
386 |
APPENDIX C. SOLUTIONS TO SELECTED EXERCISES |
9.
extract :: [Maybe a] -> [a] extract [] = [] extract (Nothing:xs) = extract xs
extract (Just x:xs) = x : extract xs
10.
loop :: String -> String -> Int -> Maybe Int loop [] s2 n = Nothing
loop (x:xs) s2 n
= if length s2 > length (x:xs) then Nothing
else if take (length s2) (x:xs) == s2 then Just n
else loop xs s2 (n+1)
f :: String -> String -> Maybe Int f str1 str2 = loop str1 str2 0
11.
foldrWith ::
(a -> b -> c -> c) -> c -> [a] -> [b] -> c foldrWith f z [] bs = z
foldrWith f z as [] = z foldrWith f z (a:as) (b:bs) =
f a b (foldrWith f z as bs)
12.
mappend :: (a -> [b]) -> [a] -> [b] mappend f xs = foldr fun [] xs
where fun x acc = f x ++ acc
13.
removeDuplicates :: Eq a => [a] -> [a] removeDuplicates [] = [] removeDuplicates (x:xs)
= if elem x xs
then removeDuplicates xs else x : removeDuplicates xs
14.
member :: Eq a => a -> [a] -> Bool member a [] = False
member a (x:xs) = a == x || member a xs
C.4. INDUCTION |
|
387 |
15. |
|
|
intersection :: Eq a => [a] -> [a] -> [a] |
||
intersection [] set2 |
= [] |
|
intersection (x:set1) set2 |
||
= if (elem x set2) |
|
|
then x : intersection set1 set2 |
||
else intersection set1 set2 |
||
16. |
|
|
isSubset :: Eq a => [a] -> [a] -> Bool |
||
isSubset [] set2 |
|
= True |
isSubset (x:xs) set2 = elem x set2 /\ isSubset xs set2 |
||
17. |
|
|
isSorted :: Ord a => [a] -> Bool |
||
isSorted [] |
= True |
isSorted (x:[]) = True
isSorted (x:y:xs) = x < y && isSorted (y:xs)
C.4 Induction
1. Let m be an arbitrary natural number, and we will prove that the theorem holds for every natural number n by induction over n.
Base case: a0×n = a0 = 1 = (am)0.
Induction case: assume the hypothesis am×n = (am)n. The aim is to establish am×(n+1) = (am)n+1. Transform the left-hand side into the right-hand side using algebra: am×(n+1) = a(m×n)+m = am×n × am = (using the induction hypothesis) (am)n × am = (am)n+1. Therefore am×n = (am)n → am×(n+1) =
(am)(n+1). So by mathematical induction, we have n |
|
N.am×n = (am)n. |
|
|
|
n−1 (2i + 1), and we |
|
2. The sum of the first n odd numbers can be written as |
|||
want to prove that this is equal to n2 |
|
|
i=0 |
|
. It’s possible to |
|
|
This theorem can also be proved by reusing the theorem we already have,
i=0 |
1 = 2 |
2 |
+ n = n − n + n = n . |
|
(2i + 1) |
= 2 |
|
|
along |
with |
some |
simple algebra, |
as follows: |
n−1 |
n−1 i + |
||
n−1 |
|
(n−1)n |
2 |
2 |
i=0 |
|
|
i=0 |
Proof by |
induction on n. |
|
|
|
|
|
||
4. |
|
|
|
|
|
|
|
|
Base case.
0
i=1 fib i
=0
=0 + 1 − 1
=fib 0 + fib (0 + 1) − 1
=fib (0 + 2) − 1


C.4. INDUCTION |
389 |
7.
Proof. Using the definition of composition, we can rewrite the equation to be proved as:
map f (map g xs) = map (f.g) xs
We prove this by induction over xs. The base case is |
|
|
map f (map g [ ]) |
{ map.1 |
} |
= map f [ ] |
||
= [ ] |
{ map.1 } |
|
= map (f.g) [ ] |
{ map.1 |
} |
Assume that map f (map g xs) = map (f.g) xs. The inductive case is
map f (map g (x : xs)) |
{ map.2 } |
|
= map f (g x : map g xs) |
||
= f (g x) |
: map f (map g xs) |
{ map.2 } |
= f (g x) |
: map (f.g) xs |
{ hypothesis } |
= ((f.g) x) : map (f.g) xs |
{ (.) } |
|
= map (f.g) (x : xs) |
{ map.2 } |
11.
Theorem 109 (++ is associative). (xs++ys)++zs = xs++(ys++zs)
Proof. Induction over xs. The base case is
([ ]++ys)++zs
=ys++zs
=[ ]++(ys++zs)
Inductive case.
((x : xs)++ys)++zs
=(x : (xs++ys))++zs
=x : ((xs++ys)++zs)
=x : (xs++(ys++zs))
=(x : xs)++(ys++zs)
390 |
APPENDIX C. SOLUTIONS TO SELECTED EXERCISES |
13. The first line of the inductive case says ‘Assume P (n), and consider a set containing n + 1 horses; call them h1, h2, . . . , hn+1.’ Consider what happens when n = 1. Our set of n + 1 horses contains only two of them, h1 and h2. Thus the two subsets turn out to be A = {h1} and B = {h2}. All the horses in A have the same colour, and all the horses in B have the same colour. So far, so good—but the next sentence says ‘Pick one of the horses that is an element of both A and B,’ and it is impossible to do this because when n = 1, the sets
A and B are disjoint. The rest of the proof is invalid because it relies on this non-existent horse.
There are two useful lessons to learn from this.
•Whenever a proof says to ‘pick an x such that . . . ’, it is essential to make sure that such an x exists.
•It is helpful to work through the details using a concrete example.
By the way: the flaw explained above is the only error in this proof. If the proof worked for the case n = 1—if all pairs of horses had the same colour—then it would indeed be true that all horses are the same colour.
14.
The length of xss must be finite, otherwise the operation would never terminate and this result would never be reached.
15.
reverse (reverse [1, 2, 3])
=reverse [3, 2, 1]
=[1, 2, 3]
16.
Proof. Induction over xs. The base case:
reverse([]++ys)
=reverse ys
=reverse ys++[ ]
=reverse ys++reverse [ ]
Inductive case:
reverse ((x : xs)++ys)
=reverse (x : (xs++ys))
=reverse (xs++ys)++[x]
=(reverse ys++reverse xs)++[x]
=reverse ys++(reverse xs++[x])
=reverse ys++(reverse(x : xs))