Skip to content

Commit

Permalink
More solutions.
Browse files Browse the repository at this point in the history
  • Loading branch information
sonatsuer committed Sep 29, 2015
1 parent 07f4482 commit 5b7a22c
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 0 deletions.
18 changes: 18 additions & 0 deletions DList.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module DList where

-- This is a simple difference list module to
-- have constant time concatenation.

newtype DList a = DList { act :: [a] -> [a] }

singleton :: a -> DList a
singleton x = DList { act = \ l -> x : l }

nilD :: DList a
nilD = DList { act = id }

(+++) :: DList a -> DList a -> DList a
l1 +++ l2 = DList { act = act l1 . act l2 }

toList :: DList a -> [a]
toList l = act l []
4 changes: 4 additions & 0 deletions Multiplicity.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Multiplicity where

data MuSi a = Multiple Int a | Single a
deriving Show
9 changes: 9 additions & 0 deletions Problem10.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Problem10 where

import Data.List (group)

-- Problem 10
-- Run-length encoding of a list.

encode :: Eq a => [a] -> [(Int, a)]
encode xss = [(length xs, head xs) | xs <- group xss]
18 changes: 18 additions & 0 deletions Problem11.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Problem11 where

import Problem10 (encode)
import Multiplicity

-- Problem 11
-- Modified run-length encoding.

-- If an element has no duplicates it is simply copied into
-- the result list. Since Haskell lists are homogeneous we
-- have to use a different data type, Multiple-Single lists
-- from the Multiplicity module.

encodeModified :: Eq a => [a] -> [MuSi a]
encodeModified xss = map format (encode xss)
where format (1, x) = Single x
format (n, x) = Multiple n x

14 changes: 14 additions & 0 deletions Problem12.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module Problem12 where

import Multiplicity

-- Problem 12
-- Inverse of encodeModified

decodeModified :: Eq a => [MuSi a] -> [a]
decodeModified [] = []
decodeModified (Multiple n x : xs)
| n == 2 = [x, x] ++ decodeModified xs
| otherwise = [x] ++ decodeModified (Multiple (n - 1) x : xs)
decodeModified (Single x : xs)
= [x] ++ decodeModified xs
9 changes: 9 additions & 0 deletions Problem3.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Problem3 where

-- Problem 3
-- Find the K'th element of a list. The first element in the list is number 1.

elementAt :: [a] -> Int -> a
elementAt [] _ = error "Position does not exist."
elementAt (x : _) 1 = x
elementAt (_ : xs) n = elementAt xs (n - 1)
14 changes: 14 additions & 0 deletions Problem4.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module Problem4 where

-- Problem 4
-- Find the number of elements of a list.

myLength :: [a] -> Int
myLength [] = 0
myLength (x : xs) = 1 + myLength xs


-- Better, using foldr.

myLength2 :: [a] -> Int
myLength2 = foldr (\x y -> 1 + y) 0
26 changes: 26 additions & 0 deletions Problem5.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Problem5 where

import DList

-- Problem 5
-- Reverse a list.


-- This solution uses an explicit accumulation parameter
-- and runs in linear time.

myReverse :: [a] -> [a]
myReverse xs = snd $ auxReverse (xs, [])
where auxReverse ([], bs) = ([], bs)
auxReverse ( a : as, bs) = auxReverse (as, a : bs)


-- This is essentially the same algorithm but hides
-- the acummulation parameter in th Dlist module.
-- It works slightly slower than myReverse but still
-- in linear time.

myReverse2 :: [a] -> [a]
myReverse2 = toList . reversoToDList
where reversoToDList [] = nilD
reversoToDList (x : xs) = reversoToDList xs +++ singleton x
9 changes: 9 additions & 0 deletions Problem6.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Problem6 where

import Problem5 (myReverse)

-- Problem 6
-- Find out whether a list is a palindrome.

isPalindrome :: Eq a => [a] -> Bool
isPalindrome xs = xs == myReverse xs
10 changes: 10 additions & 0 deletions Problem7.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Problem7 where

-- Problem 7
-- Flatten a nested list structure.

data NestedList a = Elem a | List [NestedList a]

flatten :: NestedList a -> [a]
flatten (Elem x) = [x]
flatten (List ls) = concatMap flatten ls
11 changes: 11 additions & 0 deletions Problem8.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Problem8 where

-- Problem 8
-- Eliminate consecutive duplicates of list elements.

compress :: Eq a => [a] -> [a]
compress [] = []
compress [x] = [x]
compress (x1 : x2 : xs) =
if x1 == x2 then rest else x1 : rest where
rest = compress (x2 : xs)
26 changes: 26 additions & 0 deletions Problem9.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Problem9 where

import Data.List (group)

-- Problem 9
-- Pack consecutive duplicates of list elements into sublists.

pack :: Eq a => [a] -> [[a]]
pack [] = []
pack [x] = [[x]]
pack (x1 : x2 : xs)
| x1 == x2 = (x1 : head rest) : tail rest
| otherwise = [x1] : rest
where rest = pack (x2 : xs)


-- Using span.
pack2 :: Eq a => [a] -> [[a]]
pack2 [] = []
pack2 (x : xs) = l : pack2 r
where (l, r) = span (==x) (x : xs)

-- One can also use the built in group function.

pack3 :: Eq a => [a] -> [[a]]
pack3 = group

0 comments on commit 5b7a22c

Please sign in to comment.