[
  {
    "path": ".github/workflows/.stale.yml",
    "content": "# Configuration for probot-stale - https://github.com/probot/stale\n\n# Number of days of inactivity before an Issue or Pull Request becomes stale\ndaysUntilStale: 30\n\n# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.\n# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.\ndaysUntilClose: 7\n\n# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)\nonlyLabels: []\n\n# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable\nexemptLabels:\n  - \"Status: on hold\"\n\n# Set to true to ignore issues in a project (defaults to false)\nexemptProjects: false\n\n# Set to true to ignore issues in a milestone (defaults to false)\nexemptMilestones: false\n\n# Set to true to ignore issues with an assignee (defaults to false)\nexemptAssignees: false\n\n# Label to use when marking as stale\nstaleLabel: stale\n\n# Comment to post when removing the stale label.\n# unmarkComment: >\n#   Your comment here.\n\n# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':\npulls:\n  # Comment to post when marking as stale. Set to `false` to disable\n  markComment: >\n    This pull request has been automatically marked as stale because it has not had\n    recent activity. It will be closed if no further activity occurs. Thank you\n    for your contributions.\n  # Comment to post when closing a stale Pull Request.\n  closeComment: >\n    Please reopen this pull request once you commit the changes requested\n    or make improvements on the code. If this is not the case and you need\n    some help, feel free to seek help from our [Gitter](https://gitter.im/TheAlgorithms)\n    or ping one of the reviewers. Thank you for your contributions!\nissues:\n  # Comment to post when marking as stale. Set to `false` to disable\n  markComment: >\n    This issue has been automatically marked as stale because it has not had\n    recent activity. It will be closed if no further activity occurs. Thank you\n    for your contributions.\n  # Comment to post when closing a stale Issue.\n  closeComment: >\n    Please reopen this issue once you add more information and updates here.\n    If this is not the case and you need some help, feel free to seek help\n    from our [Gitter](https://gitter.im/TheAlgorithms) or ping one of the\n    reviewers. Thank you for your contributions!\n"
  },
  {
    "path": ".github/workflows/directory_workflow.yml",
    "content": "name: directory_md\non: [push, pull_request]\n\njobs:\n  MainSequence:\n    name: DIRECTORY.md\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v1 # v2 is broken for git diff\n      - uses: actions/setup-python@v2\n      - name: Setup Git Specs\n        run: |\n          git config --global user.name github-actions\n          git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'\n          git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY\n      - name: Update DIRECTORY.md\n        shell: python\n        run: |\n            import os\n            from typing import Iterator\n            URL_BASE = \"https://github.com/TheAlgorithms/Swift/blob/master\"\n            g_output = []\n            def good_filepaths(top_dir: str = \".\") -> Iterator[str]:\n                fs_exts = tuple(\".swift\".split())\n                for dirpath, dirnames, filenames in os.walk(top_dir):\n                    dirnames[:] = [d for d in dirnames if d[0] not in \"._\"]\n                    for filename in filenames:\n                        if os.path.splitext(filename)[1].lower() in fs_exts:\n                            yield os.path.join(dirpath, filename).lstrip(\"./\")\n            def md_prefix(i):\n                return f\"{i * '  '}*\" if i else \"\\n##\"\n            def print_path(old_path: str, new_path: str) -> str:\n                global g_output\n                old_parts = old_path.split(os.sep)\n                for i, new_part in enumerate(new_path.split(os.sep)):\n                    if i + 1 > len(old_parts) or old_parts[i] != new_part:\n                        if new_part:\n                            g_output.append(f\"{md_prefix(i)} {new_part.replace('_', ' ').title()}\")\n                return new_path\n            def build_directory_md(top_dir: str = \".\") -> str:\n                global g_output\n                old_path = \"\"\n                for filepath in sorted(good_filepaths(), key=str.lower):\n                    filepath, filename = os.path.split(filepath)\n                    if filepath != old_path:\n                        old_path = print_path(old_path, filepath)\n                    indent = (filepath.count(os.sep) + 1) if filepath else 0\n                    url = \"/\".join((URL_BASE, filepath, filename)).replace(\" \", \"%20\")\n                    filename = os.path.splitext(filename.replace(\"_\", \" \").title())[0]\n                    g_output.append(f\"{md_prefix(indent)} [{filename}]({url})\")\n                return \"# List of all files\\n\" + \"\\n\".join(g_output)\n            with open(\"DIRECTORY.md\", \"w\") as out_file:\n                out_file.write(build_directory_md(\".\") + \"\\n\")\n      - name: Commit DIRECTORY.md\n        run: |\n         git commit -m \"updating DIRECTORY.md\" DIRECTORY.md ||  true\n         git diff DIRECTORY.md\n         git push --force origin HEAD:$GITHUB_REF || true\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n"
  },
  {
    "path": "DIRECTORY.md",
    "content": "# List of all files\n\n## Algorithms\n  * Ai\n    * Minimax\n      * Sources\n        * Minimax.Playground\n          * [Contents](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Contents.swift)\n          * Sources\n            * Model\n              * Board\n                * [Board](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Board/Board.swift)\n                * [Boardposition](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Board/BoardPosition.swift)\n                * [Boardstatus](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Board/BoardStatus.swift)\n              * Gamemodel\n                * [Difficultlevel](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/GameModel/DifficultLevel.swift)\n                * [Gamemodel](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/GameModel/GameModel.swift)\n              * Minimax\n                * [Gamestatevalue](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Minimax/GameStateValue.swift)\n                * [Minimax](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Minimax/Minimax.swift)\n              * Player\n                * [Player](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Player/Player.swift)\n                * [Playersymbol](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Player/PlayerSymbol.swift)\n                * [Playertype](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Player/PlayerType.swift)\n            * View\n              * [Boardview](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Minimax.playground/Sources/View/BoardView.swift)\n        * Tests\n          * Tests\n            * [Boardtests](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Tests/Tests/BoardTests.swift)\n            * [Minimaxtests](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Tests/Tests/MinimaxTests.swift)\n            * [Playertests](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/AI/minimax/Sources/Tests/Tests/PlayerTests.swift)\n  * Conversion\n    * [Binary-To-Decimal](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/binary-to-decimal.swift)\n    * [Decimal-To-Binary](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/conversion/decimal-to-binary.swift)\n  * Palindrome\n    * [Palindrome Indices](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/palindrome/palindrome_indices.swift)\n    * [Palindrome Recursion](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/palindrome/palindrome_recursion.swift)\n    * [Palindrome Reversed](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/palindrome/palindrome_reversed.swift)\n  * Parsing\n    * Shunting Yard\n      * [Shunting Yard](https://github.com/TheAlgorithms/Swift/blob/master/algorithms/parsing/shunting_yard/shunting_yard.swift)\n\n## Data Structures\n  * Doubly Linked List\n    * [Doublylinkedlist](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/doubly_linked_list/DoublyLinkedList.swift)\n  * Heap\n    * [Heap](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/heap/heap.swift)\n  * Linked List\n    * [Linkedlist](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/Linked%20List/LinkedList.swift)\n  * Queue\n    * [Queue](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/queue/queue.swift)\n  * Stack\n    * [Stack](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/Stack/stack.swift)\n  * Union Find\n    * [Union Find](https://github.com/TheAlgorithms/Swift/blob/master/data_structures/union_find/union_find.swift)\n\n## Graph\n  * Bfs\n    * [Bfs](https://github.com/TheAlgorithms/Swift/blob/master/graph/BFS/BFS.swift)\n  * Dfs\n    * [Dfs](https://github.com/TheAlgorithms/Swift/blob/master/graph/DFS/DFS.swift)\n  * [Graph](https://github.com/TheAlgorithms/Swift/blob/master/graph/Graph.swift)\n  * Spanning Tree\n    * [Dijkstra](https://github.com/TheAlgorithms/Swift/blob/master/graph/spanning_tree/dijkstra.swift)\n    * [Kruskal](https://github.com/TheAlgorithms/Swift/blob/master/graph/spanning_tree/kruskal.swift)\n\n## Recursion\n  * [Fibonacci](https://github.com/TheAlgorithms/Swift/blob/master/recursion/fibonacci.swift)\n\n## Search\n  * [Binarysearch](https://github.com/TheAlgorithms/Swift/blob/master/Search/BinarySearch.swift)\n  * [Linearsearch](https://github.com/TheAlgorithms/Swift/blob/master/Search/LinearSearch.swift)\n\n## Sorts\n  * [Bubblesort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/BubbleSort.swift)\n  * [Cocktailsort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/CocktailSort.swift)\n  * [Insertionsort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/InsertionSort.swift)\n  * [Mergesort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/MergeSort.swift)\n  * [Pancakesort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/PancakeSort.swift)\n  * [Quicksort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/QuickSort.swift)\n  * [Selectionsort](https://github.com/TheAlgorithms/Swift/blob/master/sorts/SelectionSort.swift)\n\n## Trees\n  * [Tree](https://github.com/TheAlgorithms/Swift/blob/master/trees/tree.swift)\n"
  },
  {
    "path": "README.md",
    "content": "# The Algorithms - Swift\n\n### All algorithms implemented in Swift (for education)\n\nThese implementations are for learning purposes. They may be less efficient than the implementations in the Swift standard library.\n\n## Community Channel\n\nWe're on [Gitter](https://gitter.im/TheAlgorithms)! Please join us.\n\n## List of Algorithms\n\nSee our [directory](DIRECTORY.md).\n"
  },
  {
    "path": "Search/BinarySearch.swift",
    "content": "import Foundation\n\npublic func binarySearch<T: Comparable>(_ a: [T], key: T) -> Int? {\n    var lowerBound = 0\n    var upperBound = a.count\n    while lowerBound < upperBound {\n        let midIndex = lowerBound + (upperBound - lowerBound) / 2\n        if a[midIndex] == key {\n            return midIndex\n        } else if a[midIndex] < key {\n            lowerBound = midIndex + 1\n        } else {\n            upperBound = midIndex\n        }\n    }\n    return nil\n}\n// The code below can be used for testing\n\n// var numbers = [7, 10, 13, 17, 19, 24, 29, 31, 32, 37, 41, 43, 47, 51, 53, 119, 163, 611, 627]\n// if let searchIndex = binarySearch(numbers, key: 10) {\n//     print(\"Element found on index: \\(searchIndex)\")\n// }\n// else {\n// print(\"Element not found\")\n// }\n\n"
  },
  {
    "path": "Search/LinearSearch.swift",
    "content": "import Foundation\n\nfunc linearSearch<T: Equatable>(_ array: [T], _ object: T) -> Int? {\n  for (index, obj) in array.enumerated() where obj == object {\n    return index\n  }\n  return nil\n}\n\n// The code below can be used for testing\n\n// var numbers = [10, 119, 13, 24, 53, 17, 31, 7, 19, 627, 47, 163, 37, 611, 29, 43, 51, 41, 32]\n// if let searchIndex = linearSearch(numbers,31) {\n//     print(\"Element found on index: \\(searchIndex)\")\n// }\n// else {\n// print(\"Element not found\")\n// }\n"
  },
  {
    "path": "algorithms/AI/minimax/README.md",
    "content": "# Minimax algorithm\n\n<p align=\"center\"> <img src=\"Resources/image1.jpg\" {:height=\"50%\" width=\"50%\"} /> </p>\n\n## Runtime environment\n<img src=\"https://img.shields.io/badge/Swift-5.3-orange.svg?style=flat\" />\n<img src=\"https://img.shields.io/badge/Xcode-12.4-blue.svg?style=flat\" />\n<img src=\"https://img.shields.io/badge/MacOS-11.2.3-blue.svg?style=flat\" />\n\n## Table of contents\n* [General info](#general-info)\n* [Functionality](#functionality)\n* [Pseudocode](#pseudocode)\n* [Demo](#demo)\n* [Sources](#sources)\n\n## General info\nIt is an example of implementation and use ``minimax algorithm`` in ``Tic Tac Toe`` game. Minimax is an algorithm that searches deeply into all possible states in the game. There are two types of players in the algorithm. One that wants to maximize the state of the game and one that wants to minimaze the state of the game. There are three states in the tic-tac-toe game:\n- `` -1 `` - if the minimizing player wins\n- `` 0 `` - in case of a tie\n- `` 1 `` - if the maximizing player wins\n\n``Alpha-beta prunning`` this is a method that interrupts the search of those branches that do not lead to win. Alpha for maximizing player and beta for minimizing player. Alpha-beta prunnings reduce the time complexity of the algorithm.\n\nParameters:\n- ``searching depth`` - how many moves in depth is to be calculated by the algorithm\n\nInput:\n- ``actual board state`` - in the form of an array for players symbols (cross/circle)\n- ``two player symbols`` - cross / circle\n\nOutput:\n- ``the best move for autonomus(AI) player`` - Position(row: Int, column: Int)\n\n## Functionality\n- example of use in Swift Playground with interactive UIView\n- unit tests in XCode\n\n## Pseudocode\n\n```\nfunction alphabeta(node, depth, α, β, maximizingPlayer) is\n    if depth = 0 or node is a terminal node then\n        return the heuristic value of node\n    if maximizingPlayer then\n        value := −∞\n        for each child of node do\n            value := max(value, alphabeta(child, depth − 1, α, β, FALSE))\n            if value ≥ β then\n                break (* β cutoff *)\n            α := max(α, value)\n        return value\n    else\n        value := +∞\n        for each child of node do\n            value := min(value, alphabeta(child, depth − 1, α, β, TRUE))\n            if value ≤ α then\n                break (* α cutoff *)\n            β := min(β, value)\n        return value\n```\n\n## Demo\n\n<p align=\"center\"> <img src=\"Resources/demo.gif\" {:height=\"100%\" width=\"100%\"} /> </p>\n\n## Sources\n* Minimax algorithm: https://en.wikipedia.org/wiki/Minimax\n* Alpha-beta prunning: https://en.wikipedia.org/wiki/Alpha–beta_pruning\n\n## Author\nWritten by Michał Nowak(mnowak061)\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Contents.swift",
    "content": "import UIKit\nimport PlaygroundSupport\n\nlet boardSize = CGSize(width: 500, height: 550)\nlet boardView = BoardView(frame: CGRect(origin: .zero, size: boardSize))\n\nPlaygroundPage.current.needsIndefiniteExecution = true\nPlaygroundPage.current.liveView = boardView\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Board/Board.swift",
    "content": "public struct Board {\n    // MARK: -- Public variable's\n    public var size: Int\n\n    // MARK: -- Private variable's\n    private var table: [ [PlayerSymbol?] ]\n\n    // MARK: -- Public function's\n    public init(size: Int) {\n        self.size = size\n        self.table = []\n        self.clear()\n    }\n\n    public mutating func clear() {\n        self.table = Array(repeating: Array(repeating: PlayerSymbol.empty, count: size), count: size)\n    }\n\n    public func hasEmptyField() -> Bool {\n        for i in 0 ..< self.size {\n            for j in 0 ..< self.size {\n                if self.table[i][j] == PlayerSymbol.empty {\n                    return true\n                }\n            }\n        }\n        return false\n    }\n\n    public func symbol(forPosition position: Position) -> PlayerSymbol? {\n        guard position.row < self.size, position.column < size else { return nil }\n        return self.table[position.row][position.column]\n    }\n\n    public mutating func makeMove(player: Player, position: Position) {\n        guard self.symbol(forPosition: position) == PlayerSymbol.empty else { return }\n        guard self.symbol(forPosition: position) != player.symbol else { return }\n\n        self.table[position.row][position.column] = player.symbol\n    }\n\n    public func check(player: Player) -> BoardStatus {\n        let playerSymbol: PlayerSymbol = player.symbol\n\n        if self.foundWinInRows(playerSymbol) { return BoardStatus.win }\n        if self.foundWinInColumns(playerSymbol) { return BoardStatus.win }\n        if self.foundWinInSlants(playerSymbol) { return BoardStatus.win }\n\n        if self.hasEmptyField() { return BoardStatus.continues } else { return BoardStatus.draw }\n    }\n\n    // MARK: -- Private function's\n    private func foundWinInRows(_ playerSymbol: PlayerSymbol) -> Bool {\n        for i in 0 ..< self.size {\n            var theSameSymbolsInRowCount = 0\n\n            for j in 0 ..< self.size - 1 {\n                if self.table[i][j] == self.table[i][j+1] && (self.table[i][j] == playerSymbol) {\n                    theSameSymbolsInRowCount += 1\n                } else {\n                    theSameSymbolsInRowCount = 0\n                }\n            }\n\n            if theSameSymbolsInRowCount == self.size - 1 {\n                return true\n            }\n        }\n\n        return false\n    }\n\n    private func foundWinInColumns(_ playerSymbol: PlayerSymbol) -> Bool {\n        for j in 0 ..< self.size {\n            var theSameSymbolsInColumnCount = 0\n\n            for i in 0 ..< self.size - 1 {\n                if self.table[i][j] == self.table[i+1][j] && (self.table[i][j] == playerSymbol) {\n                    theSameSymbolsInColumnCount += 1\n                } else {\n                    theSameSymbolsInColumnCount = 0\n                }\n            }\n\n            if theSameSymbolsInColumnCount == self.size - 1 {\n                return true\n            }\n        }\n\n        return false\n    }\n\n    private func foundWinInSlants(_ playerSymbol: PlayerSymbol) -> Bool {\n        var theSameSymbolsInSlantCount = 0\n\n        for i in 0 ..< self.size {\n            for j in -(self.size - 1) ... 0 {\n                if(self.table[-j][i] == playerSymbol) {\n                    var k: Int = -j\n                    var l: Int = i\n                    theSameSymbolsInSlantCount = 0\n\n                    while l < self.size && k >= 0 {\n                        if self.table[k][l] == playerSymbol {\n                            theSameSymbolsInSlantCount += 1\n                        } else {\n                            theSameSymbolsInSlantCount = 0\n                        }\n                        k -= 1\n                        l += 1\n\n                        if theSameSymbolsInSlantCount == self.size {\n                            return true\n                        }\n                    }\n                    theSameSymbolsInSlantCount = 0\n                }\n                theSameSymbolsInSlantCount = 0\n            }\n            theSameSymbolsInSlantCount = 0\n        }\n\n        theSameSymbolsInSlantCount = 0\n\n        for i in 0 ..< self.size {\n            for j in 0 ..< self.size {\n                if(self.table[j][i] == playerSymbol) {\n                    var k: Int = j\n                    var l: Int = i\n                    theSameSymbolsInSlantCount = 0\n\n                    while l < self.size && k < self.size {\n                        if self.table[k][l] == playerSymbol {\n                            theSameSymbolsInSlantCount += 1\n                        } else {\n                            theSameSymbolsInSlantCount = 0\n                        }\n                        k += 1\n                        l += 1\n\n                        if theSameSymbolsInSlantCount == self.size {\n                            return true\n                        }\n                    }\n                    theSameSymbolsInSlantCount = 0\n                }\n                theSameSymbolsInSlantCount = 0\n            }\n            theSameSymbolsInSlantCount = 0\n        }\n\n        return false\n    }\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Board/BoardPosition.swift",
    "content": "public typealias Position = (row: Int, column: Int)\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Board/BoardStatus.swift",
    "content": "public enum BoardStatus {\n\n    case continues\n\n    case win\n\n    case draw\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/GameModel/DifficultLevel.swift",
    "content": "public enum DifficultLevel: Int {\n\n    case easy = 2\n\n    case medium = 3\n\n    case hard = 5\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/GameModel/GameModel.swift",
    "content": "import Foundation\n\npublic class GameModel {\n    // MARK: -- Public variable's\n    public var board: Board!\n\n    public var gameStatus: BoardStatus\n\n    // MARK: -- Private variable's\n    private var playersList: [Player]!\n\n    private var movementsSequence: [Int]!\n\n    private var actualPlayerIndex: Int!\n\n    private var actualPlayer: Player {\n        get {\n            return playersList[actualPlayerIndex]\n        }\n    }\n\n    private var difficultLevel: DifficultLevel = DifficultLevel.hard\n\n    // MARK: -- Public function's\n    public init(boardSize: Int, playersList: [Player], difficultLevel: DifficultLevel) {\n        self.board = Board.init(size: boardSize)\n        self.playersList = playersList\n        self.difficultLevel = difficultLevel\n        self.gameStatus = BoardStatus.continues\n\n        self.generateMovementsSequence()\n        self.changeActualPlayer()\n    }\n\n    public func update() {\n        self.gameStatus = board.check(player: actualPlayer)\n\n        switch self.gameStatus {\n        case BoardStatus.continues:\n            changeActualPlayer()\n        case BoardStatus.draw:\n            changeActualPlayer()\n        default: break\n        }\n    }\n\n    public func playerMakeMove(selectedPosition: (row: Int, column: Int)) {\n        guard board.symbol(forPosition: selectedPosition) == PlayerSymbol.empty else { return }\n        guard board.hasEmptyField() == true else { return }\n\n        board.makeMove(player: actualPlayer, position: selectedPosition)\n        update()\n    }\n\n    public func makeMinimaxMove() {\n        guard actualPlayer.type == PlayerType.computer else { return }\n        guard board.hasEmptyField() == true else { return }\n\n        sleep(1)\n\n        let selectedPosition: Position = minimaxMove(board: board, player: playersList[0], opponent: playersList[1], depth: self.difficultLevel.rawValue)\n        board.makeMove(player: actualPlayer, position: selectedPosition)\n        update()\n    }\n\n    public func newRound() {\n        board.clear()\n        gameStatus = BoardStatus.continues\n        generateMovementsSequence()\n        changeActualPlayer()\n    }\n\n    // MARK: -- Private function's\n    private func generateMovementsSequence() {\n        self.movementsSequence = []\n\n        let playersCount = playersList.count\n        let movesCount = (board.size * board.size)\n\n        var move = Int.random(in: 0 ..< playersCount)\n        movementsSequence.append(move)\n\n        for _ in 0 ..< movesCount - 1 {\n            move += 1\n            movementsSequence.append(move % playersCount)\n        }\n    }\n\n    private func changeActualPlayer() {\n        if !movementsSequence.isEmpty {\n            actualPlayerIndex = movementsSequence.first!\n            movementsSequence.removeFirst()\n        }\n    }\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Minimax/GameStateValue.swift",
    "content": "public enum GameStateValue: Int {\n\n    case min = -1\n\n    case null = 0\n\n    case max = 1\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Minimax/Minimax.swift",
    "content": "public func minimaxMove(board: Board, player: Player, opponent: Player, depth: Int) -> Position {\n    var bestVal = GameStateValue.min\n    var bestMoves: [Position] = []\n\n    for i in 0 ..< board.size {\n        for j in 0 ..< board.size {\n            if board.symbol(forPosition: Position(i, j)) == PlayerSymbol.empty {\n                var tempBoard = board\n                let move = Position(i, j)\n\n                tempBoard.makeMove(player: opponent, position: (i, j))\n                let moveVal = minMax(board: tempBoard, player: opponent, opponent: player,\n                                     depth: depth,\n                                     alpha: GameStateValue.min.rawValue, beta: GameStateValue.max.rawValue,\n                                     maximizingPlayer: false)\n\n                if moveVal.rawValue > bestVal.rawValue {\n                    bestVal = moveVal\n                    bestMoves = []\n                    bestMoves.append(move)\n                } else if moveVal == bestVal {\n                    bestMoves.append(move)\n                }\n            }\n        }\n    }\n\n    return bestMoves[Int.random(in: 0 ..< bestMoves.count)]\n}\n\npublic func minMax(board: Board, player: Player, opponent: Player, depth: Int, alpha: Int, beta: Int, maximizingPlayer: Bool) -> GameStateValue {\n    var alpha = alpha\n    var beta = beta\n\n    if let gameResult = evaluateGameState(board: board, player: player, opponent: opponent) {\n        guard depth != 0 && gameResult != GameStateValue.min && gameResult != GameStateValue.max && gameResult != GameStateValue.null else {\n            return gameResult\n        }\n    }\n\n    if maximizingPlayer {\n        var maxEval = GameStateValue.min\n\n        for i in 0 ..< board.size {\n            for j in 0 ..< board.size {\n                if board.symbol(forPosition: Position(i, j)) == PlayerSymbol.empty {\n                    var tempBoard = board\n                    tempBoard.makeMove(player: player, position: Position(i, j))\n\n                    let eval = minMax(board: tempBoard, player: player, opponent: opponent, depth: depth - 1,\n                                      alpha: alpha, beta: beta,\n                                      maximizingPlayer: !maximizingPlayer)\n\n                    maxEval = GameStateValue(rawValue: max(maxEval.rawValue, eval.rawValue))!\n                    alpha = max(alpha, eval.rawValue)\n\n                    if beta <= alpha { break }\n                }\n            }\n        }\n\n        return maxEval\n    } else {\n        var minEval = GameStateValue.max\n\n        for i in 0 ..< board.size {\n            for j in 0 ..< board.size {\n                if board.symbol(forPosition: Position(i, j)) == PlayerSymbol.empty {\n                    var tempBoard = board\n                    tempBoard.makeMove(player: opponent, position: (i, j))\n\n                    let eval = minMax(board: tempBoard, player: player, opponent: opponent, depth: depth - 1,\n                                      alpha: alpha, beta: beta,\n                                      maximizingPlayer: !maximizingPlayer)\n\n                    minEval =  GameStateValue(rawValue: min(minEval.rawValue, eval.rawValue))!\n                    beta = min(beta, eval.rawValue)\n\n                    if beta <= alpha { break }\n                }\n            }\n        }\n\n        return minEval\n    }\n}\n\npublic func evaluateGameState(board: Board, player: Player, opponent: Player) -> GameStateValue? {\n    if board.check(player: player) == BoardStatus.win {\n        return GameStateValue.max\n    } else if board.check(player: opponent) == BoardStatus.win {\n        return GameStateValue.min\n    } else if board.check(player: player) == BoardStatus.draw || board.check(player: opponent) == BoardStatus.draw {\n        return GameStateValue.null\n    }\n\n    return nil\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Player/Player.swift",
    "content": "public struct Player {\n    // MARK: -- Public variable's\n    public var type: PlayerType\n\n    public var symbol: PlayerSymbol\n\n    // MARK: -- Public function's\n    public init(type: PlayerType, symbol: PlayerSymbol) {\n        self.type = type\n        self.symbol = symbol\n    }\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Player/PlayerSymbol.swift",
    "content": "public enum PlayerSymbol: String {\n\n    case empty = \"\"\n\n    case circle = \"⭕️\"\n\n    case cross = \"❌\"\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/Model/Player/PlayerType.swift",
    "content": "public enum PlayerType {\n\n    case computer\n\n    case human\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/Sources/View/BoardView.swift",
    "content": "import UIKit\n\npublic class BoardView: UIView {\n    // MARK: -- Public\n    public var gameModel: GameModel!\n\n    public var players = [Player(type: .human, symbol: .circle),\n                          Player(type: .computer, symbol: .cross)]\n\n    // MARK: -- Override's\n    public override init(frame: CGRect) {\n        super.init(frame: frame)\n\n        self.setupBoard()\n        self.setupResetButton()\n        self.setupIndicator()\n        self.startGame()\n    }\n\n    required init?(coder: NSCoder) {\n        super.init(coder: coder)\n    }\n\n    // MARK: -- Private\n    private var buttons: [UIButton] = []\n\n    private var stackView: UIStackView!\n\n    private var resetButton: UIButton!\n\n    private var indicator: UIActivityIndicatorView!\n\n    private func startGame() {\n        self.gameModel = GameModel.init(boardSize: 3, playersList: self.players, difficultLevel: .hard)\n\n        DispatchQueue.global(qos: .userInteractive).async {\n\n            self.blockViewForUser()\n\n            self.gameModel.makeMinimaxMove()\n\n            self.unblockViewForUser()\n        }\n    }\n\n    private func updateUI() {\n        if gameModel.gameStatus != BoardStatus.continues {\n            self.resetButton.setTitle(\"New game\", for: .normal)\n            blockButtons()\n        } else {\n            self.resetButton.setTitle(\"Reset\", for: .normal)\n        }\n        boardToButtons()\n    }\n\n    private func boardToButtons() {\n        var buttonIndex = 0\n\n        for row in 0 ..< 3 {\n            for column in 0 ..< 3 {\n                let symbol = gameModel.board.symbol(forPosition: Position(row, column))\n                if symbol != PlayerSymbol.empty {\n                    self.buttons[buttonIndex].setTitle(symbol?.rawValue, for: .normal)\n                    self.buttons[buttonIndex].isUserInteractionEnabled = false\n                }\n                buttonIndex += 1\n            }\n        }\n    }\n\n    private func setupBoard() {\n        self.stackView = UIStackView()\n        self.stackView.translatesAutoresizingMaskIntoConstraints = false\n        self.stackView.axis = .vertical\n        self.stackView.alignment = .fill\n        self.stackView.distribution = .fillEqually\n        self.stackView.spacing = 10\n\n        self.addSubview(self.stackView)\n\n        for index in 1 ... 3 {\n            let boardRow = self.createBoardRow(rowNumber: index)\n            self.stackView.addArrangedSubview(boardRow)\n        }\n\n        // constraints\n        let constraints = [\n            self.stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 10),\n            self.stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor),\n            self.stackView.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -20),\n            self.stackView.heightAnchor.constraint(equalTo: self.stackView.widthAnchor)\n        ]\n        NSLayoutConstraint.activate(constraints)\n    }\n\n    private func createBoardRow(rowNumber: Int) -> UIStackView {\n        let stackView = UIStackView()\n        stackView.translatesAutoresizingMaskIntoConstraints = false\n        stackView.axis = .horizontal\n        stackView.alignment = .fill\n        stackView.distribution = .fillEqually\n        stackView.spacing = 10\n\n        for index in 1 ... 3 {\n            let button = UIButton()\n            let id = String(index + ( (rowNumber - 1) * 3 ) )\n            button.restorationIdentifier = id\n            button.backgroundColor = .lightGray\n            button.titleLabel?.font = UIFont(name: \"Helvetica\", size: 50)\n            button.addTarget(self, action: #selector(buttonPressed(_:)), for: .touchUpInside)\n\n            self.buttons.append(button)\n            stackView.addArrangedSubview(button)\n        }\n\n        return stackView\n    }\n\n    private func blockViewForUser() {\n        DispatchQueue.main.async {\n            self.resetButton.isHidden = true\n            self.indicator.isHidden = false\n            self.indicator.startAnimating()\n\n            self.blockButtons()\n            self.updateUI()\n        }\n    }\n\n    private func unblockViewForUser() {\n        DispatchQueue.main.async {\n            self.unblockButtons()\n            self.updateUI()\n\n            self.resetButton.isHidden = false\n            self.indicator.isHidden = true\n            self.indicator.stopAnimating()\n        }\n    }\n\n    @objc private func buttonPressed(_ sender: UIButton) {\n        let position = buttonIDtoPosition(id: sender.restorationIdentifier!)\n\n        DispatchQueue.global(qos: .userInteractive).async {\n            self.gameModel.playerMakeMove(selectedPosition: position)\n\n            self.blockViewForUser()\n\n            self.gameModel.makeMinimaxMove()\n\n            self.unblockViewForUser()\n        }\n    }\n\n    private func setupResetButton() {\n        self.resetButton = UIButton(type: .system)\n        self.resetButton.translatesAutoresizingMaskIntoConstraints = false\n        self.resetButton.setTitle(\"Reset\", for: .normal)\n        self.resetButton.backgroundColor = .lightGray\n        self.resetButton.addTarget(self, action: #selector(resetButtonPressed(_:)), for: .touchUpInside)\n\n        self.addSubview(self.resetButton)\n\n        // constraints\n        let constraints = [\n            self.resetButton.topAnchor.constraint(equalTo: self.stackView.bottomAnchor, constant: 10),\n            self.resetButton.bottomAnchor.constraint(equalTo: self.bottomAnchor),\n            self.resetButton.widthAnchor.constraint(equalTo: self.widthAnchor)\n        ]\n        NSLayoutConstraint.activate(constraints)\n    }\n\n    @objc private func resetButtonPressed(_ sender: UIButton) {\n        self.gameModel.newRound()\n        self.clearButtons()\n        self.startGame()\n    }\n\n    private func setupIndicator() {\n        self.indicator = UIActivityIndicatorView()\n        self.indicator.translatesAutoresizingMaskIntoConstraints = false\n        self.indicator.backgroundColor = .lightGray\n\n        self.addSubview(self.indicator)\n\n        // constraints\n        let constraints = [\n            self.indicator.topAnchor.constraint(equalTo: self.stackView.bottomAnchor, constant: 10),\n            self.indicator.bottomAnchor.constraint(equalTo: self.bottomAnchor),\n            self.indicator.widthAnchor.constraint(equalTo: self.widthAnchor)\n        ]\n        NSLayoutConstraint.activate(constraints)\n    }\n\n    private func buttonIDtoPosition(id: String) -> Position {\n        switch id {\n        case \"1\":\n            return Position(0, 0)\n        case \"2\":\n            return Position(0, 1)\n        case \"3\":\n            return Position(0, 2)\n        case \"4\":\n            return Position(1, 0)\n        case \"5\":\n            return Position(1, 1)\n        case \"6\":\n            return Position(1, 2)\n        case \"7\":\n            return Position(2, 0)\n        case \"8\":\n            return Position(2, 1)\n        case \"9\":\n            return Position(2, 2)\n        default:\n            return Position(0, 0)\n        }\n    }\n\n    private func clearButtons() {\n        for button in self.buttons {\n            button.setTitle(\"\", for: .normal)\n            button.isUserInteractionEnabled = true\n        }\n    }\n\n    private func unblockButtons() {\n        for button in self.buttons {\n            button.isUserInteractionEnabled = true\n        }\n    }\n\n    private func blockButtons() {\n        for button in self.buttons {\n            button.isUserInteractionEnabled = false\n        }\n    }\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/contents.xcplayground",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='ios' buildActiveScheme='true' importAppTypes='true'>\n    <timeline fileName='timeline.xctimeline'/>\n</playground>"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/playground.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Minimax.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Tests/Tests/BoardTests.swift",
    "content": "import XCTest\n\nclass BoardTests: XCTestCase {\n\n    private var sut: Board!\n\n    private var boardSize = 3\n\n    override func setUp() {\n        super.setUp()\n        sut = Board(size: boardSize)\n    }\n\n    override func tearDown() {\n        sut = nil\n        super.tearDown()\n    }\n\n    func testInit() {\n        XCTAssertEqual(sut.size, boardSize)\n        XCTAssertEqual(allFieldsAreEmpty(), true)\n    }\n\n    func testSymbolForPosition() {\n        let player = Player(type: .human, symbol: .circle)\n        let position = Position(0, 0)\n\n        sut.clear()\n        XCTAssertEqual(sut.symbol(forPosition: position), PlayerSymbol.empty)\n\n        sut.makeMove(player: player, position: position)\n        XCTAssertEqual(sut.symbol(forPosition: position), player.symbol)\n    }\n\n    func testClear() {\n        let player = Player(type: .computer, symbol: .circle)\n        let position = Position(0, 0)\n\n        sut.makeMove(player: player, position: position)\n\n        XCTAssertEqual(allFieldsAreEmpty(), false)\n\n        sut.clear()\n\n        XCTAssertEqual(allFieldsAreEmpty(), true)\n    }\n\n    func testHasEmptyField() {\n        let player = Player(type: .computer, symbol: .circle)\n\n        sut.clear()\n\n        XCTAssertEqual(sut.hasEmptyField(), true)\n\n        sut.makeMove(player: player, position: Position(0, 0))\n        sut.makeMove(player: player, position: Position(0, 1))\n        sut.makeMove(player: player, position: Position(0, 2))\n\n        sut.makeMove(player: player, position: Position(1, 0))\n        sut.makeMove(player: player, position: Position(1, 1))\n        sut.makeMove(player: player, position: Position(1, 2))\n\n        sut.makeMove(player: player, position: Position(2, 0))\n        sut.makeMove(player: player, position: Position(2, 1))\n        sut.makeMove(player: player, position: Position(2, 2))\n\n        XCTAssertEqual(sut.hasEmptyField(), false)\n    }\n\n    func testMakeMove() {\n        let firstPlayer = Player(type: .human, symbol: .circle)\n        let secondPlayer = Player(type: .human, symbol: .cross)\n        let position = Position(0, 0)\n\n        sut.clear()\n        sut.makeMove(player: firstPlayer, position: position)\n        sut.makeMove(player: secondPlayer, position: position)\n\n        XCTAssertEqual(sut.symbol(forPosition: position), firstPlayer.symbol)\n    }\n\n    func testCheck() {\n        let firstPlayer = Player(type: .computer, symbol: .circle)\n        let secondPlayer = Player(type: .computer, symbol: .cross)\n\n        sut.clear()\n\n        XCTAssertEqual(sut.check(player: firstPlayer), BoardStatus.continues)\n        XCTAssertEqual(sut.check(player: secondPlayer), BoardStatus.continues)\n\n        sut.clear()\n        sut.makeMove(player: firstPlayer, position: Position(0, 0))\n        sut.makeMove(player: firstPlayer, position: Position(0, 1))\n        sut.makeMove(player: firstPlayer, position: Position(0, 2))\n\n        XCTAssertEqual(sut.check(player: firstPlayer), BoardStatus.win)\n        XCTAssertEqual(sut.check(player: secondPlayer), BoardStatus.continues)\n\n        sut.clear()\n        sut.makeMove(player: firstPlayer, position: Position(0, 0))\n        sut.makeMove(player: firstPlayer, position: Position(1, 0))\n        sut.makeMove(player: firstPlayer, position: Position(2, 0))\n\n        XCTAssertEqual(sut.check(player: firstPlayer), BoardStatus.win)\n        XCTAssertEqual(sut.check(player: secondPlayer), BoardStatus.continues)\n\n        sut.clear()\n        sut.makeMove(player: firstPlayer, position: Position(0, 0))\n        sut.makeMove(player: firstPlayer, position: Position(1, 1))\n        sut.makeMove(player: firstPlayer, position: Position(2, 2))\n\n        XCTAssertEqual(sut.check(player: firstPlayer), BoardStatus.win)\n        XCTAssertEqual(sut.check(player: secondPlayer), BoardStatus.continues)\n\n        sut.clear()\n        sut.makeMove(player: firstPlayer, position: Position(0, 0))\n        sut.makeMove(player: secondPlayer, position: Position(0, 1))\n        sut.makeMove(player: secondPlayer, position: Position(0, 2))\n\n        sut.makeMove(player: secondPlayer, position: Position(1, 0))\n        sut.makeMove(player: firstPlayer, position: Position(1, 1))\n        sut.makeMove(player: firstPlayer, position: Position(1, 2))\n\n        sut.makeMove(player: secondPlayer, position: Position(2, 0))\n        sut.makeMove(player: firstPlayer, position: Position(2, 1))\n        sut.makeMove(player: secondPlayer, position: Position(2, 2))\n\n        XCTAssertEqual(sut.check(player: firstPlayer), BoardStatus.draw)\n        XCTAssertEqual(sut.check(player: secondPlayer), BoardStatus.draw)\n    }\n\n    private func allFieldsAreEmpty() -> Bool {\n        var allFieldAreEmpty = true\n\n        for row in 0 ..< sut.size {\n            for column in 0 ..< sut.size {\n                if sut.symbol(forPosition: Position(row, column)) != PlayerSymbol.empty {\n                    allFieldAreEmpty = false\n                }\n            }\n        }\n\n        return allFieldAreEmpty\n    }\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Tests/Tests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Tests/Tests/MinimaxTests.swift",
    "content": "import XCTest\n\nclass MinimaxTests: XCTestCase {\n    override func setUp() {\n        super.setUp()\n    }\n\n    override func tearDown() {\n        super.tearDown()\n    }\n\n    func testEvaluateGameState() {\n        var board = Board(size: 3)\n        let firstPlayer = Player(type: .human, symbol: .cross)\n        let secondPlayer = Player(type: .human, symbol: .circle)\n\n        board.clear()\n\n        XCTAssertEqual(evaluateGameState(board: board, player: firstPlayer, opponent: secondPlayer), nil)\n\n        board.makeMove(player: firstPlayer, position: Position(0, 0))\n\n        XCTAssertEqual(evaluateGameState(board: board, player: firstPlayer, opponent: secondPlayer), nil)\n\n        board.makeMove(player: firstPlayer, position: Position(0, 1))\n        board.makeMove(player: firstPlayer, position: Position(0, 2))\n\n        XCTAssertEqual(evaluateGameState(board: board, player: firstPlayer, opponent: secondPlayer), .max)\n        XCTAssertEqual(evaluateGameState(board: board, player: secondPlayer, opponent: firstPlayer), .min)\n\n        board.clear()\n        board.makeMove(player: secondPlayer, position: Position(0, 0))\n        board.makeMove(player: secondPlayer, position: Position(0, 1))\n        board.makeMove(player: secondPlayer, position: Position(0, 2))\n        board.makeMove(player: firstPlayer, position: Position(1, 0))\n\n        XCTAssertEqual(evaluateGameState(board: board, player: firstPlayer, opponent: secondPlayer), .min)\n        XCTAssertEqual(evaluateGameState(board: board, player: secondPlayer, opponent: firstPlayer), .max)\n\n        board.clear()\n        board.makeMove(player: firstPlayer, position: Position(0, 0))\n        board.makeMove(player: secondPlayer, position: Position(0, 1))\n        board.makeMove(player: secondPlayer, position: Position(0, 2))\n\n        board.makeMove(player: secondPlayer, position: Position(1, 0))\n        board.makeMove(player: firstPlayer, position: Position(1, 1))\n        board.makeMove(player: firstPlayer, position: Position(1, 2))\n\n        board.makeMove(player: secondPlayer, position: Position(2, 0))\n        board.makeMove(player: firstPlayer, position: Position(2, 1))\n        board.makeMove(player: secondPlayer, position: Position(2, 2))\n\n        XCTAssertEqual(evaluateGameState(board: board, player: firstPlayer, opponent: secondPlayer), .null)\n        XCTAssertEqual(evaluateGameState(board: board, player: secondPlayer, opponent: firstPlayer), .null)\n    }\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Tests/Tests/PlayerTests.swift",
    "content": "import XCTest\n\nclass PlayerTests: XCTestCase {\n\n    private var sut: Player!\n\n    private var playerType: PlayerType = .human\n\n    private var playerSymbol: PlayerSymbol = .circle\n\n    override func setUp() {\n        super.setUp()\n        sut = Player(type: playerType, symbol: playerSymbol)\n    }\n\n    override func tearDown() {\n        sut = nil\n        super.tearDown()\n    }\n\n    func testInit() {\n        XCTAssertEqual(sut.type, playerType)\n        XCTAssertEqual(sut.symbol, playerSymbol)\n    }\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Tests/Tests.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t9D029435268265690015843C /* BoardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D029434268265690015843C /* BoardTests.swift */; };\n\t\t9D02946D268285E20015843C /* PlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D02946C268285E20015843C /* PlayerTests.swift */; };\n\t\t9D0294852682B1850015843C /* Minimax.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D02947A2682B1840015843C /* Minimax.swift */; };\n\t\t9D0294862682B1850015843C /* PlayerSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D02947B2682B1840015843C /* PlayerSymbol.swift */; };\n\t\t9D0294872682B1850015843C /* Board.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D02947D2682B1840015843C /* Board.swift */; };\n\t\t9D0294882682B1850015843C /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D02947E2682B1840015843C /* Player.swift */; };\n\t\t9D0294892682B1850015843C /* BoardPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D02947F2682B1840015843C /* BoardPosition.swift */; };\n\t\t9D02948A2682B1850015843C /* PlayerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D0294802682B1840015843C /* PlayerType.swift */; };\n\t\t9D02948B2682B1850015843C /* GameModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D0294812682B1840015843C /* GameModel.swift */; };\n\t\t9D02948C2682B1850015843C /* DifficultLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D0294822682B1840015843C /* DifficultLevel.swift */; };\n\t\t9D02948D2682B1850015843C /* BoardStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D0294832682B1840015843C /* BoardStatus.swift */; };\n\t\t9D02948E2682B1850015843C /* GameStateValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D0294842682B1850015843C /* GameStateValue.swift */; };\n\t\t9DB8564E268129FE0046878A /* MinimaxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DB8564D268129FE0046878A /* MinimaxTests.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t9D029434268265690015843C /* BoardTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoardTests.swift; sourceTree = \"<group>\"; };\n\t\t9D02946C268285E20015843C /* PlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerTests.swift; sourceTree = \"<group>\"; };\n\t\t9D02947A2682B1840015843C /* Minimax.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Minimax.swift; path = ../Minimax.playground/Sources/Model/Minimax/Minimax.swift; sourceTree = \"<group>\"; };\n\t\t9D02947B2682B1840015843C /* PlayerSymbol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PlayerSymbol.swift; path = ../Minimax.playground/Sources/Model/Player/PlayerSymbol.swift; sourceTree = \"<group>\"; };\n\t\t9D02947D2682B1840015843C /* Board.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Board.swift; path = ../Minimax.playground/Sources/Model/Board/Board.swift; sourceTree = \"<group>\"; };\n\t\t9D02947E2682B1840015843C /* Player.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Player.swift; path = ../Minimax.playground/Sources/Model/Player/Player.swift; sourceTree = \"<group>\"; };\n\t\t9D02947F2682B1840015843C /* BoardPosition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoardPosition.swift; path = ../Minimax.playground/Sources/Model/Board/BoardPosition.swift; sourceTree = \"<group>\"; };\n\t\t9D0294802682B1840015843C /* PlayerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PlayerType.swift; path = ../Minimax.playground/Sources/Model/Player/PlayerType.swift; sourceTree = \"<group>\"; };\n\t\t9D0294812682B1840015843C /* GameModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameModel.swift; path = ../Minimax.playground/Sources/Model/GameModel/GameModel.swift; sourceTree = \"<group>\"; };\n\t\t9D0294822682B1840015843C /* DifficultLevel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DifficultLevel.swift; path = ../Minimax.playground/Sources/Model/GameModel/DifficultLevel.swift; sourceTree = \"<group>\"; };\n\t\t9D0294832682B1840015843C /* BoardStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoardStatus.swift; path = ../Minimax.playground/Sources/Model/Board/BoardStatus.swift; sourceTree = \"<group>\"; };\n\t\t9D0294842682B1850015843C /* GameStateValue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameStateValue.swift; path = ../Minimax.playground/Sources/Model/Minimax/GameStateValue.swift; sourceTree = \"<group>\"; };\n\t\t9DB8564A268129FE0046878A /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t9DB8564D268129FE0046878A /* MinimaxTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MinimaxTests.swift; sourceTree = \"<group>\"; };\n\t\t9DB8564F268129FE0046878A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t9DB85647268129FE0046878A /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t9DB8563F268129EF0046878A = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9D02947D2682B1840015843C /* Board.swift */,\n\t\t\t\t9D02947F2682B1840015843C /* BoardPosition.swift */,\n\t\t\t\t9D0294832682B1840015843C /* BoardStatus.swift */,\n\t\t\t\t9D0294822682B1840015843C /* DifficultLevel.swift */,\n\t\t\t\t9D0294812682B1840015843C /* GameModel.swift */,\n\t\t\t\t9D0294842682B1850015843C /* GameStateValue.swift */,\n\t\t\t\t9D02947A2682B1840015843C /* Minimax.swift */,\n\t\t\t\t9D02947E2682B1840015843C /* Player.swift */,\n\t\t\t\t9D02947B2682B1840015843C /* PlayerSymbol.swift */,\n\t\t\t\t9D0294802682B1840015843C /* PlayerType.swift */,\n\t\t\t\t9DB8564C268129FE0046878A /* Tests */,\n\t\t\t\t9DB8564B268129FE0046878A /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9DB8564B268129FE0046878A /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9DB8564A268129FE0046878A /* Tests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9DB8564C268129FE0046878A /* Tests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9DB8564F268129FE0046878A /* Info.plist */,\n\t\t\t\t9D02946C268285E20015843C /* PlayerTests.swift */,\n\t\t\t\t9D029434268265690015843C /* BoardTests.swift */,\n\t\t\t\t9DB8564D268129FE0046878A /* MinimaxTests.swift */,\n\t\t\t);\n\t\t\tpath = Tests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t9DB85649268129FE0046878A /* Tests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 9DB85650268129FE0046878A /* Build configuration list for PBXNativeTarget \"Tests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t9DB85646268129FE0046878A /* Sources */,\n\t\t\t\t9DB85647268129FE0046878A /* Frameworks */,\n\t\t\t\t9DB85648268129FE0046878A /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = Tests;\n\t\t\tproductName = Tests;\n\t\t\tproductReference = 9DB8564A268129FE0046878A /* Tests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t9DB85640268129EF0046878A /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1250;\n\t\t\t\tLastUpgradeCheck = 1250;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t9DB85649268129FE0046878A = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 12.5;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 9DB85643268129EF0046878A /* Build configuration list for PBXProject \"Tests\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 9DB8563F268129EF0046878A;\n\t\t\tproductRefGroup = 9DB8564B268129FE0046878A /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t9DB85649268129FE0046878A /* Tests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t9DB85648268129FE0046878A /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t9DB85646268129FE0046878A /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t9D029435268265690015843C /* BoardTests.swift in Sources */,\n\t\t\t\t9D02948E2682B1850015843C /* GameStateValue.swift in Sources */,\n\t\t\t\t9DB8564E268129FE0046878A /* MinimaxTests.swift in Sources */,\n\t\t\t\t9D0294872682B1850015843C /* Board.swift in Sources */,\n\t\t\t\t9D0294892682B1850015843C /* BoardPosition.swift in Sources */,\n\t\t\t\t9D02948A2682B1850015843C /* PlayerType.swift in Sources */,\n\t\t\t\t9D02948B2682B1850015843C /* GameModel.swift in Sources */,\n\t\t\t\t9D02948C2682B1850015843C /* DifficultLevel.swift in Sources */,\n\t\t\t\t9D0294862682B1850015843C /* PlayerSymbol.swift in Sources */,\n\t\t\t\t9D02948D2682B1850015843C /* BoardStatus.swift in Sources */,\n\t\t\t\t9D0294882682B1850015843C /* Player.swift in Sources */,\n\t\t\t\t9D02946D268285E20015843C /* PlayerTests.swift in Sources */,\n\t\t\t\t9D0294852682B1850015843C /* Minimax.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t9DB85644268129EF0046878A /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t9DB85645268129EF0046878A /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t9DB85651268129FE0046878A /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tINFOPLIST_FILE = Tests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t\t\"@loader_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 11.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.example.Tests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t9DB85652268129FE0046878A /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tINFOPLIST_FILE = Tests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t\t\"@loader_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 11.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.example.Tests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t9DB85643268129EF0046878A /* Build configuration list for PBXProject \"Tests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t9DB85644268129EF0046878A /* Debug */,\n\t\t\t\t9DB85645268129EF0046878A /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t9DB85650268129FE0046878A /* Build configuration list for PBXNativeTarget \"Tests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t9DB85651268129FE0046878A /* Debug */,\n\t\t\t\t9DB85652268129FE0046878A /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 9DB85640268129EF0046878A /* Project object */;\n}\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "algorithms/AI/minimax/Sources/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "algorithms/conversion/binary-to-decimal.swift",
    "content": "import Foundation\n\n/// This function accepts a binary number as String and converts it to decimal as Int. \n/// If it's not valid binary number (a.k.a not made only from digits), it returns nil.\npublic func convertBinaryToDecimal(binary: String) -> Int? {\n    if let _ = Int(binary) {\n        var decimal = 0\n\n        let digits = binary.map { Int(String($0))! }.reversed()\n        print(digits)\n        var power = 1\n\n        for digit in digits {\n            decimal += digit * power\n\n            power *= 2\n        }\n\n        return decimal\n    }\n\n    return nil\n}"
  },
  {
    "path": "algorithms/conversion/decimal-to-binary.swift",
    "content": "/// This function accepts a non-negative number and returns its binary form as String.\npublic func convertDecimalToBinary(decimal: Int) -> String {\n    var binary = \"\"\n    var decimal = decimal\n\n    while decimal != 0 {\n        binary.insert(decimal % 2 == 0 ? \"0\" : \"1\", at: binary.startIndex)\n        decimal /= 2\n    }\n\n    return binary\n}"
  },
  {
    "path": "algorithms/palindrome/palindrome_indices.swift",
    "content": "// A palindrome is a string that reads the same forwards and backwards.\n//\n// Examples: \"level\", \"radar\", \"madam\", \"A man, a plan, a canal: Panama\".\n\nextension String {\n    \n    /// Iteratively comparing characters from the beginning and end of the string. Only include letters and numbers.\n    /// - Complexity: O(n), without allocating new space.\n    func isPalindrome() -> Bool {\n        var leftIndex = startIndex\n        var rightIndex = index(before: endIndex)\n        \n        while leftIndex < rightIndex {\n            guard self[leftIndex].isLetter || self[leftIndex].isNumber else {\n                leftIndex = index(after: leftIndex)\n                continue\n            }\n            guard self[rightIndex].isLetter || self[rightIndex].isNumber else {\n                rightIndex = index(before: rightIndex)\n                continue\n            }\n            guard self[leftIndex].lowercased() == self[rightIndex].lowercased() else {\n                return false\n            }\n            \n            leftIndex = index(after: leftIndex)\n            rightIndex = index(before: rightIndex)\n        }\n        \n        return true\n    }\n}\n"
  },
  {
    "path": "algorithms/palindrome/palindrome_recursion.swift",
    "content": "// A palindrome is a string that reads the same forwards and backwards.\n//\n// Examples: \"level\", \"radar\", \"madam\", \"A man, a plan, a canal: Panama\".\n\nextension String {\n    \n    /// Recursively comparing characters from the beginning and end of the string. Only include letters and numbers.\n    /// - Complexity: O(n), without allocating new space.\n    func isPalindrome() -> Bool {\n        isPalindromeRecursion(\n            leftIndex: startIndex,\n            rightIndex: index(before: endIndex)\n        )\n    }\n    \n    private func isPalindromeRecursion(\n        leftIndex: String.Index,\n        rightIndex: String.Index\n    ) -> Bool {\n        guard leftIndex < rightIndex else {\n            return true\n        }\n        guard self[leftIndex].isLetter || self[leftIndex].isNumber else {\n            return isPalindromeRecursion(\n                leftIndex: index(after: leftIndex),\n                rightIndex: rightIndex\n            )\n        }\n        guard self[rightIndex].isLetter || self[rightIndex].isNumber else {\n            return isPalindromeRecursion(\n                leftIndex: leftIndex,\n                rightIndex: index(before: rightIndex)\n            )\n        }\n        guard self[leftIndex].lowercased() == self[rightIndex].lowercased() else {\n            return false\n        }\n        \n        return isPalindromeRecursion(\n            leftIndex: index(after: leftIndex),\n            rightIndex: index(before: rightIndex)\n        )\n    }\n}\n"
  },
  {
    "path": "algorithms/palindrome/palindrome_reversed.swift",
    "content": "// A palindrome is a string that reads the same forwards and backwards.\n//\n// Examples: \"level\", \"radar\", \"madam\", \"A man, a plan, a canal: Panama\".\n\nextension String {\n    \n    /// Using the `reverse()` method to reverse the string and comparing it with the original. Only include letters and numbers.\n    /// - Complexity: O(n), with allocating O(n) space.\n    func isPalindrome() -> Bool {\n        let input = lowercased().filter { $0.isLetter || $0.isNumber }\n        return input == String(input.reversed())\n    }\n}\n"
  },
  {
    "path": "algorithms/parsing/shunting_yard/shunting_yard.swift",
    "content": "import Foundation\n\nenum ShuntingYard {\n    enum Operator: String, CaseIterable {\n        case power = \"^\"\n        case plus = \"+\"\n        case minus = \"-\"\n        case times = \"*\"\n        case divide = \"/\"\n    }\n\n    static func evaluate(_ string: String) -> Double {\n        let scanner = Scanner(string: string)\n        var numberStack: [Double] = []\n        var operatorStack: [Operator] = []\n\n        func applyOperator(_ op: Operator) {\n            guard let a = numberStack.popLast(), let b = numberStack.popLast() else {\n                return\n            }\n\n            numberStack.append(op.apply(a, b))\n        }\n\n        while !scanner.isAtEnd {\n            if let op = scanner.scanOperator() {\n                while let last = operatorStack.last, last.precedence > op.precedence || (op.leftAssociative && last.precedence == op.precedence) {\n                    applyOperator(last)\n                    operatorStack.removeLast()\n                }\n                operatorStack.append(op)\n            } else if let number = scanner.scanDouble() {\n                numberStack.append(number)\n            } else {\n                break\n            }\n        }\n\n        while let op = operatorStack.popLast() {\n            applyOperator(op)\n        }\n\n        return numberStack.first ?? 0\n    }\n}\n\nextension ShuntingYard.Operator {\n    var precedence: Int {\n        switch self {\n        case .power: return 3\n        case .divide, .times: return 2\n        case .plus, .minus: return 1\n        }\n    }\n\n    var leftAssociative: Bool {\n        switch self {\n        case .power: return false\n        case .plus, .minus, .times, .divide: return true\n        }\n    }\n\n    func apply(_ a: Double, _ b: Double) -> Double {\n        switch self {\n        case .power: return pow(b, a)\n        case .divide: return b / a\n        case .times: return a * b\n        case .plus: return a + b\n        case .minus: return b - a\n        }\n    }\n}\n\nprivate extension Scanner {\n    func scanOperator() -> ShuntingYard.Operator? {\n        for op in ShuntingYard.Operator.allCases {\n            if scanString(op.rawValue) != nil {\n                return op\n            }\n        }\n        return nil\n    }\n}\n\nfunc testShuntingYard() {\n    func test(_ x: String) {\n        print(x,\"=\", ShuntingYard.evaluate(x))\n    }\n\n    test(\"3 + 4 * 5\")\n    test(\"4 * 5 + 3\")\n    test(\"2 ^ 3 ^ 4\")\n    test(\"10.5 - 4 * 5\")\n    test(\"2 + 3 ^ 4\")\n    test(\"2 * 3 ^ 4\")\n    test(\"3 ^ 4\")\n}\n"
  },
  {
    "path": "data_structures/Linked List/LinkedList.swift",
    "content": "import Foundation\n\npublic class Node<Value> {\n    public var value: Value?\n    public var next: Node?\n    \n    public init(value: Value? = nil, next: Node<Value>? = nil) {\n        self.value = value\n        self.next = next\n    }\n}\n\nextension Node: CustomStringConvertible {\n    public var description: String {\n        guard let next = next else {\n            return \"\\(String(describing: value))\"\n        }\n        return \"\\(String(describing: value)) -> \" + String(describing: next) + \" \"\n    }\n}\n\npublic struct LinkedList<Value> {\n    \n    public var head: Node<Value>?\n    public var tail: Node<Value>?\n    \n    public init() {}\n    \n    public var isEmpty: Bool {\n        return head == nil\n    }\n    public mutating func push(_ value: Value) {\n        head = Node(value: value, next: head)\n        \n        if tail == nil {\n            tail = head\n        }\n    }\n    \n    public mutating func append(_ value: Value) {\n        guard !isEmpty else {\n            push(value)\n            return\n        }\n        \n        tail!.next = Node(value: value)\n        \n        tail = tail!.next\n    }\n\n    public func node(at index: Int) -> Node<Value>? {\n        var currentNode = head\n        var currentIndex = 0\n        \n        while currentNode != nil && currentIndex < index {\n            currentNode = currentNode!.next\n            currentIndex += 1\n        }\n        \n        return currentNode\n    }\n\n    @discardableResult\n    public mutating func insert(_ value: Value,\n                                after node: Node<Value>) -> Node<Value> {\n        guard tail !== node else {\n          append(value)\n          return tail!\n        }\n        node.next = Node(value: value, next: node.next)\n        \n        return node.next!\n    }\n    \n    @discardableResult\n    public mutating func pop() -> Value? {\n        defer {\n            head = head?.next\n            if isEmpty {\n                tail = nil\n            }\n        }\n        return head?.value\n    }\n    \n    @discardableResult\n    public mutating func removeLast() -> Value? {\n      guard let head = head else {\n    return nil\n    }\n      guard head.next != nil else {\n        return pop()\n      }\n      var prev = head\n      var current = head\n      while let next = current.next {\n        prev = current\n        current = next\n      }\n      prev.next = nil\n      tail = prev\n      return current.value\n    }\n    \n    @discardableResult\n    public mutating func remove(after node: Node<Value>) -> Value? {\n      defer {\n        if node.next === tail {\n          tail = node \n        }\n        node.next = node.next?.next\n      }\n      return node.next?.value\n    }\n}\n\nextension LinkedList: CustomStringConvertible {\n    public var description: String {\n        guard let head = head else {\n          return \"Empty list\"\n        }\n        return String(describing: head)\n      }\n}\n\n// Below you can find a testing Scenario for Playground.\n\n/*\n import UIKit\n\n // Test Linked List\n\n let node1 = Node(value: 1)\n let node2 = Node(value: 2)\n let node3 = Node(value: 3)\n\n node1.next = node2\n node2.next = node3\n\n print(node1)\n\n var list = LinkedList<Int>()\n list.push(3)\n list.push(2)\n list.push(1)\n\n print(list)\n\n var listAppend = LinkedList<Int>()\n\n listAppend.append(1)\n listAppend.append(2)\n listAppend.append(3)\n\n print(listAppend)\n */\n"
  },
  {
    "path": "data_structures/Stack/stack.swift",
    "content": "import Foundation\n\npublic struct Stack<T> {\n    private var elements = [T]()\n    \n    public mutating func push(_ element: T) {\n        elements.append(element)\n    }\n    \n    public mutating func pop() -> T? {\n        return elements.popLast()\n    }\n    \n    public var isEmpty: Bool {\n        return elements.isEmpty\n    }\n    \n    public var count: Int {\n        return elements.count\n    }\n    \n    public var peek: T? {\n        return elements.last\n    }\n}\n\n// The code below can be used for testing\n\nvar stack = Stack<Int>()\n\nstack.push(10)\nstack.push(20)\nstack.push(30)\n\nprint(stack.count)\nprint(stack.peek)\nprint(stack.isEmpty)\n\nprint(stack.pop())\nprint(stack.pop())\nprint(stack.pop())\nprint(stack.isEmpty)\nprint(stack.count)\n"
  },
  {
    "path": "data_structures/doubly_linked_list/DoublyLinkedList.swift",
    "content": "import Foundation\n\npublic class Node<Value> {\n    public var value: Value?\n    public var next: Node?\n    public var prev: Node?\n    \n    public init(value: Value? = nil, next: Node<Value>? = nil, prev: Node<Value>? = nil) {\n        self.value = value\n        self.next = next\n        self.prev = prev\n    }\n}\n\nextension Node: CustomStringConvertible {\n    public var description: String {\n        guard let next: Node<Value> = self.next else {\n            return \"\\(String(describing: value))\"\n        }\n        return \"\\(String(describing: value)) <-> \\(String(describing: next)) \"\n    }\n}\n\npublic struct DoublyLinkedList<Value> {\n    \n    public var head: Node<Value>?\n    public var tail: Node<Value>?\n    public var count: Int = 0\n    \n    public var isEmpty: Bool {\n        return head == nil\n    }\n\n    public mutating func push(_ value: Value) {\n        let new: Node<Value> = Node(value: value, next: head)\n        if head != nil { head!.prev = new }\n        head = new\n        if tail == nil { tail = head }\n        count += 1\n    }\n    \n    public mutating func append(_ value: Value) {\n        guard !isEmpty else {\n            push(value)\n            return\n        }\n        tail!.next = Node(value: value, prev: tail)\n        tail = tail!.next\n        count += 1\n    }\n\n    @discardableResult\n    public mutating func insert(_ value: Value,\n                                after node: Node<Value>) -> Node<Value> {\n        guard tail !== node else {\n            append(value)\n            return tail!\n        }\n        var new: Node<Value> = Node(value: value, next: node.next, prev: node)\n        node.next?.prev = new\n        node.next = new\n        count += 1\n        return node.next!\n    }\n\n    @discardableResult\n    public mutating func insert(_ value: Value,\n                                before node: Node<Value>) -> Node<Value> {\n        guard head !== node else {\n            push(value)\n            return head!\n        }\n        var new: Node<Value> = Node(value: value, next: node, prev: node.prev)\n        node.prev?.next = new\n        node.prev = new\n        count += 1\n        return node.prev!\n    }\n\n    public func node(at index: Int) -> Node<Value>? {\n        guard index > -1 || index < count else { return nil }\n        \n        let startFromTail: Bool = index > count / 2\n        var currentNode: Node<Value>? = startFromTail ? tail : head\n        var currentIndex: Int = startFromTail ? count - 1 : 0\n        var change: Int = startFromTail ? -1 : 1\n        \n        while currentNode != nil {\n            if currentIndex == index { break }\n            currentNode = startFromTail ? currentNode!.prev : currentNode!.next\n            currentIndex += change\n        }\n        \n        return currentNode\n    }\n    \n    @discardableResult\n    public mutating func pop() -> Value? {\n        defer {\n            head = head?.next\n            count -= 1\n            if isEmpty {\n                tail = nil\n            } else {\n                head!.prev = nil\n            }\n        }\n        return head?.value\n    }\n    \n    @discardableResult\n    public mutating func removeLast() -> Value? {\n        defer {\n            tail = tail?.prev\n            count -= 1\n            if isEmpty {\n                head = nil\n            } else {\n                tail!.next = nil\n            }\n        }\n        return tail?.value\n    }\n    \n    @discardableResult\n    public mutating func remove(after node: Node<Value>) -> Value? {\n        defer {\n            if node.next != nil {\n                count -= 1\n            }\n            if node.next === tail {\n                tail = node\n            }\n            if let next2node: Node<Value> = node.next?.next {\n                next2node.prev = node\n            }\n            node.next = node.next?.next\n        }\n        return node.next?.value\n    }\n\n    @discardableResult\n    public mutating func remove(before node: Node<Value>) -> Value? {\n        defer {\n            if node.prev != nil {\n                count -= 1\n            }\n            if node.prev === head {\n                head = node\n            }\n            if let prev2node: Node<Value> = node.prev?.prev {\n                prev2node.next = node\n            }\n            node.prev = node.prev?.prev\n        }\n        return node.prev?.value\n    }\n}\n\nextension DoublyLinkedList: CustomStringConvertible {\n    public var description: String {\n        guard let head: Node<Value> = self.head else {\n          return \"Empty list\"\n        }\n        return String(describing: head)\n      }\n}\n\n// Here are testing scenarios to run in a Swift playground\n\n/*\nvar list = DoublyLinkedList<Int>()\n\nlist.push(4)\nlist.push(2)\nlist.push(1)\n\nlist.append(6)\n\nvar n = list.node(at: 2)\n\nlist.insert(5, after: n!)\nlist.insert(3, before: n!)\n\nprint(list)\n\nprint(list.pop()!)\nprint(list.removeLast()!)\n\nprint(list.remove(after: n!)!)\nprint(list.remove(before: n!)!)\n\nprint(list.count)\n*/\n"
  },
  {
    "path": "data_structures/heap/heap.swift",
    "content": "struct Heap<Element> {\n    let compare: (Element, Element) -> Bool\n    private var items : [Element]\n\n    init(_ items : [Element], compare: @escaping (Element, Element) -> Bool) {\n        self.compare = compare\n        self.items = items\n        for index in (0 ..< count / 2).reversed() {\n            heapify(index)\n        }\n    }\n\n    /// The minimum item on this heap or nil if the heap is empty\n    var min: Element? {\n        return items.first\n    }\n\n    /// The number of items on this heap\n    var count: Int {\n        return items.count\n    }\n\n    /// true if this heap is empty\n    var isEmpty: Bool {\n        return items.isEmpty\n    }\n\n    /// Removes and returns the minimum item from the heap.\n    /// - returns: The minimum item from the heap or nil if the heap is empty.\n    mutating func extractMin() -> Element? {\n        guard let result = items.first else { return nil }\n\n        items.removeFirst()\n        heapify(0)\n        return result\n\n    }\n\n    /// Inserts a new item into this heap\n    /// - parameter item: The new item to insert\n    mutating func insert(item : Element) {\n        items.append(item)\n        var i = items.count - 1\n        while i > 0 && compare(items[i], items[parent(i)]) {\n            items.swapAt(i, parent(i))\n            i = parent(i)\n        }\n    }\n\n    /// Restores the heap property starting at a given index\n    /// - parameter index: The index to start at\n    private mutating func heapify(_ index : Int) {\n        var minimumIndex = index\n        if left(index) < count && compare(items[left(index)], items[minimumIndex]) {\n            minimumIndex = left(index)\n        }\n\n        if right(index) < count && compare(items[right(index)], items[minimumIndex]) {\n            minimumIndex = right(index)\n        }\n\n        if minimumIndex != index {\n            items.swapAt(minimumIndex, index)\n            heapify(minimumIndex)\n        }\n    }\n\n    /// Returns the index of the left child of an item\n    private func left(_ index : Int) -> Int {\n        return 2 * index + 1\n    }\n\n    /// Returns the index of the right child of an item\n    private func right(_ index: Int) -> Int {\n        return 2 * index + 2\n    }\n\n    /// Returns the index of the parent of an item\n    private func parent(_ index: Int) -> Int {\n        return (index - 1) / 2\n    }\n}\n\n\nextension Heap: ExpressibleByArrayLiteral where Element: Comparable {\n    init(arrayLiteral elements: Element...) {\n        self.init(elements, compare: <)\n    }\n\n    init(_ elements: [Element]) {\n        self.init(elements, compare: <)\n    }\n}\n"
  },
  {
    "path": "data_structures/queue/queue.swift",
    "content": "// Create simple queue\n// Tejas Nanaware\n\nstruct Queue<T> {\n  private var elements: [T] = []\n\n  mutating func push(_ value: T) {\n    elements.append(value)\n  }\n\n  mutating func pop() -> T? {\n    guard !elements.isEmpty else { \n      return nil\n    }\n    return elements.removeFirst()\n  }\n}\n\nvar queue = Queue<String>()\n\nqueue.push(\"One\")\nqueue.push(\"Two\")\nqueue.push(\"Three\")\n\nprint(queue.pop())\nprint(queue)\nprint(queue.pop())\nprint(queue)\nprint(queue.pop())\nprint(queue)\n"
  },
  {
    "path": "data_structures/union_find/union_find.swift",
    "content": "class UnionFindNode {\n    var rank = 0\n\n    private var parent: UnionFindNode? = nil\n\n    func findRoot() -> UnionFindNode {\n        var x = self\n        while let parent = x.parent {\n            x.parent = parent.parent ?? parent\n            x = parent\n        }\n        return x\n    }\n\n    @discardableResult\n    static func union(_ x: UnionFindNode, _ y: UnionFindNode) -> UnionFindNode {\n        var x = x.findRoot()\n        var y = y.findRoot()\n\n        guard x !== y else { return x }\n\n        if x.rank < y.rank {\n            swap(&x, &y)\n        }\n\n        y.parent = x\n        if x.rank == y.rank {\n            x.rank = y.rank + 1\n        }\n        \n        return x\n    }\n\n    static func inSameSet(_ x: UnionFindNode, _ y: UnionFindNode) -> Bool {\n        return x.findRoot() === y.findRoot()\n    }\n}\n\n\nfunc testUnionFind() {\n    let a = UnionFindNode()\n    let b = UnionFindNode()\n    let c = UnionFindNode()\n\n    print(\"a, b\", UnionFindNode.inSameSet(a, b))\n    print(\"b, c\", UnionFindNode.inSameSet(b, c))\n    print(\"a, c\", UnionFindNode.inSameSet(a, c))\n\n    print(\"Joining a, b\")\n\n    UnionFindNode.union(a, b)\n    print(\"a, b\", UnionFindNode.inSameSet(a, b))\n    print(\"b, c\", UnionFindNode.inSameSet(b, c))\n    print(\"a, c\", UnionFindNode.inSameSet(a, c))\n\n    print(\"Joining b, c\")\n\n    UnionFindNode.union(b, c)\n    print(\"a, b\", UnionFindNode.inSameSet(a, b))\n    print(\"b, c\", UnionFindNode.inSameSet(b, c))\n    print(\"a, c\", UnionFindNode.inSameSet(a, c))\n\n\n    print(\"New node d\")\n    let d = UnionFindNode()\n\n    print(\"a, d\", UnionFindNode.inSameSet(a, d))\n\n    print(\"Joining d, c\")\n    UnionFindNode.union(d, c)\n    print(\"a, d\", UnionFindNode.inSameSet(a, d))\n\n}\n"
  },
  {
    "path": "graph/BFS/BFS.swift",
    "content": "// MARK: - Basic requirement\nstruct Edge {\n    let from: Int\n    let to: Int\n}\n\npublic class Node {\n    var val: Int\n    var neighbors: [Int]\n    public init(_ val: Int) {\n        self.val = val\n        self.neighbors = []\n    }\n}\n\n// MARK: - BFS implementation\nfunc testBFS(edges: [Edge]) {\n    \n    var graph = [Int: Node]()\n    for edge in edges {\n        graph[edge.from] = Node(edge.from)\n        graph[edge.to] = Node(edge.to)\n    }\n    for edge in edges {\n        graph[edge.from]?.neighbors.append(edge.to)\n        graph[edge.to]?.neighbors.append(edge.from)\n    }\n    var visited: [Bool] = Array(repeating: false, count: graph.count + 1)\n    var nodesOfCurrentLevel: [Int] = []\n    \n    for node in 1...graph.count {\n        if visited[node] == false {\n            nodesOfCurrentLevel.append(node)\n            while(nodesOfCurrentLevel.isEmpty == false) {\n                var nodesOfNextLevel: [Int] = []\n                let sizeOfQueue = nodesOfCurrentLevel.count\n                for index in 0..<sizeOfQueue {\n                    let currNode = nodesOfCurrentLevel[index]\n                    if(visited[currNode] == true){\n                        continue\n                    }\n                    print(\"\\(currNode) \")\n                    visited[currNode] = true\n                    guard let neighbors = graph[currNode]?.neighbors else { continue }\n                    for neigh in neighbors {\n                        if visited[neigh] == false {\n                            nodesOfNextLevel.append(neigh)\n                        }\n                    }\n                }\n                nodesOfCurrentLevel = nodesOfNextLevel\n            }\n        }\n    }\n}\n\n// MARK: - Input Graph\nfunc setup() {\n    let edges = [\n        Edge(from: 1, to: 2),\n        Edge(from: 1, to: 4),\n        Edge(from: 2, to: 3),\n        Edge(from: 2, to: 4),\n        Edge(from: 2, to: 5),\n        Edge(from: 3, to: 5),\n        Edge(from: 4, to: 5),\n        Edge(from: 4, to: 6),\n        Edge(from: 5, to: 6),\n        Edge(from: 5, to: 6),\n        Edge(from: 6, to: 7),\n    ]\n    testBFS(edges: edges)\n}\n\nsetup()\n"
  },
  {
    "path": "graph/DFS/DFS.swift",
    "content": "// MARK: - Basic requirement\nstruct Edge {\n    let from: Int\n    let to: Int\n}\n\npublic class Node {\n    var val: Int\n    var neighbors: [Int]\n    public init(_ val: Int) {\n        self.val = val\n        self.neighbors = []\n    }\n}\n\n// MARK: - DFS Recursion\nfunc dfs(vertex: Int, visited: inout [Bool], graph: [Int: Node]) {\n    if visited[vertex] == true {\n        return\n    }\n    visited[vertex] = true\n    print(\"\\(vertex) \")\n    guard let neighbors = graph[vertex] else { return }\n    for neighbor in neighbors.neighbors {\n        dfs(vertex: neighbor, visited: &visited, graph: graph)\n    }\n}\n\nfunc testDFS(edges: [Edge]) {\n    var graph = [Int: Node]()\n    for edge in edges {\n        graph[edge.from] = Node(edge.from)\n        graph[edge.to] = Node(edge.to)\n    }\n    for edge in edges {\n        graph[edge.from]?.neighbors.append(edge.to)\n        graph[edge.to]?.neighbors.append(edge.from)\n    }\n    var visited: [Bool] = Array(repeating: false, count: graph.count + 1)\n    for node in 1...graph.count {\n        if visited[node] == false {\n            dfs(vertex: node, visited: &visited, graph: graph)\n        }\n    }\n}\n\n\n// MARK: - setup\nfunc setup() {\n    let edges = [\n        Edge(from: 1, to: 2),\n        Edge(from: 1, to: 4),\n        Edge(from: 2, to: 3),\n        Edge(from: 2, to: 4),\n        Edge(from: 2, to: 5),\n        Edge(from: 3, to: 5),\n        Edge(from: 4, to: 5),\n        Edge(from: 4, to: 6),\n        Edge(from: 5, to: 6),\n        Edge(from: 5, to: 6),\n        Edge(from: 6, to: 7),\n    ]\n    testDFS(edges: edges)\n}\n"
  },
  {
    "path": "graph/Graph.swift",
    "content": "struct GraphEdge<G: Graph> {\n    var from: G.Node\n    var to: G.Node\n    var value: G.EdgeValue\n}\n\nprotocol Graph {\n    typealias Edge = GraphEdge<Self>\n\n    associatedtype Node: Equatable\n    associatedtype EdgeValue\n\n    func edges(from: Node) -> [Edge]\n}\n\nstruct AdjacencyList<Node: Hashable, EdgeValue>: Graph {\n    typealias EdgeValue = EdgeValue\n    typealias Node = Node\n\n    var graph: [Node: [Edge]] = [:]\n\n    func edges(from node: Node) -> [Edge] {\n        graph[node, default: []]\n    }\n\n    mutating func insert(from: Node, to: Node, value: EdgeValue) {\n        graph[from, default: []].append(Edge(from: from, to: to, value: value))\n    }\n\n    var allEdges: [Edge] {\n        graph.values.flatMap { $0 }\n    }\n}\n\nextension AdjacencyList where EdgeValue == () {\n    mutating func insert(from: Node, to: Node) {\n        insert(from: from, to: to, value: ())\n    }\n}\n\nextension Graph {\n    func depthFirstSearch(start: Node, destination: Node) -> [Edge]? {\n        if start == destination {\n            return []\n        }\n\n        for edge in edges(from: start) {\n            if let path = depthFirstSearch(start: edge.to, destination: destination) {\n                return [edge] + path\n            }\n        }\n\n        return nil\n    }\n}\n\nextension Graph where Node: Hashable {\n    func breadthFirstSearch(start: Node, destination: Node) -> [Edge]? {\n        var queue: [(Node, [Edge])] = [(start, [])]\n        var visited: Set<Node> = [start]\n\n        while !queue.isEmpty {\n            let (current, path) = queue.removeFirst()\n            if current == destination {\n                return path\n            }\n\n            for edge in edges(from: current) where visited.insert(edge.to).inserted {\n                queue.append((edge.to, path + [edge]))\n            }\n        }\n\n        return nil\n    }\n}\n\nextension GraphEdge: CustomDebugStringConvertible {\n    var debugDescription: String {\n        if type(of: value) == Void.self {\n            return \"\\(from) -- \\(to)\"\n        } else {\n            return \"\\(from) -\\(value)- \\(to)\"\n        }\n    }\n}\n\nvar graph = AdjacencyList<String, Void>()\ngraph.insert(from: \"a\", to: \"b\")\ngraph.insert(from: \"a\", to: \"d\")\ngraph.insert(from: \"b\", to: \"c\")\ngraph.insert(from: \"c\", to: \"d\")\n\nfunc test<G: Graph>(_ message: String, _ list: [GraphEdge<G>]?) {\n    print(message)\n    if let list = list {\n        for edge in list {\n            print(edge)\n        }\n    } else {\n        print(\"Not found\")\n    }\n    print(\"\")\n}\n\ntest(\"Depth-first a -> d\", graph.depthFirstSearch(start: \"a\", destination: \"d\"))\ntest(\"Depth-first a -> e\", graph.depthFirstSearch(start: \"a\", destination: \"e\"))\n\ntest(\"Breadth-first a -> d\", graph.breadthFirstSearch(start: \"a\", destination: \"d\"))\ntest(\"Breadth-first a -> e\", graph.breadthFirstSearch(start: \"a\", destination: \"e\"))\n"
  },
  {
    "path": "graph/spanning_tree/dijkstra.swift",
    "content": "class Node : CustomStringConvertible {\n    // unique identifier required for each node\n    var identifier : Int\n    var distance : Int = Int.max\n    var edges = [Edge]()\n    var visited = false\n    \n    var description: String {\n        var edgesString = String()\n        edges.forEach{  edgesString.append($0.description)}\n        return \"{ Node, identifier: \\(identifier.description) +  Edges: \\(edgesString) + }\"\n    }\n    \n    init(visited: Bool, identifier: Int, edges: [Edge]) {\n        self.visited = visited\n        self.identifier = identifier\n        self.edges = edges\n    }\n    \n    static func == (lhs: Node, rhs: Node) -> Bool {\n        return lhs.identifier == rhs.identifier\n    }\n}\n\nclass Edge {\n    var from: Node // does not actually need to be stored!\n    var to: Node\n    var weight: Int\n    var description : String {\n        return \"{ Edge, from: \\(from.identifier), to: \\(to.identifier), weight: \\(weight) }\"\n        \n    }\n    init(to: Node, from: Node, weight: Int) {\n        self.to = to\n        self.weight = weight\n        self.from = from\n    }\n}\n\nclass Graph {\n    var nodes: [Node] = []\n}\n\n\n// Complete the quickestWayUp function below.\nfunc setupGraphwith(edges: [[Int]]) -> Graph {\n    let graph = Graph()\n    \n    // create all the nodes\n    // The first and last node need to be included, so need nodes from \"to\" and \"from\"\n    let nodeNames = Set ( edges.map{ $0[0] } + edges.map{ $0[1]} )\n    for node in nodeNames {\n        let newNode = Node(visited: false, identifier: node, edges: [])\n        graph.nodes.append(newNode)\n    }\n    \n    // create all the edges to link the nodes\n    for edge in edges {\n        if let fromNode = graph.nodes.first(where: { $0.identifier == edge[0] }) {\n            if let toNode = graph.nodes.first(where: { $0.identifier == edge[1] }) {\n                let forwardEdge = Edge(to: toNode, from: fromNode, weight: edge[2])\n                fromNode.edges.append(forwardEdge)\n            }\n        }\n    }\n    return graph\n}\n\nfunc shortestPath (source: Int, destination: Int, graph: Graph) -> Int {\n\n    var currentNode = graph.nodes.first{ $0.identifier == source }!\n    currentNode.visited = true\n    currentNode.distance = 0\n    var toVisit = [Node]()\n    toVisit.append(currentNode)\n    while ( !toVisit.isEmpty) {\n        toVisit = toVisit.filter{ $0.identifier != currentNode.identifier }\n        currentNode.visited = true\n        // Go to each adjacent vertex and update the path length\n        for connectedEdge in currentNode.edges {\n            let dist = currentNode.distance + connectedEdge.weight\n            \n            if (dist < connectedEdge.to.distance) {\n                \n                connectedEdge.to.distance = dist\n                toVisit.append(connectedEdge.to)\n                if (connectedEdge.to.visited == true) {\n                    \n                    connectedEdge.to.visited = false\n                }\n            }\n        }\n        \n        currentNode.visited = true\n        //set current node to the smallest vertex\n        if !toVisit.isEmpty {\n            currentNode = toVisit.min(by: { (a, b) -> Bool in\n                return a.distance < b.distance\n            })!\n        }\n        \n        if (currentNode.identifier == destination) {\n            return currentNode.distance\n        }\n    }\n    \n    return -1\n}\n"
  },
  {
    "path": "graph/spanning_tree/kruskal.swift",
    "content": "enum Kruskal {\n    struct Vertex {\n        let name: String\n        let node = UnionFindNode()\n\n        init(_ name: String) {\n            self.name = name\n        }\n    }\n\n    struct Edge {\n        let from: Vertex\n        let to: Vertex\n        let weight: Int\n    }\n\n    typealias Graph = [Edge]\n\n\n    static func kruskal(_ graph: Graph) -> Graph {\n        var edges = Heap(graph) { $0.weight < $1.weight }\n\n        var result: Graph = []\n        result.reserveCapacity(edges.count)\n\n        while let edge = edges.extractMin() {\n            guard !UnionFindNode.inSameSet(edge.from.node, edge.to.node) else {\n                continue\n            }\n            UnionFindNode.union(edge.from.node, edge.to.node)\n            result.append(edge)\n        }\n\n        return result\n    }\n}\n\nextension Kruskal.Vertex: CustomStringConvertible {\n    var description: String { name }\n}\n\nextension Kruskal.Edge: CustomStringConvertible {\n    var description: String { \"\\(from) --(\\(weight))-- \\(to)\" }\n}\n\nfunc testKruskal() {\n    typealias Vertex = Kruskal.Vertex\n    typealias Edge = Kruskal.Edge\n\n    let A = Vertex(\"A\")\n    let B = Vertex(\"B\")\n    let C = Vertex(\"C\")\n    let D = Vertex(\"D\")\n    let E = Vertex(\"E\")\n    let F = Vertex(\"F\")\n    let G = Vertex(\"G\")\n\n    let graph = [\n        Edge(from: A, to: B, weight: 7),\n        Edge(from: A, to: D, weight: 5),\n        Edge(from: B, to: C, weight: 8),\n        Edge(from: B, to: D, weight: 9),\n        Edge(from: B, to: E, weight: 7),\n        Edge(from: C, to: E, weight: 5),\n        Edge(from: D, to: E, weight: 15),\n        Edge(from: D, to: F, weight: 6),\n        Edge(from: E, to: F, weight: 8),\n        Edge(from: E, to: G, weight: 9),\n        Edge(from: F, to: G, weight: 11),\n    ]\n\n    print(Kruskal.kruskal(graph).map { String(describing: $0) }.joined(separator: \"\\n\") )\n}\n"
  },
  {
    "path": "recursion/fibonacci.swift",
    "content": "// The Fibonacci numbers, commonly denoted F(n) form a sequence,\n// called the Fibonacci sequence, such that # each number is the sum\n// of the two preceding ones, starting from 0 and 1. That is,\n//\n// F(0) = 0, F(1) = 1\n// F(n) = F(n - 1) + F(n - 2), for n > 1\n//\n// Given n, calculate F(n).\n//\n// @leticiafaleia\nfunc fibonacci(_ number: Int) -> Int {\n    guard number > 1 else { return number }\n    return fibonacci(number - 1) + fibonacci(number - 2)\n}\n\nfibonacci(5)\n"
  },
  {
    "path": "sorts/BubbleSort.swift",
    "content": "import Foundation\n\nextension Array where Element: Comparable {\n\n    func bubbleSort(by areInIncreasingOrder: ((Element, Element) -> Bool) = (<)) -> [Element] {\n        var data = self\n        \n        for i in 0..<(data.count-1) { \n            for j in 0..<(data.count-i-1) where areInIncreasingOrder(data[j+1], data[j]) { \n                data.swapAt(j, j + 1)\n            }\n        }\n        \n        return data\n    }\n}\n\nfunc swap<T: Comparable>(left: inout T, right: inout T) {\n    print(\"Swapping \\(left) and \\(right)\")\n    let temp = right\n    right = left\n    left = temp\n}\n\n// The code below can be used for testing\n\n// let numberList : Array<Int> = [8, 2, 10, 9, 7, 5]\n// let results: Array<Int> = numberList.bubbleSort()\n// print(results)\n"
  },
  {
    "path": "sorts/CocktailSort.swift",
    "content": "\n/*\n Cocktail Sort (or Cocktail shaker sort) is a variation of Bubble sort.\n The Bubble sort algorithm always traverses elements from left and moves the largest element\n to its correct position in first iteration and second largest in second iteration and so on.\n Cocktail Sort traverses through a given array in both directions alternatively.\n*/\n\nimport Foundation\n\nfunc cocktailSort<T: Comparable>(_ a: [T]) -> [T] {\n    var list = a\n    var swapped = true\n    var start = 0\n    var end = list.count - 1\n\n    while (swapped) {\n        swapped = false\n\n        for i in start..<end {\n            if (list[i] > list[i + 1]) {\n                list.swapAt(i, i+1)\n                swapped = true\n            }\n        }\n\n        if (!swapped) {\n            break\n        }\n        swapped = false\n        end -= 1\n\n        for index in stride(from: end-1, through: start, by: -1) {\n            if (list[index] > list[index + 1]) {\n                list.swapAt(index, index+1)\n                swapped = true\n            }\n        }\n        start += 1\n    }\n    \n    return list\n}\n\n// The code below can be used for testing\n\n//var numbers = [2, -4, 4, 6, 1, 12, 9, 0]\n//numbers = cocktailSort(numbers)\n//print(numbers)\n"
  },
  {
    "path": "sorts/InsertionSort.swift",
    "content": "import Foundation\n\nfunc insertionSort<T>(_ array: [T], by comparison: (T, T) -> Bool) -> [T] {\n    guard array.count > 1 else { return array }\n    \n    var sortedArray = array\n    \n    for index in 1..<sortedArray.count {\n        var currentIndex = index\n        let temp = sortedArray[currentIndex]\n        \n        while currentIndex > 0, comparison(temp, sortedArray[currentIndex - 1]) {\n            sortedArray[currentIndex] = sortedArray[currentIndex - 1]\n            currentIndex -= 1\n        }\n        sortedArray[currentIndex] = temp\n    }\n    \n    return sortedArray\n}\n\n// The code below can be used for testing\n\n/*\nlet numbers = [10, 1, 3, 8, 4, 2]\n\nprint(insertionSort(numbers, by: >))\nprint(insertionSort(numbers, by: <))\n\nlet names = [\"Jack\", \"Paul\", \"Olivia\", \"Emma\", \"Michael\"]\n\nprint(insertionSort(names, by: >))\nprint(insertionSort(names, by: <))\n*/\n"
  },
  {
    "path": "sorts/MergeSort.swift",
    "content": "\nimport Foundation\n\nextension Array where Element: Comparable {\n\t\n\tmutating func mergeSort(by comparison: (Element, Element) -> Bool) {\n\t\tguard self.count > 1 else {\n\t\t\treturn\n\t\t}\n\t\t_mergeSort(from: 0, to: count - 1, by: comparison)\n\t}\n\t\n\tmutating private func _mergeSort(\n\t\tfrom left: Int,\n\t\tto right: Int,\n\t\tby comparison: (Element, Element) -> Bool\n\t) {\n\t\tif left < right {\n\t\t\tlet mid = left + (right - left) / 2\n\t\t\t_mergeSort(from: 0, to: mid, by: comparison)\n\t\t\t_mergeSort(from: mid + 1, to: right, by: comparison)\n\t\t\t_merge(from: left, mid: mid, to: right, by: comparison)\n\t\t}\n\t}\n\t\n\tmutating private func _merge(\n\t\tfrom left: Int,\n\t\tmid: Int,\n\t\tto right: Int,\n\t\tby comparison: (Element, Element) -> Bool\n\t) {\n\t\tvar copy = [Element](repeating: self[left], count: right - left + 1)\n\t\tvar (leftStartIndex, rightStartIndex, currentIndex) = (left, mid + 1, 0)\n\t\tfor _ in left ... right {\n\t\t\tif leftStartIndex > mid {\n\t\t\t\tcopy[currentIndex] = self[rightStartIndex]\n\t\t\t\trightStartIndex += 1\n\t\t\t} else if rightStartIndex > right {\n\t\t\t\tcopy[currentIndex] = self[leftStartIndex]\n\t\t\t\tleftStartIndex += 1\n\t\t\t} else if comparison(self[leftStartIndex], self[rightStartIndex]) {\n\t\t\t\tcopy[currentIndex] = self[leftStartIndex]\n\t\t\t\tleftStartIndex += 1\n\t\t\t} else {\n\t\t\t\tcopy[currentIndex] = self[rightStartIndex]\n\t\t\t\trightStartIndex += 1\n\t\t\t}\n\t\t\tcurrentIndex += 1\n\t\t}\n\t\tleftStartIndex = left\n\t\tfor i in copy.indices {\n\t\t\tself[leftStartIndex] = copy[i]\n\t\t\tleftStartIndex += 1\n\t\t}\n\t}\n\t\n\tfunc mergeSorted(by comparison: (Element, Element) -> Bool) -> Array {\n\t\tvar copy = self\n\t\tcopy.mergeSort(by: comparison)\n\t\treturn copy\n\t}\n\t\n}\n\n// The code below can be used for testing\n// var numberList = [15, 2, 23, 11, 3, 9]\n// debugPrint(numberList.mergeSorted(by: >))\n// numberList.mergeSort(by: <)\n// debugPrint(numberList)\n"
  },
  {
    "path": "sorts/PancakeSort.swift",
    "content": "\n/*\n Pancake sorting is the mathematical problem of sorting a disordered stack\n of pancakes in order of size when a spatula can be inserted at any\n point in the stack and used to flip all pancakes above it.\n */\n\nimport Foundation\n\nfunc flip(array: [Int], key: Int) -> [Int] {\n    var flippedArray = array\n    var pos = key\n    var start = 0\n    var aux = 0\n\n    while (start < pos) {\n        aux = flippedArray[start]\n        flippedArray[start] = flippedArray[pos]\n        flippedArray[pos] = aux\n        \n        start += 1\n        pos -= 1\n    }\n    \n    return flippedArray\n}\n\nfunc pancakeSort(_ array: [Int]) -> [Int] {\n    var list = array\n    var currentSize = list.count\n    for _ in (1 ..< currentSize).reversed() {\n        \n        let listToSearch = list[0...currentSize-1]\n        let max = listToSearch.max() ?? 0\n        let indexOfMax = listToSearch.firstIndex(of: max) ?? 0\n\n        if indexOfMax != currentSize - 1 {\n            list = flip(array: list, key: indexOfMax)\n            list = flip(array: list, key: currentSize - 1)\n        }\n        \n        currentSize -= 1\n    }\n    \n    return list\n}\n\n// The code below can be used for testing\n//var numbers = [2, 4, 6, 12, 3, -2, 9, 14, 22, 0, 18]\n//numbers = pancakeSort(numbers)\n//print(numbers)\n"
  },
  {
    "path": "sorts/QuickSort.swift",
    "content": "import Foundation\n\nextension Array where Element: Comparable {\n    /// Sorts the array using the QuickSort algorithm in place.\n    ///\n    /// The QuickSort algorithm sorts the array by first choosing a pivot. This pivot is used to rearrange\n    /// all elements, moving the smaller ones to the left of it. This operation is then recursevely applied\n    /// to the subarrays formed around the pivot.\n    mutating func quickSort() {\n        guard count > 1 else {\n            return\n        }\n        \n        _quickSort(from: 0, to: count - 1)\n    }\n    \n    mutating private func _quickSort(from left: Int, to right: Int) {\n        guard left < right, right - left > 0 else {\n            return\n        }\n        \n        let pivotIndex = partition(from: left, to: right)\n        _quickSort(from: left, to: pivotIndex - 1)\n        _quickSort(from: pivotIndex + 1, to: right)\n    }\n    \n    /// This method is where the pivot is chosen, so the smaller elements get moved to the left,\n    /// and the bigger ones to the right.\n    mutating private func partition(from left: Int, to right: Int) -> Int {\n        /// Chooses the pivot, which in this case is always the first element, which is not very efficient.\n        let pivotIndex = left\n        swapAt(pivotIndex, right)\n        \n        let pivot = self[right]\n        var i = left\n        \n        for j in i ..< right {\n            // If the element is smaller than the pivot, move it to the left.\n            if self[j] <= pivot {\n                swapAt(i, j)\n                i += 1\n            }\n        }\n        \n        // Move the pivot to its right sorted position.\n        swapAt(i, right)\n        \n        return i\n    }\n    \n    /// Returns a sorted version of this array using the QuickSort algorithm.\n    func quickSorted() -> Array {\n        var copy = self\n        \n        copy.quickSort()\n        \n        return copy\n    }\n}\n\n// Use the following code to test it:\n// var numbers = [1002, 42, 55, 124, 205]\n// debugPrint(numbers.quickSorted())\n//\n// numbers.quickSort()\n// debugPrint(numbers)\n//\n// The console should print:\n// [42, 55, 124, 205, 1002]\n// [42, 55, 124, 205, 1002]\n"
  },
  {
    "path": "sorts/SelectionSort.swift",
    "content": "import Foundation\n\nextension Array where Element: Comparable {\nfunc selectionSort() -> Array<Element> {     \n        \n        guard self.count > 1 else {\n            return self\n        }        \n        \n        var output: Array<Element> = self\n                \n        for primaryindex in 0..<output.count {\n                        \n            var minimum = primaryindex\n            var secondaryindex = primaryindex + 1\n                        \n            while secondaryindex < output.count {\n         \n                if output[minimum] > output[secondaryindex] {\n                    minimum = secondaryindex\n                }                \n                secondaryindex += 1\n            }\n            \n            if primaryindex != minimum {\n            output.swapAt(primaryindex, minimum)\n            }            \n        }\n                \n        return output        \n    }\n}\n\n// The code below can be used for testing\n\n// let numberList : Array<Int> = [15, 2, 23, 11, 3, 9]\n// let results: Array<Int> = numberList.selectionSort()\n// print(results)\n"
  },
  {
    "path": "trees/tree.swift",
    "content": "import Foundation\n\npublic class TreeNode<T> {\n    public var value: T\n\n    public weak var parent: TreeNode?\n    public var children = [TreeNode<T>]()\n\n    public init(value: T) {\n        self.value = value\n    }\n\n    public func addChild(_ node: TreeNode<T>) {\n        children.append(node)\n        node.parent = self\n    }\n}\n\n/* Checks the node's value property, if there is no match, check the child nodes.\nRepeat the same process recursively */\nextension TreeNode where T: Equatable {\n    func search(_ value: T) -> TreeNode? {\n        if value == self.value {\n            return self\n        }\n        for child in children {\n            if let found = child.search(value) {\n                return found\n            }\n        }\n        return nil\n    }\n}\n\n// The code below can be used for testing\nlet tree = TreeNode<String>(value: \"animals\")\n\nlet reptilesNode = TreeNode<String>(value: \"reptiles\")\nlet mammalsNode = TreeNode<String>(value: \"mammals\")\n\nlet lizardsNode = TreeNode<String>(value: \"lizards\")\nlet snakesNode = TreeNode<String>(value: \"snakes\")\n\nlet dogsNode = TreeNode<String>(value: \"dogs\")\nlet humansNode = TreeNode<String>(value: \"humans\")\n\ntree.addChild(reptilesNode)\ntree.addChild(mammalsNode)\n\nreptilesNode.addChild(lizardsNode)\nreptilesNode.addChild(snakesNode)\n\nmammalsNode.addChild(dogsNode)\nmammalsNode.addChild(humansNode)\n\nprint(tree.search(\"humans\")?.value)\nprint(tree.search(\"lizards\")?.value)\nprint(tree.search(\"dragons\")?.value)\n"
  }
]