mirror of
https://github.com/iritmaximus/haskell.git
synced 2026-10-12 19:13:39 +03:00
180 lines
5.9 KiB
Haskell
180 lines
5.9 KiB
Haskell
module Set10a where
|
|
|
|
import Data.Char
|
|
|
|
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 cards (strings), and a list
|
|
-- of players (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.
|
|
--
|
|
-- 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
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
-- 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
|