Summary Files Commits Branches @commit @diff @stats
path: root / Year 2 / Functional Programming / 11-Practice-05.01.2023.hs
blob: 1bcb7063de608eb3f727570a6869884c9780f779 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
-- Ex1

type Radius = Double
type Width = Double
type Height = Double
type SideA = Double
type SideB = Double
type SideC = Double
data Shape = Circle Radius | Rectangle Width Height | Triangle SideA SideB SideC
             deriving (Eq, Ord)

instance Show Shape where
    show (Circle r) = "Circle: " ++ show r
    show (Rectangle w h) = "Rectangle: " ++ show w ++ " " ++ show h
    show (Triangle a b c) = "Triangle: " ++ show a ++ " " ++ show b ++ " " ++ show c

-- Ex2

perimeter :: Shape -> Double
perimeter (Circle r) = 2 * pi * r
perimeter (Rectangle w h) = 2 * w + 2 * h
perimeter (Triangle a b c) = a + b + c

area :: Shape -> Double
area (Circle r) = pi * r * r
area (Rectangle w h) = w * h
area (Triangle a b c) = let s = (perimeter (Triangle a b c)) / 2 in sqrt(s * (s - a) * (s - b) * (s - c))

-- Ex3

sumArea :: [Shape] -> Double
sumArea sa = foldr (\s acc -> acc + area s) 0 sa

-- Ex4

data Point = Point2D Double Double | Point3D Double Double Double

instance Eq Point where
    (Point2D x1 y1) == (Point2D x2 y2) = (x1 == x2) && (y1 == y2)
    (Point3D x1 y1 z1) == (Point3D x2 y2 z2) = (x1 == x2) && (y1 == y2) && (z1 == z2)

-- Ex5

distance :: Point -> Point -> Double
distance (Point2D x1 y1) (Point2D x2 y2) = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
distance (Point3D x1 y1 z1) (Point3D x2 y2 z2) = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1))
distance (Point2D _ _) (Point3D _ _ _) = error "Cannot find distance between a 2D and 3D point"
distance (Point3D _ _ _) (Point2D _ _) = error "Cannot find distance between a 2D and 3D point"

-- Ex6

instance Show Point where
    show (Point2D x y) = "Point 2D: " ++ show x ++ " " ++ show y
    show (Point3D x y z) = "Point 3D: " ++ show x ++ " " ++ show y ++ " " ++ show z

getClosestPoint :: [Point] -> Point -> Point
getClosestPoint pa p = foldr (\pc acc -> if (distance p pc) < (distance p acc) then pc else acc) (head pa) (tail pa)

-- Ex7

fstt (a,_,_) = a
sndt (_,a,_) = a

getClosestDistance :: [Point] -> (Double, Point, Point)
getClosestDistance ps = foldr (\pc acc -> foldr (\pc1 acc1 -> if pc == pc1 then acc1 else minVal acc1 (distance pc pc1, pc, pc1)) acc ps) (distance (ps!!0) (ps!!1), ps!!0, ps!!1) ps
    where
        minVal :: (Double, Point, Point) -> (Double, Point, Point) -> (Double, Point, Point)
        minVal va vb
            | fstt va < fstt vb = va
            | otherwise = vb

main:: IO()
main = do
    print(Triangle 0.1 0.2 0.3)
    print(perimeter (Rectangle 1 2))
    print(area (Triangle 4 13 15))
    print(sumArea [Triangle 4 13 15, Rectangle 2 3, Circle 4])
    print((Point3D 1 2 3) == (Point3D 1 2 3))
    print(distance (Point2D 0 0) (Point2D 1 1))
    print(getClosestPoint [Point2D 1 2, Point2D 5 6, Point2D 0.5 10, Point2D 0.1 0.1, Point2D 10 10] (Point2D 0 0))
    print(getClosestDistance [Point2D 0 0, Point2D 103 4, Point2D 7 5, Point2D 0.1 0.1, Point2D 7.1 5.2, Point2D 99 0])