diff --git a/wk3/src/Caesar3.elm b/wk3/src/Caesar3.elm index cdc3631..893a430 100644 --- a/wk3/src/Caesar3.elm +++ b/wk3/src/Caesar3.elm @@ -22,7 +22,7 @@ candidates canaries encryptedText = [] -> [] x :: xs -> - filterList x (bruteGenerator encryptedText accumulatorStart) ++ candidates (List.drop 1 canaries) encryptedText + filterList x (bruteGenerator encryptedText accumulatorStart) ++ candidates xs encryptedText -- The Brute Generator generates all possible decrypted strings from a given start value bruteGenerator: String -> Int -> List (Int, String) @@ -48,11 +48,12 @@ containsText: String -> String -> Bool containsText canary text = if String.left (String.length canary) text == canary then True - -- Necessary to prevent a RangeError: Maximum call stack exceeded - else if String.length text == 0 then - False - else - containsText canary (String.dropLeft 1 text) + else + case String.uncons text of + Nothing -> + False + Just (_, tail) -> + containsText canary tail -- Tests testContainsText: Bool diff --git a/wk4/elm.json b/wk4/elm.json new file mode 100644 index 0000000..ce2a08d --- /dev/null +++ b/wk4/elm.json @@ -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": {} + } +} diff --git a/wk4/src/3x2-graph.png b/wk4/src/3x2-graph.png new file mode 100644 index 0000000..c57d7da Binary files /dev/null and b/wk4/src/3x2-graph.png differ diff --git a/wk4/src/Modelling1.elm b/wk4/src/Modelling1.elm new file mode 100644 index 0000000..df942d7 --- /dev/null +++ b/wk4/src/Modelling1.elm @@ -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] \ No newline at end of file diff --git a/wk4/src/Sorting.elm b/wk4/src/Sorting.elm new file mode 100644 index 0000000..d60249a --- /dev/null +++ b/wk4/src/Sorting.elm @@ -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] \ No newline at end of file diff --git a/wk4/src/tests.png b/wk4/src/tests.png new file mode 100644 index 0000000..409557b Binary files /dev/null and b/wk4/src/tests.png differ