Files

186 lines
6.2 KiB
Haskell

module Set10a where
import Data.Char
import Data.List
import Mooc.Todo
------------------------------------------------------------------------------
-- Ex 1: Given a list, produce a new list where each element of the
-- original list repeats twice.
--
-- Make sure your function works with infinite lists.
--
-- Examples:
-- doublify [7,1,6] ==> [7,7,1,1,6,6]
-- take 10 (doublify [0..]) ==> [0,0,1,1,2,2,3,3,4,4]
doublify :: [a] -> [a]
doublify = todo
------------------------------------------------------------------------------
-- Ex 2: Implement the function interleave that takes two lists and
-- produces a new list that takes elements alternatingly from both
-- lists like this:
--
-- interleave [1,2,3] [4,5,6] ==> [1,4,2,5,3,6]
--
-- If one list runs out of elements before the other, just keep adding
-- elements from the other list.
--
-- Make sure your function also works with infinite lists.
--
-- Examples:
-- interleave [1,2,3] [4,5,6] ==> [1,4,2,5,3,6]
-- interleave [1,2] [4,5,6,7] ==> [1,4,2,5,6,7]
-- take 10 (interleave [7,7,7] [1..]) ==> [7,1,7,2,7,3,4,5,6,7]
-- take 10 (interleave [1..] (repeat 0)) ==> [1,0,2,0,3,0,4,0,5,0]
interleave :: [a] -> [a] -> [a]
interleave = todo
------------------------------------------------------------------------------
-- Ex 3: Deal out cards. Given a list of players (strings), and a list
-- of cards (strings), deal out the cards to the players in a cycle.
--
-- Make sure your function works with infinite inputs as well!
--
-- Examples:
-- deal ["Hercule","Ariadne"] ["Ace","Joker","Heart"]
-- ==> [("Ace","Hercule"),("Joker","Ariadne"),("Heart","Hercule")]
-- take 4 (deal ["a","b","c"] (map show [0..]))
-- ==> [("0","a"),("1","b"),("2","c"),("3","a")]
-- deal ("you":(repeat "me")) ["1","2","3","4"]
-- ==> [("1","you"),("2","me"),("3","me"),("4","me")]
--
-- Hint: remember the functions cycle and zip?
deal :: [String] -> [String] -> [(String,String)]
deal = todo
------------------------------------------------------------------------------
-- Ex 4: Compute a running average. Go through a list of Doubles and
-- output a list of averages: the average of the first number, the
-- average of the first two numbers, the first three numbers, and so
-- on.
--
-- Make sure your function works with infinite inputs as well!
--
-- Examples:
-- averages [] ==> []
-- averages [3,2,1] ==> [3.0,2.5,2.0]
-- take 10 (averages [1..]) ==> [1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5]
averages :: [Double] -> [Double]
averages = todo
------------------------------------------------------------------------------
-- Ex 5: Given two lists, xs and ys, and an element z, generate an
-- infinite list that consists of
--
-- * the elements of xs
-- * z
-- * the elements of ys
-- * z
-- * the elements of xs
-- * ... and so on
--
-- Examples:
-- take 20 (alternate "abc" "def" ',') ==> "abc,def,abc,def,abc,"
-- take 10 (alternate [1,2] [3,4,5] 0) ==> [1,2,0,3,4,5,0,1,2,0]
alternate :: [a] -> [a] -> a -> [a]
alternate xs ys z = todo
------------------------------------------------------------------------------
-- Ex 6: Check if the length of a list is at least n. Make sure your
-- function works for infinite inputs.
--
-- Examples:
-- lengthAtLeast 2 [1,2,3] ==> True
-- lengthAtLeast 7 [1,2,3] ==> False
-- lengthAtLeast 10 [0..] ==> True
lengthAtLeast :: Int -> [a] -> Bool
lengthAtLeast = todo
------------------------------------------------------------------------------
-- Ex 7: The function chunks should take in a list, and a number n,
-- and return all sublists of length n of the original list. The
-- sublists should be in the order that they appear in the original
-- list. A sublist means a slice, that is, a list of elements
-- a,b,c,... that occur in the original list next to each other and in
-- the same order.
--
-- Make sure your function works with infinite inputs. The function
-- lengthAtLeast can help with this.
--
-- Examples:
-- chunks 2 [1,2,3,4] ==> [[1,2],[2,3],[3,4]]
-- take 4 (chunks 3 [0..]) ==> [[0,1,2],[1,2,3],[2,3,4],[3,4,5]]
chunks :: Int -> [a] -> [[a]]
chunks = todo
------------------------------------------------------------------------------
-- Ex 8: Define a newtype called IgnoreCase, that wraps a value of
-- type String. Define an `Eq` instance for IgnoreCase so that it
-- compares strings in a case-insensitive way.
--
-- To help the tests, also implement the function
-- ignorecase :: String -> IgnoreCase
--
-- Hint: remember Data.Char.toLower
--
-- Examples:
-- ignorecase "abC" == ignorecase "ABc" ==> True
-- ignorecase "acC" == ignorecase "ABc" ==> False
ignorecase = todo
------------------------------------------------------------------------------
-- Ex 9: Here's the Room type and some helper functions from the
-- course material. Define a cyclic Room structure like this:
--
-- * maze1 has the description "Maze"
-- * The direction "Left" goes to maze2
-- * "Right" goes to maze3
-- * maze2 has the description "Deeper in the maze"
-- * "Left" goes to maze3
-- * "Right" goes to maze1
-- * maze3 has the description "Elsewhere in the maze"
-- * "Left" goes to maze1
-- * "Right" goes to maze2
--
-- The variable maze should point to the room maze1.
--
-- Examples:
-- play maze ["Left","Left","Left"]
-- ==> ["Maze","Deeper in the maze","Elsewhere in the maze","Maze"]
-- play maze ["Right","Right","Right","Right"]
-- ==> ["Maze","Elsewhere in the maze","Deeper in the maze","Maze","Elsewhere in the maze"]
-- play maze ["Left","Left","Right"]
-- ==> ["Maze","Deeper in the maze","Elsewhere in the maze","Deeper in the maze"]
data Room = Room String [(String,Room)]
-- Do not modify describe, move or play. The tests will use the
-- original definitions of describe, move and play regardless of your
-- modifications.
describe :: Room -> String
describe (Room s _) = s
move :: Room -> String -> Maybe Room
move (Room _ directions) direction = lookup direction directions
play :: Room -> [String] -> [String]
play room [] = [describe room]
play room (d:ds) = case move room d of Nothing -> [describe room]
Just r -> describe room : play r ds
maze :: Room
maze = todo