Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Discrete math with computers_3

.pdf
Скачиваний:
87
Добавлен:
16.03.2016
Размер:
2.29 Mб
Скачать

Appendix C

Solutions to Selected Exercises

C.1 Introduction to Haskell

3.

isA :: Char -> Bool isA ’a’ = True

isA c = False

4.

isHello :: String -> Bool

isHello (’h’:’e’:’l’:’l’:’o’:[]) = True

isHello str

 

= False

5.

 

 

removeSpace :: String -> String

removeSpace []

= []

removeSpace (’

’:xs) = xs

removeSpace xs

= xs

6.

 

 

toBool :: Int -> Bool

toBool 1

= True

toBool 0

= False

convert :: [Int] -> [Bool] convert xs = map toBool xs

381

382

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 a(n+1) = (am)n+1. Transform the left-hand side into the right-hand side using algebra: a(n+1) = a(m×n)+m = am×n × am = (using the induction hypothesis) (am)n × am = (am)n+1. Therefore am×n = (am)n → a(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

388

APPENDIX C. SOLUTIONS TO SELECTED EXERCISES

Induction case. Assume the hypothesis

n+1

i=1 fib i

n

= i=1 fib i + fib (n + 1)

= fib (n + 2) 1 + fib (n + 1) = fib (n + 1) + fib (n + 2) 1 = fib (n + 3) 1

= fib (n + 1 + 2) 1

n

fib i = fib (n + 2)

1.

i=1

Thus we have proved that the theorem holds for n = 0, and that if it holds for arbitrary n it also holds for n + 1. Therefore, by induction, the theorem holds for all n in the set of natural numbers.

5.

Proof. Induction over xs. The base case is

 

 

length ([ ]++ys)

{ (++).1

}

= length ys

= 0 + length ys

{ 0 + x = x }

= length [ ] + length ys

{ length.1 }

Assume that length (xs++ys) = length xs +

length ys. The inductive case is

length ((x : xs)++ys)

{ (++).2 }

= length (x : (xs++ys))

= 1 + length (xs++ys)

{ length.2 }

= 1 + (length xs + length ys)

{ hypothesis }

= (1 + length xs) + length ys

{ (+) is associative }

= length (x : xs) + length ys

{ length.2 }

6.

 

 

Proof. Induction over xs. The base case is

 

 

map f ([ ] ++ ys)

{ (++).1

}

= map f ys

= [ ] ++ map f ys

{ (++).1

}

= map f [ ] ++ map f ys

{ map.1 }

For the inductive case, assume map f (xs++ys) = map f xs ++ map f ys. Then

map f ((x : xs) ++ ys)

{ (++).2 }

= map f (x : (xs++ys))

= f x

: map f (xs++ys)

{ map.2 }

= f x

: (map f xs ++ map f ys)

{ hypothesis }

= (f x

: map f xs) ++ map f ys

{ (++).2 }

= map f (x : xs) ++ map f ys

{ map.2 }

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))

Соседние файлы в предмете Дискретная математика