------------------------------------------------------------------------ -- DISTRIBUTION OF SCORES FOR CIS 252 QUIZ 3 -- range: scores -- 0- 1: -- 2- 3: -- 4- 5: 5 -- 6- 7: 6 7 -- 8- 9: 8 8 8 -- 10-11: 10 10 11 11 -- 12-13: 12 12 12 13 -- 14-15: 14 14 14 -- 16-17: 16 17 17 17 -- 18-19: 18 18 18 19 -- 20-21: 20 20 20 21 -- 22-23: 22 -- 24-25: 24 24 25 -- average = 14.9 median = 16 ------------------------------------------------------------------------ -- ANSWERS ------------------------------------------------------------- ------------------------------------------------------------------------ ------------------------------------------------------------------------ -- Question 1 (8 points). -- Buckbeak's Unix home directory /home/bestiary/bbeak contains -- three subdirectories: -- cis252, which contains the text files hw1.hs, lab2.trans, and hw3.hs; -- Mail, which contains several files; and -- misc, which contains the text file ratnests.txt. -- -- For each of the following tasks, assume that Buckbeak starts out in -- his home directory (thus, each task is completely independent of the -- others). What one-line Unix command (possibly involving pipes and -- filters) should he type to do each of the following? -- a. (2 points) Count the number of words in the file ratnests.txt. -- ANSWER: wc -w misc/ratnests.txt -- b. (2 points) Print out all lines in all the files in Mail that -- contain the word ``witherwing''. -- ANSWER: grep "witherwing" Mail/* -- c. (2 points) Find all five-letter words in /usr/dict/words that end -- with the letter 'm', but do **not** contain the letter 'e'. -- ANSWER: grep '^....m$' /usr/dict/words | grep -v 'e' -- d. (2 points) Count the number of words in /usr/dict/words that -- contain both a 'g' and a 'w' (they may appear in either order). -- ANSWER: grep 'g' /usr/dict/words | grep 'w' | wc -w ------------------------------------------------------------------------ -- Question 2 (8 points). -- In the game of Rock, Paper, Scissors, two players use hand gestures -- to "throw" either Rock, Paper, or Scissors. A player wins if her -- throw beats the other player's throw, according to the following -- three rules: -- Paper beats Rock. -- Rock beats Scissors. -- Scissors beats Paper. -- Here is an algebraic type to represent these throws: data Throw = Rock | Paper | Scissors deriving (Eq, Show) -- a. (4 points) Write a function winner :: Throw -> Throw -> Int -- such that (winner th1 th2) -- = 1, if the throw th1 beats th2; -- = 2, if the throw th2 beats th1; and -- = 0, if both throws are the same. -- ANSWER: Here is one way of doing it. winner Scissors Paper = 1 winner Paper Rock = 1 winner Rock Scissors = 1 winner Paper Scissors = 2 winner Rock Paper = 2 winner Scissors Rock = 2 winner _ _ = 0 -- or winner Scissors Paper = 1 winner Paper Rock = 1 winner Rock Scissors = 1 winner t1 t2 | t1==t2 = 0 | otherwise = 2 -- b. (4 points) Write a function score ::[Throw] -> [Throw] -> (Int,Int,Int) -- such that takes two equal-length lists of throws (representing each -- player's series of throws), and returns a triple representing the -- number of games the first player won, the number of games the second -- player won, and the number of ties. For example, -- score [Rock, Rock, Rock, Rock] [Paper, Scissors, Paper, Rock] -- should return -- (1,2,1). -- ANSWER: score [] [] = (0,0,0) score (t:ts) (t':ts') | win==0 = (a,b,c+1) | win==1 = (a+1,b,c) | win==2 = (a,b+1,c) where win = winner t t' (a,b,c) = score ts ts' ------------------------------------------------------------------------ -- Question 3. (9 points) A small pizza shop has recently opened, -- and-until business picks up-they are offering a very limited menu: -- * A pizza with no toppings costs $10.00. -- There are also four optional toppings: pepperoni, onions, ham, -- and a pesto sauce. Each of the first three costs $1.25; the -- pesto sauce costs $1.75. -- * Subs are available for $5.25. -- * A large salad costs $4.50, and a small salad costs $3.25. -- These menu options can be represented with the following Haskell types: data Topping = Pepperoni | Onions | Ham | Pesto data Size = Small | Large data Dressing = Ranch | Greek | Caesar data Order = Pizza [Topping] | Salad Size Dressing | Sub Dressing -- Note the following two things about these type definitions: -- * There is no limit to the number of toppings possible on a pizza: -- for example, (Pizza [Ham, Onions, Ham]) represents a pizza with -- onions and a double-order of ham. -- * None of these types have been declared to belong to the Eq -- class. As a result, you should NOT use == or /= to compare elements -- of any of these types. -- a. (5 points) Write a Haskell function cost :: Order -> Float -- such that (cost order) calculates the cost of order, as indicated by -- the menu. cost (Pizza []) = 10.00 cost (Pizza (Pesto:ts)) = 1.75 + cost (Pizza ts) cost (Pizza (_:ts)) = 1.25 + cost (Pizza ts) cost (Salad Small _) = 3.25 cost (Salad Large _) = 4.50 cost (Sub _) = 5.25 -- or cost' (Pizza ts) = 10.00 + topCost ts cost' (Salad Small _) = 3.25 cost' (Salad Large _) = 4.50 cost' (Sub _) = 5.25 topCost [] = 0.0 topCost (Pesto:ts) = 1.75 + topCost ts topCost (_:ts) = 1.25 + topCost ts -- b. (4 points) In an effort to bring in new customers, the owner has -- decided to run a promotion: anyone who buys more than one order at a -- time will receive the least expensive order free. For example, the -- cost for buying a sub, a pesto pizza, and a large salad will be -- $17.00 (i.e., the large salad is free). Write a Haskell function sale :: [Order] -> Float -- that computes the cost of an entire purchase, under this promotion. -- Hint: Consider using the built-in function -- minimum::(Ord a) => [a] -> a, -- that returns the minimal element in a list of numbers (or other -- ordered types). sale [] = 0.0 sale [ord] = cost ord sale ords = (sum prices) - (minimum prices) where prices = [ cost ord | ord <- ords ]