wk4: MergeSort, FuncModelling

Co-authored-by: KaloyanStoykov <KaloyanStoykov@users.noreply.github.com>
This commit is contained in:
Dimitar Byalkov
2024-03-15 22:28:32 +01:00
parent 8006690958
commit 8eb9c65aa6
6 changed files with 203 additions and 6 deletions

24
wk4/elm.json Normal file
View File

@@ -0,0 +1,24 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.3"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

BIN
wk4/src/3x2-graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

114
wk4/src/Modelling1.elm Normal file
View File

@@ -0,0 +1,114 @@
module Modelling1 exposing (..)
{-
Modelling Math Functions (part 1)
Dimitar Byalkov and Kaloyan Stoykov
-}
type Function
= Poly Function Int
| Mult Function Function
| Div Function Function
| Plus Function Function
| Minus Function Function
| Const Int
| X
print: Function -> String
print f =
case f of
X ->
"x"
Const val ->
String.fromInt val
Poly func val ->
"(" ++ print func ++ " ^ " ++ String.fromInt val ++ ")"
Mult func1 func2 ->
"(" ++ print func1 ++ " * " ++ print func2 ++ ")"
Div func1 func2 ->
"(" ++ print func1 ++ " / " ++ print func2 ++ ")"
Plus func1 func2 ->
"(" ++ print func1 ++ " + " ++ print func2 ++ ")"
Minus func1 func2 ->
"(" ++ print func1 ++ " - " ++ print func2 ++ ")"
eval: Float -> Function -> Float
eval num f =
case f of
X ->
num
Const val ->
toFloat val
Poly func val ->
eval num func ^ (toFloat val)
Mult func1 func2 ->
eval num func1 * eval num func2
Div func1 func2 ->
eval num func1 / eval num func2
Plus func1 func2 ->
eval num func1 + eval num func2
Minus func1 func2 ->
eval num func1 - eval num func2
-- Graph line drawing function
graphLine: Function -> Int -> Int -> Int -> String
graphLine func x ymin ymax =
let
-- value of f(x)
funcValue = round (eval (toFloat x) func)
-- number of points on the line
ySpan = abs ymin + abs ymax
in
-- Check if the value of f(x) is in the specified range
if (funcValue > ymin) && (funcValue < ymax) then
stringFill (funcValue - ymin) "*" ++ stringFill (ySpan - (funcValue - ymin)) "-"
else if (funcValue > ymin) then
stringFill ySpan "*"
else
stringFill ySpan "-"
-- Recursive function to create a string of specified characters with a given length
stringFill: Int -> String -> String
stringFill n sym =
if (n <= 0) then
""
else
sym ++ stringFill (n - 1) sym
-- xmin < xmax; ymin < ymax
graph: Function -> Int -> Int -> Int -> Int -> String
graph func xmin xmax ymin ymax =
-- Check if range is not possible
if xmin > xmax || ymin > ymax then
"Error: Range is negative"
else if xmin == xmax then
graphLine func xmin ymin ymax
else
graphLine func xmin ymin ymax ++ "\n" ++ graph func (xmin + 1) xmax ymin ymax
testPrint: Bool
testPrint = print (Plus (Mult (Plus (Const 3) X) (Minus X (Poly X 5))) (Const 2)) == "(((3 + x) * (x - (x ^ 5))) + 2)"
testEval: Bool
testEval = eval 2 (Plus (Mult (Plus (Const 3) X) (Minus X (Poly X 5))) (Const 2)) == -148
testGraph1: Bool
testGraph1 = graph (Plus (Minus (Poly (Minus (Div X (Const 5)) (Const 1)) 4) (Poly (Plus (Div X (Const -2)) (Const 2)) 2)) (Const 6)) -10 20 -10 10 ==
"********************\n********************\n********************\n*******************-\n**************------\n************--------\n**********----------\n**********----------\n***********---------\n************--------\n*************-------\n**************------\n***************-----\n****************----\n****************----\n****************----\n***************-----\n**************------\n************--------\n**********----------\n********------------\n******--------------\n****----------------\n**------------------\n*-------------------\n**------------------\n***-----------------\n*******-------------\n*************-------\n********************\n********************"
-- for reference 3x2-graph.png
testGraph2: Bool
testGraph2 = graph (Mult (Const 3) (Poly X 2)) -5 5 -1 10 == "***********\n***********\n***********\n***********\n****-------\n*----------\n****-------\n***********\n***********\n***********\n***********"
testEmptyParams: Bool
testEmptyParams = graph (Mult (Const 3) (Poly X 2)) 0 0 0 0 == ""
testSingleLine: Bool
testSingleLine = graph (Mult (Const 3) (Poly X 2)) 1 1 -1 10 == "****-------"
testInvalidArgs: Bool
testInvalidArgs = graph X 2 1 2 1 == "Error: Range is negative"
testAllGraphs : List Bool
testAllGraphs = [testGraph1, testGraph2, testEmptyParams, testSingleLine, testInvalidArgs]

58
wk4/src/Sorting.elm Normal file
View File

@@ -0,0 +1,58 @@
module Sorting exposing (..)
{-
Merge Sort
Dimitar Byalkov and Kaloyan Stoykov
-}
msort: List comparable -> List comparable
msort myList =
case myList of
[] ->
[]
[x] ->
[x]
_ ->
let
mid = List.length myList // 2
left = List.take mid myList
right = List.drop mid myList
in
merge (msort left) (msort right)
merge: List comparable -> List comparable -> List comparable
merge listOne listTwo =
case (listOne, listTwo) of
([], []) ->
[]
(x, []) ->
x
([], y) ->
y
(x :: xs, y :: ys) ->
if x < y then
x :: merge xs listTwo
else
y :: merge listOne ys
-- Tests
testMergeSortOdd: Bool
testMergeSortOdd = msort [9,8,4,5,0,8,2,3,4] == [0,2,3,4,4,5,8,8,9]
testMergeSortEven: Bool
testMergeSortEven = msort [2,3,0,9,4,8,0,4] == [0,0,2,3,4,4,8,9]
testMergeSortEmpty: Bool
testMergeSortEmpty = msort [] == []
testMergeSort1: Bool
testMergeSort1 = msort [6] == [6]
testMergeSort2: Bool
testMergeSort2 = msort [8,2] == [2,8]
testMergeSortPreSorted: Bool
testMergeSortPreSorted = msort [1,2,3,4,5] == [1,2,3,4,5]
testAllMergeSort: List Bool
testAllMergeSort = [testMergeSortOdd, testMergeSortEven, testMergeSortEmpty, testMergeSort1, testMergeSort2, testMergeSortPreSorted]

BIN
wk4/src/tests.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB