Skip to content

Commit b69f7db

Browse files
author
Artur Parowicz
committed
Migrated project to stack
1 parent bc181f2 commit b69f7db

File tree

17 files changed

+477
-0
lines changed

17 files changed

+477
-0
lines changed

Haskell.cabal

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
cabal-version: 1.12
2+
3+
-- This file has been generated from package.yaml by hpack version 0.31.2.
4+
--
5+
-- see: https://github.com/sol/hpack
6+
--
7+
-- hash: 9bef5ebd7df69b30ebfe5fcb2aa3c8e73a2285caeebe8057db70cdfaf8471a5a
8+
9+
name: Haskell
10+
version: 0.0.1
11+
homepage: https://github.com/TheAlgorithms/Haskell#readme
12+
bug-reports: https://github.com/TheAlgorithms/Haskell/issues
13+
author: TheAlgorithms
14+
maintainer: TheAlgorithms
15+
license: MIT
16+
license-file: LICENSE
17+
build-type: Simple
18+
extra-source-files:
19+
LICENSE
20+
package.yaml
21+
README.md
22+
stack.yaml
23+
24+
source-repository head
25+
type: git
26+
location: https://github.com/TheAlgorithms/Haskell
27+
28+
library
29+
exposed-modules:
30+
BinaryTree.BinarySearchTree
31+
BinaryTree.BinaryTree
32+
HaskellAlgorithms
33+
ProjectEuler.Problem1.Problem1
34+
ProjectEuler.Problem2.Problem2
35+
Robotics.ComplementaryFilter.CompFilt
36+
Robotics.ComplementaryFilter.TestData
37+
Sorts.BubbleSort
38+
Sorts.MergeSort
39+
Sorts.QuickSort
40+
other-modules:
41+
Paths_Haskell
42+
hs-source-dirs:
43+
src
44+
ghc-options: -Wall
45+
build-depends:
46+
base
47+
default-language: Haskell2010
48+
49+
test-suite Haskell-test-suite
50+
type: exitcode-stdio-1.0
51+
main-is: Spec.hs
52+
other-modules:
53+
SortSpecs.BubbleSortSpec
54+
hs-source-dirs:
55+
specs
56+
ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N
57+
build-depends:
58+
Haskell
59+
, QuickCheck
60+
, base
61+
, hspec
62+
default-language: Haskell2010

Setup.hs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

package.yaml

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# This YAML file describes your package. Stack will automatically generate a
2+
# Cabal file when you run `stack build`. See the hpack website for help with
3+
# this file: <https://github.com/sol/hpack>.
4+
name: Haskell
5+
version: '0.0.1'
6+
github: "TheAlgorithms/Haskell"
7+
license: MIT
8+
author: "TheAlgorithms"
9+
maintainer: "TheAlgorithms"
10+
11+
extra-source-files:
12+
- LICENSE
13+
- package.yaml
14+
- README.md
15+
- stack.yaml
16+
17+
ghc-options: -Wall
18+
19+
library:
20+
dependencies:
21+
- base
22+
source-dirs: src
23+
24+
tests:
25+
Haskell-test-suite:
26+
source-dirs: specs
27+
main: Spec.hs
28+
dependencies:
29+
- base
30+
- Haskell
31+
- hspec
32+
- QuickCheck
33+
ghc-options:
34+
- -rtsopts
35+
- -threaded
36+
- -with-rtsopts=-N

specs/SortSpecs/BubbleSortSpec.hs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{-# LANGUAGE ScopedTypeVariables #-}
2+
module SortSpecs.BubbleSortSpec where
3+
4+
import Test.Hspec
5+
import Test.QuickCheck
6+
import Sorts.BubbleSort
7+
8+
spec :: Spec
9+
spec = do
10+
describe "bubbleSort" $ do
11+
it "returns empty list when sorting empty list" $ property $
12+
bubbleSort [] == ([] :: [Int])
13+
14+
it "returns same list if input was already sorted" $ property $
15+
\(x :: [Int]) -> bubbleSort x == (bubbleSort . bubbleSort $ x)
16+
17+
it "returns list with smallest element at 0" $ property $
18+
forAll (listOf1 arbitrary) $
19+
\(x :: [Int]) -> let sortedList = bubbleSort x
20+
in head sortedList == minimum sortedList
21+
22+
it "returns list with largest element at the end" $ property $
23+
forAll (listOf1 arbitrary) $
24+
\(x :: [Int]) -> let sortedList = bubbleSort x
25+
in last sortedList == maximum sortedList
26+
27+
it "handle simple sorting of static value" $
28+
let (unsortedList :: [Int]) = [4, 2, 1, 7, 3]
29+
(sortedList :: [Int]) = [1, 2, 3, 4, 7]
30+
in bubbleSort unsortedList == sortedList

specs/Spec.hs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
2+
3+
module Spec where

src/BinaryTree/BinarySearchTree.hs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
module BinaryTree.BinarySearchTree where
2+
3+
data BTree a = Empty | Node a (BTree a) (BTree a) deriving (Show)
4+
data Side = LeftSide | RightSide deriving (Eq, Show)
5+
6+
-- Function to get the data associated with the node.
7+
nodeKey :: BTree a -> Maybe a
8+
nodeKey Empty = Nothing
9+
nodeKey (Node x _ _) = Just x
10+
11+
-- Perform inorder walk of the binary search tree.
12+
-- Cormen, Thomas H., et al. Introduction to algorithms. pg. 288, MIT press, 2009.
13+
inorderWalk :: (Eq a, Ord a) => BTree a -> [a]
14+
inorderWalk Empty = []
15+
inorderWalk (Node x l r) = (inorderWalk l) ++ [x] ++ (inorderWalk r)
16+
17+
-- Function to insert a value into the tree. Returns the new tree.
18+
-- Cormen, Thomas H., et al. Introduction to algorithms. pg. 294, MIT press, 2009.
19+
bstInsert :: (Eq a, Ord a) => BTree a -> a -> BTree a
20+
bstInsert Empty z = Node z Empty Empty
21+
bstInsert (Node x l r) z
22+
| z < x = Node x (bstInsert l z) r
23+
| otherwise = Node x l (bstInsert r z)
24+
25+
-- Function to find the maximum value in the BST.
26+
bstMax :: (Eq a, Ord a) => BTree a -> Maybe a
27+
bstMax Empty = Nothing
28+
bstMax (Node x Empty Empty) = Just x
29+
bstMax (Node x l Empty) = Just x
30+
bstMax (Node x l r) = bstMax r
31+
32+
-- Function to find the minimum value in the BST.
33+
bstMin :: (Eq a, Ord a) => BTree a -> Maybe a
34+
bstMin Empty = Nothing
35+
bstMin (Node x Empty Empty) = Just x
36+
bstMin (Node x Empty r) = Just x
37+
bstMin (Node x l r) = bstMin l
38+
39+
-- Function to build BST from a list of values using a fold.
40+
bstFromList :: (Eq a, Ord a) => [a] -> BTree a
41+
bstFromList [] = Empty
42+
bstFromList lst = foldl (\tree elem -> bstInsert tree elem) Empty lst
43+
44+
sampleTree = bstFromList [10, 7, 3, 11, 12, 1, 3, 2]
45+
46+
-- Function to check if a given tree is a Binary Search Tree.
47+
-- Property:
48+
-- x is a node in the BST. If y is a node in the left subtree of x then
49+
-- y.key <= x.key. If y is a node in the right subtree of x then
50+
-- y.key >= x.key.
51+
-- Cormen, Thomas H., et al. Introduction to algorithms. MIT press, 2009.
52+
isBST :: (Ord a, Eq a) => BTree a -> Bool
53+
isBST Empty = True
54+
isBST (Node x Empty Empty) = True
55+
isBST (Node x Empty r) = (x < (nkey r)) && (isBST r) where nkey = (\(Node n ll rr) -> n)
56+
isBST (Node x l Empty) = (x >= (nkey l)) && (isBST l) where nkey = (\(Node n ll rr) -> n)
57+
isBST (Node x l r) = (x >= (nkey l)) && (x < (nkey r)) && (isBST l) && (isBST r) where nkey = (\(Node n ll rr) -> n)

src/BinaryTree/BinaryTree.hs

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module BinaryTree.BinaryTree where
2+
3+
import qualified Data.List as L
4+
5+
data BTree a = Empty | Node a (BTree a) (BTree a) deriving (Show)
6+
data Side = LeftSide | RightSide deriving (Eq, Show)
7+
8+
-- Get subtree on specified side
9+
getSubTree :: Side -> BTree a -> BTree a
10+
getSubTree _ Empty = Empty
11+
getSubTree s (Node _ l r) = if s == LeftSide then l else r
12+
13+
-- Get Left Subtree
14+
getLeftTree :: BTree a -> BTree a
15+
getLeftTree Empty = Empty
16+
getLeftTree (Node _ l _) = l
17+
18+
-- Get Right Subtree
19+
getRightTree :: BTree a -> BTree a
20+
getRightTree Empty = Empty
21+
getRightTree (Node _ _ r) = r
22+
23+
-- Get string representation of node Data
24+
nodeShow :: (Show a) => BTree a -> String
25+
nodeShow Empty = ""
26+
nodeShow (Node val _ _) = show val
27+
28+
-- Depth first traversal
29+
dfsList :: BTree a -> [a]
30+
dfsList Empty = []
31+
dfsList (Node n l r) = [n] ++ (dfsList l) ++ (dfsList r)
32+
33+
-- Breadth first traversal.
34+
bfsList :: BTree a -> [a]
35+
bfsList Empty = []
36+
bfsList t = concat $ takeWhile (\l -> (length l) > 0) [getLevel i 0 t | i <- [0..]]
37+
38+
-- Get all nodes from a single level in the tree.
39+
getLevel :: (Num b, Enum b, Eq b) => b -> b -> BTree a -> [a]
40+
getLevel _ _ Empty = []
41+
getLevel 0 _ (Node n l r) = [n]
42+
getLevel level i (Node n l r)
43+
| i == level = [n]
44+
| otherwise = (getLevel level (i+1) l) ++ (getLevel level (i+1) r)
45+
46+
-- Get a list of lists of nodes in each level
47+
getLevels :: BTree a -> [[a]]
48+
getLevels t = takeWhile (\l -> (length l) > 0) [getLevel i 0 t | i <- [0..]]
49+
50+
-- Get the depth of the tree
51+
getDepth :: BTree a -> Int
52+
getDepth t = length $ getLevels t
53+
54+
-- Generate a Binary Tree from a list of values.
55+
-- Assume list is in breadth first order.
56+
fromList :: [a] -> BTree a
57+
fromList lst = fromListInt 0 lst
58+
-- Internal function to convert list to tree.
59+
fromListInt :: Int -> [a] -> BTree a
60+
fromListInt _ [] = Empty
61+
fromListInt i lst@(x:xs) = Node x (fromListInt (2*i + 1) (drop (i+1) lst))
62+
(fromListInt (2*i + 2) (drop (i+2) lst))
63+
64+
-- Count number of nodes in the tree.
65+
numNodes :: BTree a -> Int
66+
numNodes t = length $ bfsList t
67+
68+
-- Pretty Print a Binary Tree
69+
simplePrint :: (Show a) => BTree a -> String
70+
simplePrint Empty = ""
71+
simplePrint t = (nodeShow t) ++ " " ++ (simplePrint $ getLeftTree t) ++ (simplePrint $ getRightTree t)

src/HaskellAlgorithms.hs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module HaskellAlgorithms
2+
(
3+
module Sorts.BubbleSort
4+
) where
5+
6+
import Sorts.BubbleSort

src/ProjectEuler/Problem1/Problem1.hs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module ProjectEuler.Problem1.Problem1 where
2+
3+
solList = filter (\n -> (rem n 5 == 0) || (rem n 3 == 0)) [1..999]
4+
5+
main = do
6+
print $ sum solList

src/ProjectEuler/Problem2/Problem2.hs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module ProjectEuler.Problem2.Problem2 where
2+
3+
fib :: Integer -> [Integer]
4+
fib n
5+
| n < 0 = []
6+
| n == 1 = [0]
7+
| n == 2 = [0, 1]
8+
| otherwise = reverse $ foldl (\acc n -> (sum (take 2 acc)):acc) [1, 0] [3..n]
9+
10+
main = do
11+
print $ sum $ filter even $ takeWhile (<=4000000) (fib 100)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module Robotics.ComplementaryFilter.CompFilt where
2+
3+
import Robotics.ComplementaryFilter.TestData
4+
5+
-- Utility functions to extract X, Y, Z components from 3D vector.
6+
getX :: (a, a, a) -> a
7+
getX (x,_,_) = x
8+
9+
getY :: (a, a, a) -> a
10+
getY (_,y,_) = y
11+
12+
getZ :: (a, a, a) -> a
13+
getZ (_,_,z) = z
14+
15+
-- Extract accel data from list of floats
16+
getAccel :: (RealFloat a) => [a] -> (a, a, a)
17+
getAccel [] = (0, 0, 0)
18+
getAccel s = if length s >= 6
19+
then (s!!0, s!!1, s!!2)
20+
else (0, 0, 0)
21+
22+
-- Extract gyro data from a lsit of floats
23+
getGyro :: (RealFloat a) => [a] -> (a, a, a)
24+
getGyro s = if length s >= 6
25+
then (s!!3, s!!4, s!!5)
26+
else (0, 0, 0)
27+
28+
-- Function to calculate tilt angle from accelerometer reading.
29+
-- By default the tilt measurement is made around the Z axis.
30+
accelTiltAngle :: (RealFloat a) => (a, a, a) -> a
31+
accelTiltAngle (_, y, z) = (atan2 z y)*180.0/pi
32+
33+
34+
-- Complementary filter, uses the scanl pattern.
35+
compFilt :: (RealFloat a) => [a] -> [a] -> a -> a -> [a]
36+
compFilt ωs θ_accs α δt = scanl (\θ (ω, θ_acc) -> α*+ ω*δt) + (1-α)*θ_acc)
37+
(head θ_accs)
38+
(zip ωs θ_accs)
39+
40+
-- Calculate tilts
41+
calcTilt :: (RealFloat a) => [(a, a, a)] -> [(a, a, a)] -> a -> a -> [a]
42+
calcTilt accel gyro α δt = compFilt (map getX gyro) (map accelTiltAngle accel) α δt
43+
44+
main = do
45+
let accels = map getAccel testData
46+
let gyros = map getGyro testData
47+
let tilts = calcTilt accels gyros 0.95 0.01
48+
print tilts

src/Robotics/ComplementaryFilter/TestData.hs

+3
Large diffs are not rendered by default.

src/Sorts/BubbleSort.hs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module Sorts.BubbleSort where
2+
3+
listToSort :: [Int]
4+
listToSort = [13, 2, 3, 14, 17, 4, 1, 5, 16, 12, 9, 10, 15, 8, 7, 11, 18, 19, 6, 20]
5+
6+
7+
-- The bubble sort function
8+
bubbleSort :: (Ord a) => [a] -> [a]
9+
bubbleSort lst = if bpassed == lst then lst
10+
else bubbleSort bpassed
11+
where bpassed = bubblePass lst
12+
13+
-- A single pass of bubble sort
14+
bubblePass :: (Ord a) => [a] -> [a]
15+
bubblePass [] = [] -- Empty list is empty.
16+
bubblePass [x] = [x] -- Singleton list is always trivially sorted.
17+
bubblePass (x1:x2:xs) = if x1 > x2
18+
then [x2] ++ (bubblePass ([x1] ++ xs))
19+
else [x1] ++ (bubblePass ([x2] ++ xs))
20+
21+
main = do
22+
putStrLn $ "Unsorted: " ++ show listToSort
23+
putStrLn $ "Sorted: " ++ show (bubbleSort listToSort)

src/Sorts/MergeSort.hs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module Sorts.MergeSort where
2+
3+
listToSort = [13, 2, 3, 14, 17, 4, 1, 5, 16, 12, 9, 10, 15, 8, 7, 11, 18, 19, 6, 20]
4+
5+
mergeSort :: (Ord a) => [a] -> [a]
6+
mergeSort [] = [] -- Empty list is empty
7+
mergeSort [x] = [x] -- Singleton lists are trivially sorted.
8+
mergeSort [x, y] = [(min x y), (max x y)]
9+
mergeSort lst = merge (mergeSort leftL) (mergeSort rightL)
10+
where leftL = take splitPoint lst
11+
rightL = drop splitPoint lst
12+
splitPoint = (length lst) `div` 2
13+
14+
-- Function to execute a merge of two sorted lists
15+
merge :: (Ord a) => [a] -> [a] -> [a]
16+
merge l1 [] = l1
17+
merge [] l2 = l2
18+
merge lst1@(x:xs) lst2@(y:ys) = if x < y
19+
then x:(merge xs lst2)
20+
else y:(merge lst1 ys)
21+
22+
main = do
23+
putStrLn $ "Unsorted: " ++ show listToSort
24+
putStrLn $ "Sorted: " ++ show (mergeSort listToSort)

0 commit comments

Comments
 (0)