├── .gitignore ├── elm.json ├── src ├── Main.elm ├── Sorting │ ├── InsertionSort.elm │ ├── BubbleSort.elm │ ├── SelectionSort.elm │ └── MergeSort.elm ├── Structures │ └── BinaryTree.elm └── Util.elm ├── DIRECTORY.md ├── LICENSE ├── README.md └── .github └── workflows └── directory_workflow.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # Idea directory 7 | .idea 8 | 9 | ### Elm template 10 | # elm-package generated files 11 | elm-stuff 12 | # elm-repl generated files 13 | repl-temp-* 14 | -------------------------------------------------------------------------------- /elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "src", 5 | "src/Sorting", 6 | "src/Structures" 7 | ], 8 | "elm-version": "0.19.1", 9 | "dependencies": { 10 | "direct": { 11 | "elm/browser": "1.0.1", 12 | "elm/core": "1.0.2", 13 | "elm/html": "1.0.0" 14 | }, 15 | "indirect": { 16 | "elm/json": "1.1.3", 17 | "elm/time": "1.0.0", 18 | "elm/url": "1.0.0", 19 | "elm/virtual-dom": "1.0.2" 20 | } 21 | }, 22 | "test-dependencies": { 23 | "direct": {}, 24 | "indirect": {} 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Main.elm: -------------------------------------------------------------------------------- 1 | module Main exposing (output) 2 | 3 | import BubbleSort as Bubble 4 | import InsertionSort as Insertion 5 | import MergeSort as Merge 6 | import SelectionSort as Selection 7 | 8 | 9 | output : List String -> String 10 | output args = 11 | let 12 | bubble = 13 | Debug.log "Running Bubble sort " <| Bubble.output [] 14 | 15 | insertion = 16 | Debug.log "Running Insertion sort " <| Insertion.output [] 17 | 18 | selection = 19 | Debug.log "Running Insertion sort " <| Selection.output [] 20 | 21 | merge = 22 | Debug.log "Running Merge sort " <| Merge.output [] 23 | in 24 | "" 25 | -------------------------------------------------------------------------------- /DIRECTORY.md: -------------------------------------------------------------------------------- 1 | # List of all files 2 | 3 | ## Src 4 | * [Main](https://github.com/TheAlgorithms/Elm/blob/master/src/Main.elm) 5 | * Sorting 6 | * [Bubblesort](https://github.com/TheAlgorithms/Elm/blob/master/src/Sorting/BubbleSort.elm) 7 | * [Insertionsort](https://github.com/TheAlgorithms/Elm/blob/master/src/Sorting/InsertionSort.elm) 8 | * [Mergesort](https://github.com/TheAlgorithms/Elm/blob/master/src/Sorting/MergeSort.elm) 9 | * [Selectionsort](https://github.com/TheAlgorithms/Elm/blob/master/src/Sorting/SelectionSort.elm) 10 | * Structures 11 | * [Binarytree](https://github.com/TheAlgorithms/Elm/blob/master/src/Structures/BinaryTree.elm) 12 | * [Util](https://github.com/TheAlgorithms/Elm/blob/master/src/Util.elm) 13 | -------------------------------------------------------------------------------- /src/Sorting/InsertionSort.elm: -------------------------------------------------------------------------------- 1 | module InsertionSort exposing (output) 2 | 3 | import List exposing (head, singleton, tail) 4 | import Util 5 | 6 | 7 | insertionSort : List Int -> List Int 8 | insertionSort inputList = 9 | let 10 | insert : Int -> List Int -> List Int 11 | insert newEle sorted = 12 | case sorted of 13 | [] -> 14 | singleton newEle 15 | 16 | sortedHead :: sortedTail -> 17 | if sortedHead < newEle then 18 | sortedHead :: insert newEle sortedTail 19 | 20 | else 21 | newEle :: sorted 22 | in 23 | case inputList of 24 | [] -> 25 | [] 26 | 27 | head :: tail -> 28 | insert head <| insertionSort tail 29 | 30 | 31 | output : List String -> String 32 | output args = 33 | Util.sortingOutputDef args insertionSort 34 | -------------------------------------------------------------------------------- /src/Sorting/BubbleSort.elm: -------------------------------------------------------------------------------- 1 | module BubbleSort exposing (output) 2 | 3 | import Util exposing (sortingOutputDef) 4 | 5 | 6 | bubbleSort : List Int -> List Int 7 | bubbleSort inputList = 8 | let 9 | bubble : List Int -> List Int -> List Int -> List Int 10 | bubble source tempList result = 11 | case source of 12 | h1 :: h2 :: tail -> 13 | if h1 < h2 then 14 | bubble (h2 :: tail) (h1 :: tempList) result 15 | 16 | else 17 | bubble (h1 :: tail) (h2 :: tempList) result 18 | 19 | h1 :: [] -> 20 | sort tempList (h1 :: result) 21 | 22 | [] -> 23 | result 24 | 25 | sort : List Int -> List Int -> List Int 26 | sort source result = 27 | if List.isEmpty source then 28 | result 29 | 30 | else 31 | bubble source [] result 32 | in 33 | sort inputList [] 34 | 35 | 36 | output : List String -> String 37 | output args = 38 | sortingOutputDef args bubbleSort 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 The Algorithms 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Sorting/SelectionSort.elm: -------------------------------------------------------------------------------- 1 | module SelectionSort exposing (output) 2 | 3 | import Util 4 | 5 | 6 | getNextMinVal : Int -> List Int -> ( Int, List Int ) 7 | getNextMinVal comparedWith lst = 8 | case lst of 9 | [] -> 10 | ( comparedWith, [] ) 11 | 12 | h :: tail -> 13 | if comparedWith < h then 14 | let 15 | recRes = 16 | getNextMinVal comparedWith tail 17 | in 18 | ( Tuple.first recRes, h :: Tuple.second recRes ) 19 | 20 | else 21 | let 22 | recRes = 23 | getNextMinVal h tail 24 | in 25 | ( Tuple.first recRes, comparedWith :: Tuple.second recRes ) 26 | 27 | 28 | selectionSort : List Int -> List Int 29 | selectionSort unsorted = 30 | case unsorted of 31 | [] -> 32 | [] 33 | 34 | h :: [] -> 35 | [ h ] 36 | 37 | h :: tail -> 38 | let 39 | firstSorted = 40 | getNextMinVal h tail 41 | in 42 | Tuple.first firstSorted :: selectionSort (Tuple.second firstSorted) 43 | 44 | 45 | output : List String -> String 46 | output args = 47 | Util.sortingOutputDef args selectionSort 48 | -------------------------------------------------------------------------------- /src/Sorting/MergeSort.elm: -------------------------------------------------------------------------------- 1 | module MergeSort exposing (..) 2 | 3 | import List exposing (drop, length, take) 4 | import Util exposing (sortingOutputDef) 5 | 6 | 7 | insertInto : Int -> List Int -> List Int -> List Int 8 | insertInto toInsert lesserList greaterList = 9 | case greaterList of 10 | [] -> 11 | lesserList ++ [ toInsert ] 12 | 13 | gHead :: gTail -> 14 | if toInsert > gHead then 15 | insertInto toInsert (lesserList ++ [ gHead ]) gTail 16 | 17 | else 18 | lesserList ++ [ toInsert ] ++ greaterList 19 | 20 | 21 | mergeJoin : List Int -> List Int -> List Int 22 | mergeJoin firstHalf secondHalf = 23 | case firstHalf of 24 | [] -> 25 | secondHalf 26 | 27 | fHead :: fTail -> 28 | mergeJoin fTail (insertInto fHead [] secondHalf) 29 | 30 | 31 | mergeSort : List Int -> List Int 32 | mergeSort inputList = 33 | case inputList of 34 | [] -> 35 | [] 36 | 37 | head :: [] -> 38 | [ head ] 39 | 40 | _ -> 41 | mergeJoin (mergeSort <| take (length inputList // 2) inputList) 42 | (mergeSort <| drop (length inputList // 2) inputList) 43 | 44 | 45 | output : List String -> String 46 | output args = 47 | sortingOutputDef args mergeSort 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Algorithms - Elm 2 | 3 | [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/TheAlgorithms)   4 | 5 | ### All algorithms implemented in Elm (for education) 6 | 7 | These implementations are for learning purposes. They may be less efficient than the implementations in the Elm standard library. 8 | 9 | ## How to run 10 | 11 | ### Install run-elm 12 | Run the following to install [run-elm](https://github.com/jfairbank/run-elm) 13 | ```shell script 14 | $ npm install -g run-elm 15 | ``` 16 | 17 | ### Execute Elm 18 | 19 | Every ELM file has default run in it, and can just be executed using run-elm 20 | 21 | ```shell script 22 | $ run-elm src/Sorting/BubbleSort.elm 23 | Sorting List: [4,23,6,78,1,54,231,9,12] 24 | 1,4,6,9,12,23,54,78,231 25 | ``` 26 | 27 | Some files also have option to take arguments as input 28 | 29 | ```shell script 30 | $ run-elm src/Sorting/BubbleSort.elm 23 45 76 34 65 98 31 | Sorting List: [23,45,76,34,65,98] 32 | 23,34,45,65,76,98 33 | ``` 34 | 35 | **OR** 36 | 37 | if you want to run all the programs with default arguments 38 | ```shell script 39 | $ run-elm src/Main.elm 40 | Sorting List: [4,23,6,78,1,54,231,9,12] 41 | Running Insertion sort: "1,4,6,9,12,23,54,78,231" 42 | Sorting List: [4,23,6,78,1,54,231,9,12] 43 | Running Bubble sort: "1,4,6,9,12,23,54,78,231" 44 | ``` 45 | 46 | ## Community Channel 47 | 48 | We're on [Gitter](https://gitter.im/TheAlgorithms)! Please join us. 49 | 50 | -------------------------------------------------------------------------------- /src/Structures/BinaryTree.elm: -------------------------------------------------------------------------------- 1 | module BinaryTree exposing (..) 2 | 3 | type BTree a = Nil | Node a (BTree a) (BTree a) 4 | 5 | insert : comparable -> BTree comparable -> BTree comparable 6 | insert n tree = 7 | case tree of 8 | Nil -> Node n Nil Nil 9 | Node root left right -> 10 | if n > root then 11 | Node root left (insert n right) 12 | else if n < root then 13 | Node root (insert n left) right 14 | else 15 | tree 16 | 17 | fold : (b -> a -> b -> b) -> b -> BTree a -> b 18 | fold caseNode caseNil tree = 19 | let rec = fold caseNode caseNil 20 | in 21 | case tree of 22 | Nil -> caseNil 23 | Node root leftTree rightTree -> caseNode (rec leftTree) root (rec rightTree) 24 | 25 | map : (a -> b) -> BTree a -> BTree b 26 | map f = fold (\leftTree root rightTree -> Node (f root) leftTree rightTree) (Nil) 27 | 28 | contains : comparable -> BTree comparable -> Bool 29 | contains n = fold (\lr r rr -> r == n || lr || rr) (False) 30 | 31 | sum : BTree number -> number 32 | sum tree = fold (\recleft root recright -> root + recleft + recright) (0) tree 33 | 34 | inorder : BTree a -> List a 35 | inorder tree = fold (\recleft root recright -> recleft ++ (root::recright)) ([]) tree 36 | 37 | preorder : BTree a -> List a 38 | preorder tree = fold (\recleft root recright -> root :: recleft ++ recright) ([]) tree 39 | 40 | postorder : BTree a -> List a 41 | postorder tree = fold (\recleft root recright -> recleft ++ recright ++ [root]) ([]) tree 42 | -------------------------------------------------------------------------------- /src/Util.elm: -------------------------------------------------------------------------------- 1 | module Util exposing (..) 2 | 3 | import Array exposing (Array) 4 | import List exposing (length) 5 | import BinaryTree as Tree 6 | import Char exposing (toLower) 7 | 8 | argsToArray : List String -> Array Int 9 | argsToArray input = 10 | Array.fromList <| argsToList input 11 | 12 | 13 | argsToList : List String -> List Int 14 | argsToList input = 15 | List.map (\each -> Maybe.withDefault -1 <| String.toInt each) input 16 | 17 | 18 | arrayToString : Array Int -> String 19 | arrayToString input = 20 | listToString <| Array.toList input 21 | 22 | 23 | listToString : List Int -> String 24 | listToString input = 25 | String.join "," <| List.map String.fromInt input 26 | 27 | 28 | sortingOutputDef : List String -> (List Int -> List Int) -> String 29 | sortingOutputDef args sorting_algo = 30 | let 31 | log argList = 32 | Debug.log "Sorting List " argList 33 | 34 | defaultList = 35 | [ 4, 23, 6, 78, 1, 54, 231, 9, 12 ] 36 | in 37 | case length args of 38 | 0 -> 39 | listToString <| sorting_algo <| log <| defaultList 40 | 41 | 1 -> 42 | listToString <| sorting_algo <| log <| defaultList 43 | 44 | _ -> 45 | listToString <| sorting_algo <| log <| argsToList args 46 | 47 | 48 | treeExample : List String -> String 49 | treeExample args = 50 | let 51 | log argList s = 52 | Debug.log ("Displaying Tree with traverse " ++ s) argList 53 | defaultTree = Tree.insert 4 (Tree.Node 2 (Tree.Node 1 Tree.Nil Tree.Nil) (Tree.Node 3 Tree.Nil Tree.Nil)) 54 | in 55 | case (List.head args) of 56 | Just s -> case (String.toLower s) of 57 | "inorder" -> listToString <| Tree.inorder <| log defaultTree <| s 58 | "preorder" -> listToString <| Tree.preorder <| log defaultTree <| s 59 | "postorder" -> listToString <| Tree.postorder <| log defaultTree <| s 60 | _ -> "Non existing algorithm, select from: inorder, preorder, postorder." 61 | Nothing -> "Provide a display algorithm: inorder, preorder, postorder." 62 | -------------------------------------------------------------------------------- /.github/workflows/directory_workflow.yml: -------------------------------------------------------------------------------- 1 | name: directory_md 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | MainSequence: 6 | name: DIRECTORY.md 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 # v2 is broken for git diff 10 | - uses: actions/setup-python@v2 11 | - name: Setup Git Specs 12 | run: | 13 | git config --global user.name github-actions 14 | git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com' 15 | git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY 16 | - name: Update DIRECTORY.md 17 | shell: python 18 | run: | 19 | import os 20 | from typing import Iterator 21 | URL_BASE = "https://github.com/TheAlgorithms/Elm/blob/master" 22 | g_output = [] 23 | def good_filepaths(top_dir: str = ".") -> Iterator[str]: 24 | fs_exts = tuple(".elm".split()) 25 | for dirpath, dirnames, filenames in os.walk(top_dir): 26 | dirnames[:] = [d for d in dirnames if d[0] not in "._"] 27 | for filename in filenames: 28 | if os.path.splitext(filename)[1].lower() in fs_exts: 29 | yield os.path.join(dirpath, filename).lstrip("./") 30 | def md_prefix(i): 31 | return f"{i * ' '}*" if i else "\n##" 32 | def print_path(old_path: str, new_path: str) -> str: 33 | global g_output 34 | old_parts = old_path.split(os.sep) 35 | for i, new_part in enumerate(new_path.split(os.sep)): 36 | if i + 1 > len(old_parts) or old_parts[i] != new_part: 37 | if new_part: 38 | g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ').title()}") 39 | return new_path 40 | def build_directory_md(top_dir: str = ".") -> str: 41 | global g_output 42 | old_path = "" 43 | for filepath in sorted(good_filepaths(), key=str.lower): 44 | filepath, filename = os.path.split(filepath) 45 | if filepath != old_path: 46 | old_path = print_path(old_path, filepath) 47 | indent = (filepath.count(os.sep) + 1) if filepath else 0 48 | url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20") 49 | filename = os.path.splitext(filename.replace("_", " ").title())[0] 50 | g_output.append(f"{md_prefix(indent)} [{filename}]({url})") 51 | return "# List of all files\n" + "\n".join(g_output) 52 | with open("DIRECTORY.md", "w") as out_file: 53 | out_file.write(build_directory_md(".") + "\n") 54 | - name: Commit DIRECTORY.md 55 | run: | 56 | git commit -m "updating DIRECTORY.md" DIRECTORY.md || true 57 | git diff DIRECTORY.md 58 | git push --force origin HEAD:$GITHUB_REF || true 59 | --------------------------------------------------------------------------------