Showing preview only (4,568K chars total). Download the full file or copy to clipboard to get everything.
Repository: kodecocodes/swift-algorithm-club
Branch: master
Commit: 05c6d0bc5fa9
Files: 1063
Total size: 4.1 MB
Directory structure:
gitextract_cau619vu/
├── .github/
│ ├── CONTRIBUTING.md
│ ├── ISSUE_TEMPLATE.md
│ └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .swiftlint.yml
├── 3Sum and 4Sum/
│ ├── 3Sum.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── 4Sum.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── README.md
├── A-Star/
│ ├── AStar.swift
│ ├── Images/
│ │ ├── graph.dot
│ │ ├── step1.dot
│ │ ├── step2.dot
│ │ ├── step3.dot
│ │ ├── step4.dot
│ │ ├── step5.dot
│ │ ├── step6.dot
│ │ └── step7.dot
│ ├── README.md
│ └── Tests/
│ ├── AStarTests.swift
│ ├── AStarTests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── AStarTests.xcscheme
│ └── Info.plist
├── AVL Tree/
│ ├── AVLTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── AVLTree.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── AVLTree.swift
│ ├── Images/
│ │ ├── BalanceNotOK.graffle
│ │ ├── BalanceOK.graffle
│ │ ├── Balanced.graffle
│ │ ├── Height.graffle
│ │ └── Unbalanced.graffle
│ ├── README.markdown
│ └── Tests/
│ ├── AVLTreeTests.swift
│ ├── Info.plist
│ ├── Tests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Tests.xcscheme
│ └── TreeNodeTests.swift
├── Algorithm Design.markdown
├── All-Pairs Shortest Paths/
│ ├── APSP/
│ │ ├── APSP/
│ │ │ ├── APSP.h
│ │ │ ├── APSP.swift
│ │ │ ├── FloydWarshall.swift
│ │ │ ├── Helpers.swift
│ │ │ └── Info.plist
│ │ ├── APSP.playground/
│ │ │ ├── Contents.swift
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace/
│ │ │ │ └── contents.xcworkspacedata
│ │ │ └── timeline.xctimeline
│ │ ├── APSP.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ ├── APSP.xcscheme
│ │ │ └── APSPTests.xcscheme
│ │ ├── APSP.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── APSPTests/
│ │ ├── APSPTests.swift
│ │ └── Info.plist
│ └── README.markdown
├── Array2D/
│ ├── Array2D.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── Array2D.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Array2DTests.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── B-Tree/
│ ├── BTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── BTree.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── BTree.swift
│ ├── README.md
│ └── Tests/
│ ├── Tests/
│ │ ├── BTreeNodeTests.swift
│ │ ├── BTreeTests.swift
│ │ └── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Big-O Notation.markdown
├── Binary Search/
│ ├── BinarySearch.playground/
│ │ ├── Contents.swift
│ │ └── contents.xcplayground
│ ├── BinarySearch.swift
│ ├── README.markdown
│ └── Tests/
│ ├── BinarySearchTests.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Binary Search Tree/
│ ├── Images/
│ │ ├── DeleteLeaf.graffle
│ │ ├── DeleteOneChild.graffle
│ │ ├── DeleteTwoChildren.graffle
│ │ ├── MinimumMaximum.graffle
│ │ ├── Searching.graffle
│ │ ├── Traversing.graffle
│ │ ├── Tree1.graffle
│ │ └── Tree2.graffle
│ ├── README.markdown
│ ├── Solution 1/
│ │ ├── BinarySearchTree.playground/
│ │ │ ├── Contents.swift
│ │ │ ├── Sources/
│ │ │ │ └── BinarySearchTree.swift
│ │ │ ├── contents.xcplayground
│ │ │ └── playground.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── Tests/
│ │ ├── BinarySearchTreeTests.swift
│ │ ├── Info.plist
│ │ └── Tests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Tests.xcscheme
│ └── Solution 2/
│ ├── BinarySearchTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── BinarySearchTree.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── BinarySearchTree.swift
├── Binary Tree/
│ ├── BinaryTree.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── BinaryTree.swift
│ ├── Images/
│ │ ├── BinaryTree.graffle
│ │ └── Operations.graffle
│ └── README.markdown
├── Bit Set/
│ ├── BitSet.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── BitSet.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── README.markdown
├── Bloom Filter/
│ ├── BloomFilter.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── BloomFilter.swift
│ ├── README.markdown
│ └── Tests/
│ ├── BloomFilterTests.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Bounded Priority Queue/
│ ├── BoundedPriorityQueue.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── BoundedPriorityQueue.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── BoundedPriorityQueue.swift
│ ├── README.markdown
│ └── Tests/
│ ├── BoundedPriorityQueueTests.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Boyer-Moore-Horspool/
│ ├── BoyerMooreHorspool.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── timeline.xctimeline
│ ├── BoyerMooreHorspool.swift
│ ├── README.markdown
│ └── Tests/
│ ├── BoyerMooreHorspoolTests.swift
│ ├── BoyerMooreTests.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Breadth-First Search/
│ ├── BreadthFirstSearch.playground/
│ │ ├── Pages/
│ │ │ └── Simple example.xcplaygroundpage/
│ │ │ └── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Edge.swift
│ │ │ ├── Graph.swift
│ │ │ ├── Node.swift
│ │ │ └── Queue.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── BreadthFirstSearch.swift
│ ├── Images/
│ │ ├── AnimatedExample.graffle
│ │ ├── AnimatedExample.psd
│ │ └── TraversalTree.graffle
│ ├── README.markdown
│ └── Tests/
│ ├── BreadthFirstSearchTests.swift
│ ├── Graph.swift
│ ├── Info.plist
│ ├── Queue.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Brute-Force String Search/
│ ├── BruteForceStringSearch.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── BruteForceStringSearch.swift
│ └── README.markdown
├── Bubble Sort/
│ ├── MyPlayground.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── BubbleSort.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── README.markdown
├── Bucket Sort/
│ ├── BucketSort.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── BucketSort.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── BucketSort.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Info.plist
│ ├── Tests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Closest Pair/
│ ├── ClosestPair.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── README.markdown
├── Comb Sort/
│ ├── Comb Sort.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── Comb Sort.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── Comb Sort.swift
│ ├── README.markdown
│ └── Tests/
│ ├── CombSortTests.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Combinatorics/
│ ├── Combinatorics.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── README.markdown
├── Convex Hull/
│ ├── Convex Hull/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ └── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Base.lproj/
│ │ │ └── LaunchScreen.storyboard
│ │ ├── Info.plist
│ │ └── View.swift
│ ├── Convex Hull.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Tests.xcscheme
│ ├── README.md
│ └── Tests/
│ ├── Info.plist
│ └── Tests.swift
├── Count Occurrences/
│ ├── CountOccurrences.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── CountOccurrences.swift
│ └── README.markdown
├── CounterClockWise/
│ ├── CounterClockWise.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── CounterClockWise.swift
│ └── README.md
├── Counting Sort/
│ ├── CountingSort.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── CountingSort.swift
│ ├── README.markdown
│ └── Tests/
│ ├── CountingSortTest.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Depth-First Search/
│ ├── DepthFirstSearch.playground/
│ │ ├── Edge.o
│ │ ├── Graph.o
│ │ ├── Node.o
│ │ ├── Pages/
│ │ │ └── Simple Example.xcplaygroundpage/
│ │ │ └── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Edge.swift
│ │ │ ├── Graph.swift
│ │ │ └── Node.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── DepthFirstSearch.swift
│ ├── Images/
│ │ ├── AnimatedExample.graffle
│ │ ├── AnimatedExample.psd
│ │ └── TraversalTree.graffle
│ ├── README.markdown
│ └── Tests/
│ ├── DepthFirstSearchTests.swift
│ ├── Graph.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Deque/
│ ├── Deque-Optimized.swift
│ ├── Deque-Simple.swift
│ ├── Deque.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── README.markdown
├── Dijkstra Algorithm/
│ ├── Dijkstra.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Dijkstra.swift
│ │ │ └── Vertex.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── README.md
│ └── VisualizedDijkstra.playground/
│ ├── Contents.swift
│ ├── Sources/
│ │ ├── CustomUI/
│ │ │ ├── EdgeRepresentation.swift
│ │ │ ├── ErrorView.swift
│ │ │ ├── MyShapeLayer.swift
│ │ │ ├── RoundedButton.swift
│ │ │ └── VertexView.swift
│ │ ├── Graph.swift
│ │ ├── GraphColors.swift
│ │ ├── GraphView.swift
│ │ ├── SimpleObjects/
│ │ │ ├── Edge.swift
│ │ │ └── Vertex.swift
│ │ └── Window.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── DiningPhilosophers/
│ ├── DiningPhilosophers.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ ├── DiningPhilosophers.xcscheme
│ │ └── xcschememanagement.plist
│ ├── LICENSE
│ ├── Package.swift
│ ├── README.md
│ └── Sources/
│ └── main.swift
├── Egg Drop Problem/
│ ├── EggDrop.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── EggDrop.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ ├── EggDrop.swift
│ └── README.markdown
├── Encode and Decode Tree/
│ ├── EncodeAndDecodeTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── EncodeAndDecodeTree.swift
│ │ └── contents.xcplayground
│ ├── EncodeAndDecodeTree.swift
│ └── readme.md
├── Fixed Size Array/
│ ├── FixedSizeArray.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── timeline.xctimeline
│ ├── Images/
│ │ └── FixedSizeArrays.graffle
│ └── README.markdown
├── Fizz Buzz/
│ ├── FizzBuzz.playground/
│ │ └── Contents.swift
│ ├── FizzBuzz.swift
│ └── README.markdown
├── GCD/
│ ├── GCD.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── GCD.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── README.markdown
├── Genetic/
│ ├── README.markdown
│ ├── gen.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── gen.swift
├── Graph/
│ ├── Graph/
│ │ ├── AdjacencyListGraph.swift
│ │ ├── AdjacencyMatrixGraph.swift
│ │ ├── Edge.swift
│ │ ├── Graph.h
│ │ ├── Graph.swift
│ │ ├── Info.plist
│ │ └── Vertex.swift
│ ├── Graph.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── timeline.xctimeline
│ ├── Graph.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ ├── Graph.xcscheme
│ │ └── GraphTests.xcscheme
│ ├── Graph.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ ├── GraphTests/
│ │ ├── GraphTests.swift
│ │ └── Info.plist
│ ├── Images/
│ │ ├── AdjacencyList.graffle
│ │ ├── AdjacencyMatrix.graffle
│ │ ├── ChordMap.graffle
│ │ ├── CoreData.graffle
│ │ ├── DAG.graffle
│ │ ├── Demo1.graffle
│ │ ├── Flights.graffle
│ │ ├── FlightsDirected.graffle
│ │ ├── Graph.graffle
│ │ ├── SocialNetwork.graffle
│ │ ├── StateMachine.graffle
│ │ ├── Tasks.graffle
│ │ └── TreeAndList.graffle
│ └── README.markdown
├── Hash Set/
│ ├── HashSet.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── HashSet.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── HashSet.swift
│ ├── Images/
│ │ └── CombineSets.graffle
│ └── README.markdown
├── Hash Table/
│ ├── HashTable.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── HashTable.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── README.markdown
├── Hashed Heap/
│ ├── HashedHeap.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Hashed Heap Tests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Hashed Heap Tests.xcscheme
│ ├── HashedHeapTests.swift
│ └── Info.plist
├── HaversineDistance/
│ ├── HaversineDistance.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── README.md
├── Heap/
│ ├── Heap.swift
│ ├── Images/
│ │ ├── Array.graffle
│ │ ├── Heap1.graffle
│ │ ├── HeapShape.graffle
│ │ ├── Insert1.graffle
│ │ ├── Insert2.graffle
│ │ ├── Insert3.graffle
│ │ ├── LargeHeap.graffle
│ │ ├── RegularTree.graffle
│ │ ├── Remove1.graffle
│ │ ├── Remove2.graffle
│ │ ├── Remove3.graffle
│ │ ├── Remove4.graffle
│ │ ├── Remove5.graffle
│ │ └── SortedArray.graffle
│ ├── README.markdown
│ └── Tests/
│ ├── HeapTests.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Heap Sort/
│ ├── HeapSort.swift
│ ├── Images/
│ │ └── MaxHeap.graffle
│ ├── README.markdown
│ └── Tests/
│ ├── HeapSortTests.swift
│ ├── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Huffman Coding/
│ ├── Huffman.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Heap.swift
│ │ │ ├── Huffman.swift
│ │ │ ├── NSData+Bits.swift
│ │ │ └── PriorityQueue.swift
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── timeline.xctimeline
│ ├── Huffman.swift
│ ├── Images/
│ │ ├── BuildTree.graffle
│ │ ├── BuildTree.psd
│ │ ├── Compression.graffle
│ │ ├── Decompression.graffle
│ │ └── Tree.graffle
│ ├── NSData+Bits.swift
│ └── README.markdown
├── Insertion Sort/
│ ├── InsertionSort.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── InsertionSort.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Info.plist
│ ├── InsertionSortTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Introsort/
│ ├── HeapSort.swift
│ ├── InsertionSort.swift
│ ├── IntroSort.swift
│ ├── Introsort.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ ├── HeapSort.swift
│ │ │ ├── InsertionSort.swift
│ │ │ ├── Partition.swift
│ │ │ ├── Randomize.swift
│ │ │ └── Sort3.swift
│ │ └── contents.xcplayground
│ ├── Partition.swift
│ ├── README.markdown
│ ├── Randomize.swift
│ └── Sort3.swift
├── K-Means/
│ ├── KMeans.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Info.plist
│ ├── KMeansTests.swift
│ ├── Tests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Tests.xcscheme
│ └── Vector.swift
├── Karatsuba Multiplication/
│ ├── KaratsubaMultiplication.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── KaratsubaMultiplication.swift
│ ├── README.markdown
│ └── Tests/
│ ├── KaratsubaMultiplicationTests.swift
│ ├── Tests/
│ │ └── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Knuth-Morris-Pratt/
│ ├── KnuthMorrisPratt.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── KnuthMorrisPratt.swift
│ └── README.markdown
├── Kth Largest Element/
│ ├── README.markdown
│ └── kthLargest.playground/
│ ├── Contents.swift
│ ├── Sources/
│ │ └── kthLargest.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ └── kthLargest.xcscmblueprint
├── LICENSE.txt
├── LRU Cache/
│ ├── LRUCache.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ ├── LRUCache.swift
│ │ │ └── LinkedList.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── LRUCache.swift
│ └── Readme.md
├── Linear Regression/
│ ├── LinearRegression.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── README.markdown
├── Linear Search/
│ ├── LinearSearch.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── LinearSearch.swift
│ └── README.markdown
├── Linked List/
│ ├── LinkedList.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── LinkedList.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Info.plist
│ ├── LinkedListTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Longest Common Subsequence/
│ ├── LongestCommonSubsequence.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── LongestCommonSubsequence.swift
│ ├── README.markdown
│ └── Tests/
│ ├── LongestCommonSubsequenceTests.swift
│ ├── Tests/
│ │ └── Info.plist
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Merge Sort/
│ ├── MergeSort.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── MergeSort.swift
│ └── README.markdown
├── Miller-Rabin Primality Test/
│ ├── MRPrimality.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── MillerRabin.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── MRPrimality.swift
│ └── README.markdown
├── Minimum Edit Distance/
│ ├── MinimumEditDistance.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── README.markdown
├── Minimum Spanning Tree/
│ ├── Kruskal.swift
│ ├── MinimumSpanningTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Graph.swift
│ │ │ ├── Heap.swift
│ │ │ ├── PriorityQueue.swift
│ │ │ └── UnionFind.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── Prim.swift
│ └── README.markdown
├── Minimum Spanning Tree (Unweighted)/
│ ├── Images/
│ │ ├── Graph.sketch
│ │ ├── MinimumSpanningTree.sketch
│ │ └── Tree.graffle
│ ├── MinimumSpanningTree.playground/
│ │ ├── Pages/
│ │ │ └── Minimum spanning tree example.xcplaygroundpage/
│ │ │ └── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Edge.swift
│ │ │ ├── Graph.swift
│ │ │ ├── Node.swift
│ │ │ └── Queue.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── MinimumSpanningTree.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Graph.swift
│ ├── Info.plist
│ ├── MinimumSpanningTreeTests.swift
│ ├── Queue.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── MinimumCoinChange/
│ ├── LICENSE
│ ├── Package.swift
│ ├── README.md
│ ├── Sources/
│ │ └── MinimumCoinChange.swift
│ └── Tests/
│ ├── LinuxMain.swift
│ └── MinimumCoinChangeTests/
│ └── MinimumCoinChangeTests.swift
├── Monty Hall Problem/
│ ├── MontyHall.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── README.markdown
├── Multiset/
│ ├── Multiset.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── Multiset.swift
│ │ └── contents.xcplayground
│ └── README.markdown
├── Myers Difference Algorithm/
│ ├── MyersDifferenceAlgorithm.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── MyersDifferenceAlgorithm.swift
│ │ └── contents.xcplayground
│ ├── MyersDifferenceAlgorithm.swift
│ └── README.md
├── Naive Bayes Classifier/
│ ├── NaiveBayes.playground/
│ │ ├── Contents.swift
│ │ ├── Resources/
│ │ │ └── wine.csv
│ │ ├── Sources/
│ │ │ └── NaiveBayes.swift
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── timeline.xctimeline
│ ├── NaiveBayes.swift
│ └── README.md
├── Octree/
│ ├── Octree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── Octree.swift
│ │ ├── contents.xcplayground
│ │ └── timeline.xctimeline
│ └── README.md
├── Ordered Array/
│ ├── OrderedArray.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── OrderedArray.swift
│ └── README.markdown
├── Ordered Set/
│ ├── OrderedSet.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── OrderedSet.swift
│ │ └── contents.xcplayground
│ ├── OrderedSet.swift
│ └── README.markdown
├── Palindromes/
│ ├── Palindromes.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── Palindrome.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── README.markdown
│ └── Test/
│ ├── Palindrome.swift
│ ├── Test/
│ │ ├── Info.plist
│ │ └── Test.swift
│ └── Test.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Test.xcscheme
├── Points Lines Planes/
│ ├── Points Lines Planes/
│ │ ├── 2D/
│ │ │ ├── Line2D.swift
│ │ │ └── Point2D.swift
│ │ └── main.swift
│ ├── Points Lines Planes.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── README.md
├── Priority Queue/
│ ├── PriorityQueue.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Info.plist
│ ├── PriorityQueueTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── QuadTree/
│ ├── QuadTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── QuadTree.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── README.md
│ └── Tests/
│ ├── Tests/
│ │ ├── Info.plist
│ │ └── Tests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ └── project.xcworkspace/
│ └── contents.xcworkspacedata
├── Queue/
│ ├── Queue-Optimized.swift
│ ├── Queue-Simple.swift
│ ├── Queue.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── README.markdown
│ └── Tests/
│ ├── Info.plist
│ ├── QueueTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Quicksort/
│ ├── Images/
│ │ └── Example.graffle
│ ├── Quicksort.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── Quicksort.swift
│ ├── README.markdown
│ └── Tests/
│ ├── Info.plist
│ ├── QuicksortTests.swift
│ ├── SortingTestHelpers.swift
│ └── Tests-Quicksort.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests-Quicksort.xcscheme
├── README.markdown
├── Rabin-Karp/
│ ├── README.markdown
│ ├── Rabin-Karp.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── rabin-karp.swift
├── Radix Sort/
│ ├── RadixSort.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── radixSort.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── RadixSortExample.swift
│ ├── ReadMe.md
│ ├── Tests/
│ │ ├── Info.plist
│ │ ├── RadixSortTests.swift
│ │ └── Tests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Tests.xcscheme
│ └── radixSort.swift
├── Radix Tree/
│ ├── README.markdown
│ ├── RadixTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── RadixTree.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── RadixTree.swift
├── Red-Black Tree/
│ ├── README.markdown
│ ├── RedBlackTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── RedBlackTree.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── RedBlackTree.swift
├── Ring Buffer/
│ ├── README.markdown
│ ├── RingBuffer.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── RingBuffer.swift
├── Rootish Array Stack/
│ ├── README.md
│ ├── RootishArrayStack.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── RootishArrayStack.swift
│ └── Tests/
│ ├── Info.plist
│ ├── RootishArrayStack.swift
│ ├── RootishArrayStackTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Run-Length Encoding/
│ ├── README.markdown
│ └── RLE.playground/
│ ├── Contents.swift
│ ├── Sources/
│ │ └── RLE.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace/
│ └── contents.xcworkspacedata
├── Segment Tree/
│ ├── LazyPropagation/
│ │ ├── LazyPropagation.playground/
│ │ │ ├── Contents.swift
│ │ │ ├── contents.xcplayground
│ │ │ └── playground.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── README.markdown
│ ├── README.markdown
│ ├── SegmentTree.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── SegmentTree.swift
├── Select Minimum Maximum/
│ ├── Maximum.swift
│ ├── Minimum.swift
│ ├── MinimumMaximumPairs.swift
│ ├── README.markdown
│ ├── SelectMinimumMaximum.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── Tests/
│ ├── Info.plist
│ ├── MaximumTests.swift
│ ├── MinimumMaximumPairsTests.swift
│ ├── MinimumTests.swift
│ ├── TestHelper.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Selection Sampling/
│ ├── README.markdown
│ ├── SelectionSampling.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── SelectionSampling.swift
├── Selection Sort/
│ ├── README.markdown
│ ├── SelectionSort.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── SelectionSort.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── SelectionSort.swift
│ └── Tests/
│ ├── Info.plist
│ ├── SelectionSortTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Set Cover (Unweighted)/
│ ├── README.markdown
│ ├── SetCover.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ ├── RandomArrayOfSets.swift
│ │ │ └── SetCover.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── SetCover.swift
├── Shell Sort/
│ ├── README.markdown
│ ├── Shell Sort.playground/
│ │ ├── Contents.swift
│ │ └── contents.xcplayground
│ ├── ShellSortExample.swift
│ ├── Tests/
│ │ ├── Info.plist
│ │ ├── ShellSortTests.swift
│ │ └── Tests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Tests.xcscheme
│ └── shellsort.swift
├── Shortest Path (Unweighted)/
│ ├── Images/
│ │ └── Graph.graffle
│ ├── README.markdown
│ ├── ShortestPath.playground/
│ │ ├── Pages/
│ │ │ └── Shortest path example.xcplaygroundpage/
│ │ │ └── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Edge.swift
│ │ │ ├── Graph.swift
│ │ │ ├── Node.swift
│ │ │ └── Queue.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── ShortestPath.swift
│ └── Tests/
│ ├── Graph.swift
│ ├── Info.plist
│ ├── Queue.swift
│ ├── ShortestPathTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Shuffle/
│ ├── README.markdown
│ ├── Shuffle.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── Shuffle.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── Shuffle.swift
├── Shunting Yard/
│ ├── README.markdown
│ ├── ShuntingYard.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── Stack.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── ShuntingYard.swift
├── Simulated annealing/
│ ├── README.md
│ ├── simann.swift
│ └── simann_example.swift
├── Single-Source Shortest Paths (Weighted)/
│ ├── README.markdown
│ ├── SSSP/
│ │ ├── BellmanFord.swift
│ │ ├── Info.plist
│ │ ├── SSSP.h
│ │ └── SSSP.swift
│ ├── SSSP.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── SSSP.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ ├── SSSP.xcscheme
│ │ └── SSSPTests.xcscheme
│ ├── SSSP.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── WorkspaceSettings.xcsettings
│ └── SSSPTests/
│ ├── Info.plist
│ └── SSSPTests.swift
├── Singly Linked List/
│ ├── KeyValuePair.swift
│ ├── README.markdown
│ ├── SinglyLinkedList.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── SinglyLinkedList.swift
│ └── Tests/
│ ├── Tests/
│ │ ├── Info.plist
│ │ └── SinglyLinkedListTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Skip-List/
│ ├── README.md
│ ├── SkipList.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── SkipList.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── SkipList.swift
├── Slow Sort/
│ ├── README.markdown
│ ├── SlowSort.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── SlowSort.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── SlowSort.swift
├── Sorted Set/
│ ├── README.markdown
│ ├── SortedSet.playground/
│ │ ├── Pages/
│ │ │ ├── Example 1.xcplaygroundpage/
│ │ │ │ ├── Contents.swift
│ │ │ │ └── timeline.xctimeline
│ │ │ ├── Example 2.xcplaygroundpage/
│ │ │ │ └── Contents.swift
│ │ │ └── Example 3.xcplaygroundpage/
│ │ │ └── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Player.swift
│ │ │ ├── Random.swift
│ │ │ └── SortedSet.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── SortedSet.swift
├── Sparse Table/
│ ├── README.markdown
│ └── Sparse Table.playground/
│ ├── Contents.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace/
│ └── contents.xcworkspacedata
├── Splay Tree/
│ ├── SplayTree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── SplayTree.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── SplayTree.swift
│ ├── Tests/
│ │ ├── Info.plist
│ │ ├── SplayTreeTests.swift
│ │ ├── Tests-Bridging-Header.h
│ │ └── Tests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Tests.xcscheme
│ └── readme.md
├── Stack/
│ ├── README.markdown
│ ├── Stack.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── Stack.swift
│ └── Tests/
│ ├── Info.plist
│ ├── StackTests.swift
│ └── Tests.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── xcshareddata/
│ └── xcschemes/
│ └── Tests.xcscheme
├── Strassen Matrix Multiplication/
│ ├── README.markdown
│ └── StrassensMatrixMultiplication.playground/
│ ├── Contents.swift
│ ├── Sources/
│ │ ├── Matrix.swift
│ │ └── Number.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace/
│ └── contents.xcworkspacedata
├── Ternary Search Tree/
│ ├── README.markdown
│ ├── TST.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ ├── TSTNode.swift
│ │ │ ├── TernarySearchTree.swift
│ │ │ └── Utils.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── TSTNode.swift
│ ├── TernarySearchTree.swift
│ ├── Tests/
│ │ ├── Info.plist
│ │ ├── TernarySearchTreeTests.swift
│ │ └── Tests.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Tests.xcscheme
│ └── Utils.swift
├── Threaded Binary Tree/
│ ├── README.markdown
│ └── ThreadedBinaryTree.playground/
│ ├── Contents.swift
│ ├── Sources/
│ │ └── ThreadedBinaryTree.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── Topological Sort/
│ ├── Graph.swift
│ ├── Images/
│ │ ├── Algorithms.graffle
│ │ ├── Example.graffle
│ │ ├── Graph.graffle
│ │ ├── GraphResult.graffle
│ │ ├── InvalidSort.graffle
│ │ └── TopologicalSort.graffle
│ ├── README.markdown
│ ├── Tests/
│ │ ├── Info.plist
│ │ ├── Tests.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ └── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Tests.xcscheme
│ │ └── TopologicalSortTests.swift
│ ├── Topological Sort.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ ├── Graph.swift
│ │ │ ├── TopologicalSort1.swift
│ │ │ ├── TopologicalSort2.swift
│ │ │ └── TopologicalSort3.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ ├── TopologicalSort1.swift
│ ├── TopologicalSort2.swift
│ └── TopologicalSort3.swift
├── Treap/
│ ├── Treap/
│ │ ├── Treap/
│ │ │ └── Info.plist
│ │ ├── Treap.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Tests.xcscheme
│ │ └── TreapTests/
│ │ ├── Info.plist
│ │ └── TreapTests.swift
│ ├── Treap.swift
│ ├── TreapCollectionType.swift
│ └── TreapMergeSplit.swift
├── Tree/
│ ├── Images/
│ │ ├── Cycles.graffle
│ │ ├── Example.graffle
│ │ ├── ParentChildren.graffle
│ │ └── Tree.graffle
│ ├── README.markdown
│ ├── Tree.playground/
│ │ ├── Contents.swift
│ │ ├── Sources/
│ │ │ └── Tree.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── Tree.swift
├── Trie/
│ ├── ReadMe.md
│ └── Trie/
│ ├── Trie/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ └── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Base.lproj/
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── ReadMe.md
│ │ ├── Trie.swift
│ │ ├── ViewController.swift
│ │ └── dictionary.txt
│ ├── Trie.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata/
│ │ └── xcbaselines/
│ │ └── EB798E0A1DFEF79900F0628D.xcbaseline/
│ │ ├── 6ABF2F62-9363-4450-8DE1-D20F57026950.plist
│ │ └── Info.plist
│ ├── TrieTests/
│ │ ├── Info.plist
│ │ └── TrieTests.swift
│ └── TrieUITests/
│ ├── Info.plist
│ └── TrieUITests.swift
├── Two-Sum Problem/
│ ├── README.markdown
│ ├── Solution 1/
│ │ └── 2Sum.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── Solution 2/
│ └── 2Sum.playground/
│ ├── Contents.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── Under Construction.markdown
├── Union-Find/
│ ├── README.markdown
│ └── UnionFind.playground/
│ ├── Contents.swift
│ ├── Sources/
│ │ ├── UnionFindQuickFind.swift
│ │ ├── UnionFindQuickUnion.swift
│ │ ├── UnionFindWeightedQuickFind.swift
│ │ ├── UnionFindWeightedQuickUnion.swift
│ │ └── UnionFindWeightedQuickUnionPathCompression.swift
│ ├── contents.xcplayground
│ └── playground.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── What are Algorithms.markdown
├── Why Algorithms.markdown
├── Z-Algorithm/
│ ├── README.markdown
│ ├── ZAlgorithm.swift
│ ├── ZetaAlgorithm.playground/
│ │ ├── Contents.swift
│ │ ├── contents.xcplayground
│ │ └── playground.xcworkspace/
│ │ └── contents.xcworkspacedata
│ └── ZetaAlgorithm.swift
├── gfm-render.sh
└── install_swiftlint.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributing Guidelines
Want to help out with the Swift Algorithm Club? Great! While we don't have strict templates on the format of each contribution, we do have a few guidelines that should be kept in mind:
**Readability**
Our repo is all about learning. The `README` file is the cake, and the sample code is the cherry on top. A good contribution has succinct explanations supported by diagrams. Code is best introduced in chunks, weaved into the explanations where relevant.
> When choosing between brevity and performance, err to the side of brevity as long as the time complexity of the particular implementation is the same. You can make a note afterwards suggesting a more performant way of doing things.
**API Design Guidelines**
A good contribution abides to the [Swift API Guidelines](https://swift.org/documentation/api-design-guidelines/). We review the pull requests with this in mind.
**Swift Language Guidelines**
We follow the following Swift [style guide](https://github.com/raywenderlich/swift-style-guide).
## Contribution Categories
### Refinement
Unit tests. Fixes for typos. No contribution is too small. :-)
The repository has over 100 different data structures and algorithms. We're always interested in improvements to existing implementations and better explanations. Suggestions for making the code more Swift-like or to make it fit better with the standard library are most welcome.
### New Contributions
Before writing about something new, you should do 2 things:
1. Check the main page for existing implementations
2. Check the [pull requests](https://github.com/raywenderlich/swift-algorithm-club/pulls) for "claimed" topics. More info on that below.
If what you have in mind is a new addition, please follow this process when submitting your contribution:
1. Create a pull request to "claim" an algorithm or data structure. This is to avoid having multiple people working on the same thing.
2. Use this [style guide](https://github.com/raywenderlich/swift-style-guide) for writing code (more or less).
3. Write an explanation of how the algorithm works. Include **plenty of examples** for readers to follow along. Pictures are good. Take a look at [the explanation of quicksort](../Quicksort/) to get an idea.
4. Include your name in the explanation, something like *Written by Your Name* at the end of the document.
5. Add a playground and/or unit tests.
For the unit tests:
- Add the unit test project to `.travis.yml` so they will be run on [Travis-CI](https://travis-ci.org/raywenderlich/swift-algorithm-club). Add a line to `.travis.yml` like this:
```
- xctool test -project ./Algorithm/Tests/Tests.xcodeproj -scheme Tests
```
- Configure the Test project's scheme to run on Travis-CI:
- Open **Product -> Scheme -> Manage Schemes...**
- Uncheck **Autocreate schemes**
- Check **Shared**

## Want to chat?
This isn't just a repo with a bunch of code... If you want to learn more about how an algorithm works or want to discuss better ways of solving problems, then open a [Github issue](https://github.com/raywenderlich/swift-algorithm-club/issues) and we'll talk!
================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
### Brief Intro
<!-- Describe the issue briefly.-->
### More Details
<!-- If necessary, start off with the code snippet. Put the code in between ``` to format them into code blocks.-->
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!-- Thanks for contributing to the SAC! Before you submit your pull request, please make sure to check the following boxes by putting an x in the [ ] -->
### Checklist
- [ ] I've looked at the [contribution guidelines](https://github.com/raywenderlich/swift-algorithm-club/blob/master/.github/CONTRIBUTING.md).
- [ ] This pull request is complete and ready for review.
### Description
<!-- In a short paragraph, describe the PR -->
================================================
FILE: .gitignore
================================================
# Xcode
build/
DerivedData/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
*.xccheckout
*.moved-aside
*.xcuserstate
xcuserdata
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
!default.xcworkspace
profile
*.hmap
*.ipa
# CocoaPods
Pods/
!Podfile.lock
# Temporary files
.DS_Store
.Trashes
.Spotlight-V100
*.swp
*.lock
================================================
FILE: .swiftlint.yml
================================================
cyclomatic_complexity: 12
file_length: 550
function_body_length: 80
function_parameter_count: 8
line_length: 150
type_body_length: 300
variable_name:
min_length:
error: 1
warning: 1
excluded:
- N
disabled_rules:
- valid_docs
custom_rules:
smiley_face:
name: "Smiley Face"
regex: '( :\))'
match_kinds:
- comment
- string
message: "A closing parenthesis smiley :) creates a half-hearted smile, and thus is not preferred. Use :]"
severity: warning
================================================
FILE: 3Sum and 4Sum/3Sum.playground/Contents.swift
================================================
// last checked with Xcode 10.1
#if swift(>=4.2)
print("Hello, Swift 4.2!")
#endif
extension Collection where Element: Equatable {
/// In a sorted collection, replaces the given index with a successor mapping to a unique element.
///
/// - Parameter index: A valid index of the collection. `index` must be less than `endIndex`
func formUniqueIndex(after index: inout Index) {
var prev = index
repeat {
prev = index
formIndex(after: &index)
} while index < endIndex && self[prev] == self[index]
}
}
extension BidirectionalCollection where Element: Equatable {
/// In a sorted collection, replaces the given index with a predecessor that maps to a unique element.
///
/// - Parameter index: A valid index of the collection. `index` must be greater than `startIndex`.
func formUniqueIndex(before index: inout Index) {
var prev = index
repeat {
prev = index
formIndex(before: &index)
} while index > startIndex && self[prev] == self[index]
}
}
func threeSum<T: BidirectionalCollection>(_ collection: T, target: T.Element) -> [[T.Element]] where T.Element: Numeric & Comparable {
let sorted = collection.sorted()
var ret: [[T.Element]] = []
var l = sorted.startIndex
ThreeSum: while l < sorted.endIndex { defer { sorted.formUniqueIndex(after: &l) }
var m = sorted.index(after: l)
var r = sorted.index(before: sorted.endIndex)
TwoSum: while m < r && r < sorted.endIndex {
let sum = sorted[l] + sorted[m] + sorted[r]
if sum == target {
ret.append([sorted[l], sorted[m], sorted[r]])
sorted.formUniqueIndex(after: &m)
sorted.formUniqueIndex(before: &r)
} else if sum < target {
sorted.formUniqueIndex(after: &m)
} else {
sorted.formUniqueIndex(before: &r)
}
}
}
return ret
}
// Answer: [[-1, 0, 1], [-1, -1, 2]]
threeSum([-1, 0, 1, 2, -1, -4], target: 0)
// Answer: [[-1, -1, 2], [-1, 0, 1]]
threeSum([-1, -1, -1, -1, 2, 1, -4, 0], target: 0)
// Answer: [[-1, -1, 2]]
threeSum([-1, -1, -1, -1, -1, -1, 2], target: 0)
================================================
FILE: 3Sum and 4Sum/3Sum.playground/contents.xcplayground
================================================
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios'>
<timeline fileName='timeline.xctimeline'/>
</playground>
================================================
FILE: 3Sum and 4Sum/3Sum.playground/playground.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: 3Sum and 4Sum/3Sum.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: 3Sum and 4Sum/4Sum.playground/Contents.swift
================================================
// last checked with Xcode 10.1
#if swift(>=4.2)
print("Hello, Swift 4.2!")
#endif
extension Collection where Element: Equatable {
/// In a sorted collection, replaces the given index with a successor mapping to a unique element.
///
/// - Parameter index: A valid index of the collection. `index` must be less than `endIndex`
func formUniqueIndex(after index: inout Index) {
var prev = index
repeat {
prev = index
formIndex(after: &index)
} while index < endIndex && self[prev] == self[index]
}
}
extension BidirectionalCollection where Element: Equatable {
/// In a sorted collection, replaces the given index with a predecessor that maps to a unique element.
///
/// - Parameter index: A valid index of the collection. `index` must be greater than `startIndex`.
func formUniqueIndex(before index: inout Index) {
var prev = index
repeat {
prev = index
formIndex(before: &index)
} while index > startIndex && self[prev] == self[index]
}
}
func fourSum<T: BidirectionalCollection>(_ collection: T, target: T.Element) -> [[T.Element]] where T.Element: Numeric & Comparable {
let sorted = collection.sorted()
var ret: [[T.Element]] = []
var l = sorted.startIndex
FourSum: while l < sorted.endIndex { defer { sorted.formUniqueIndex(after: &l) }
var ml = sorted.index(after: l)
ThreeSum: while ml < sorted.endIndex { defer { sorted.formUniqueIndex(after: &ml) }
var mr = sorted.index(after: ml)
var r = sorted.index(before: sorted.endIndex)
TwoSum: while mr < r && r < sorted.endIndex {
let sum = sorted[l] + sorted[ml] + sorted[mr] + sorted[r]
if sum == target {
ret.append([sorted[l], sorted[ml], sorted[mr], sorted[r]])
sorted.formUniqueIndex(after: &mr)
sorted.formUniqueIndex(before: &r)
} else if sum < target {
sorted.formUniqueIndex(after: &mr)
} else {
sorted.formUniqueIndex(before: &r)
}
}
}
}
return ret
}
// answer: [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
fourSum([1, 0, -1, 0, -2, 2], target: 0)
================================================
FILE: 3Sum and 4Sum/4Sum.playground/contents.xcplayground
================================================
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios'>
<timeline fileName='timeline.xctimeline'/>
</playground>
================================================
FILE: 3Sum and 4Sum/4Sum.playground/playground.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: 3Sum and 4Sum/4Sum.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: 3Sum and 4Sum/README.md
================================================
# 3Sum and 4Sum
3Sum and 4Sum are extensions of a popular algorithm question, the [2Sum][5].
## 3Sum
> Given an array of integers, find all subsets of the array with 3 values where the 3 values sum up to a target number.
>
> **Note**: The solution subsets must not contain duplicate triplets.
>
> For example, given the array [-1, 0, 1, 2, -1, -4], and the target **0**:
> The solution set is: [[-1, 0, 1], [-1, -1, 2]] // The two **-1** values in the array are considered to be distinct
There are 2 key procedures in solving this algorithm. Sorting the array, and avoiding duplicates.
### Sorting
Sorting your input array allows for powerful assumptions:
* duplicates are always adjacent to each other
* moving an index to the right increases the value, while moving an index to the left decreases the value
You'll make use of these two rules to create an efficient algorithm.
### Avoiding Duplicates
Since you pre-sort the array, duplicates will be adjacent to each other. You just need to skip over duplicates by comparing adjacent values:
```swift
extension Collection where Element: Equatable {
/// In a sorted collection, replaces the given index with a successor mapping to a unique element.
///
/// - Parameter index: A valid index of the collection. `index` must be less than `endIndex`
func formUniqueIndex(after index: inout Index) {
var prev = index
repeat {
prev = index
formIndex(after: &index)
} while index < endIndex && self[prev] == self[index]
}
}
```
A similar implementation is used to get the unique index *before* a given index:
```swift
extension BidirectionalCollection where Element: Equatable {
/// In a sorted collection, replaces the given index with a predecessor that maps to a unique element.
///
/// - Parameter index: A valid index of the collection. `index` must be greater than `startIndex`.
func formUniqueIndex(before index: inout Index) {
var prev = index
repeat {
prev = index
formIndex(before: &index)
} while index > startIndex && self[prev] == self[index]
}
}
```
### Assembling the Subsets
You'll keep track of 3 indices to represent the 3 numbers. The sum at any given moment is `array[l] + array[m] + array[r]`:
```swift
m -> <- r
[-4, -1, -1, 0, 1, 2]
l
```
The premise is quite straightforward (given that you're familiar with 2Sum). You'll iterate `l` through the array. For every iteration, you also apply the 2Sum algorithm to elements after `l`. You'll check the sum every time you moving the indices to check if you found match. Here's the algorithm:
```swift
func threeSum<T: BidirectionalCollection>(_ collection: T, target: T.Element) -> [[T.Element]] where T.Element: Numeric & Comparable {
let sorted = collection.sorted()
var ret: [[T.Element]] = []
var l = sorted.startIndex
ThreeSum: while l < sorted.endIndex { defer { sorted.formUniqueIndex(after: &l) }
var m = sorted.index(after: l)
var r = sorted.index(before: sorted.endIndex)
TwoSum: while m < r && r < sorted.endIndex {
let sum = sorted[l] + sorted[m] + sorted[r]
if sum == target {
ret.append([sorted[l], sorted[m], sorted[r]])
sorted.formUniqueIndex(after: &m)
sorted.formUniqueIndex(before: &r)
} else if sum < target {
sorted.formUniqueIndex(after: &m)
} else {
sorted.formUniqueIndex(before: &r)
}
}
}
return ret
}
```
## 4Sum
> Given an array S of n integers, find all subsets of the array with 4 values where the 4 values sum up to a target number.
>
> **Note**: The solution set must not contain duplicate quadruplets.
### Solution
Foursum is a very straightforward extension to the threeSum algorithm. In threeSum, you kept track of 3 indices:
```swift
m -> <- r
[-4, -1, -1, 0, 1, 2]
l
```
For fourSum, you'll keep track of 4:
```swift
mr -> <- r
[-4, -1, -1, 0, 1, 2]
l ml ->
```
Here's the code for it (notice it is very similar to 3Sum):
```swift
func fourSum<T: BidirectionalCollection>(_ collection: T, target: T.Element) -> [[T.Element]] where T.Element: Numeric & Comparable {
let sorted = collection.sorted()
var ret: [[T.Element]] = []
var l = sorted.startIndex
FourSum: while l < sorted.endIndex { defer { sorted.formUniqueIndex(after: &l) }
var ml = sorted.index(after: l)
ThreeSum: while ml < sorted.endIndex { defer { sorted.formUniqueIndex(after: &ml) }
var mr = sorted.index(after: ml)
var r = sorted.index(before: sorted.endIndex)
TwoSum: while mr < r && r < sorted.endIndex {
let sum = sorted[l] + sorted[ml] + sorted[mr] + sorted[r]
if sum == target {
ret.append([sorted[l], sorted[ml], sorted[mr], sorted[r]])
sorted.formUniqueIndex(after: &mr)
sorted.formUniqueIndex(before: &r)
} else if sum < target {
sorted.formUniqueIndex(after: &mr)
} else {
sorted.formUniqueIndex(before: &r)
}
}
}
}
return ret
}
```
[5]: https://github.com/raywenderlich/swift-algorithm-club/tree/master/Two-Sum%20Problem
*Written for the Swift Algorithm Club by Kai Chen and Kelvin Lau*
================================================
FILE: A-Star/AStar.swift
================================================
// Written by Alejandro Isaza.
import Foundation
public protocol Graph {
associatedtype Vertex: Hashable
associatedtype Edge: WeightedEdge where Edge.Vertex == Vertex
/// Lists all edges going out from a vertex.
func edgesOutgoing(from vertex: Vertex) -> [Edge]
}
public protocol WeightedEdge {
associatedtype Vertex
/// The edge's cost.
var cost: Double { get }
/// The target vertex.
var target: Vertex { get }
}
public final class AStar<G: Graph> {
/// The graph to search on.
public let graph: G
/// The heuristic cost function that estimates the cost between two vertices.
///
/// - Note: The heuristic function needs to always return a value that is lower-than or equal to the actual
/// cost for the resulting path of the A* search to be optimal.
public let heuristic: (G.Vertex, G.Vertex) -> Double
/// Open list of nodes to expand.
private var open: HashedHeap<Node<G.Vertex>>
/// Closed list of vertices already expanded.
private var closed = Set<G.Vertex>()
/// Actual vertex cost for vertices we already encountered (refered to as `g` on the literature).
private var costs = Dictionary<G.Vertex, Double>()
/// Store the previous node for each expanded node to recreate the path.
private var parents = Dictionary<G.Vertex, G.Vertex>()
/// Initializes `AStar` with a graph and a heuristic cost function.
public init(graph: G, heuristic: @escaping (G.Vertex, G.Vertex) -> Double) {
self.graph = graph
self.heuristic = heuristic
open = HashedHeap(sort: <)
}
/// Finds an optimal path between `source` and `target`.
///
/// - Precondition: both `source` and `target` belong to `graph`.
public func path(start: G.Vertex, target: G.Vertex) -> [G.Vertex] {
open.insert(Node<G.Vertex>(vertex: start, cost: 0, estimate: heuristic(start, target)))
while !open.isEmpty {
guard let node = open.remove() else {
break
}
costs[node.vertex] = node.cost
if (node.vertex == target) {
let path = buildPath(start: start, target: target)
cleanup()
return path
}
if !closed.contains(node.vertex) {
expand(node: node, target: target)
closed.insert(node.vertex)
}
}
// No path found
return []
}
private func expand(node: Node<G.Vertex>, target: G.Vertex) {
let edges = graph.edgesOutgoing(from: node.vertex)
for edge in edges {
let g = cost(node.vertex) + edge.cost
if g < cost(edge.target) {
open.insert(Node<G.Vertex>(vertex: edge.target, cost: g, estimate: heuristic(edge.target, target)))
parents[edge.target] = node.vertex
}
}
}
private func cost(_ vertex: G.Edge.Vertex) -> Double {
if let c = costs[vertex] {
return c
}
let node = Node(vertex: vertex, cost: Double.greatestFiniteMagnitude, estimate: 0)
if let index = open.index(of: node) {
return open[index].cost
}
return Double.greatestFiniteMagnitude
}
private func buildPath(start: G.Vertex, target: G.Vertex) -> [G.Vertex] {
var path = Array<G.Vertex>()
path.append(target)
var current = target
while current != start {
guard let parent = parents[current] else {
return [] // no path found
}
current = parent
path.append(current)
}
return path.reversed()
}
private func cleanup() {
open.removeAll()
closed.removeAll()
parents.removeAll()
}
}
private struct Node<V: Hashable>: Hashable, Comparable {
/// The graph vertex.
var vertex: V
/// The actual cost between the start vertex and this vertex.
var cost: Double
/// Estimated (heuristic) cost betweent this vertex and the target vertex.
var estimate: Double
public init(vertex: V, cost: Double, estimate: Double) {
self.vertex = vertex
self.cost = cost
self.estimate = estimate
}
static func < (lhs: Node<V>, rhs: Node<V>) -> Bool {
return lhs.cost + lhs.estimate < rhs.cost + rhs.estimate
}
static func == (lhs: Node<V>, rhs: Node<V>) -> Bool {
return lhs.vertex == rhs.vertex
}
var hashValue: Int {
return vertex.hashValue
}
}
================================================
FILE: A-Star/Images/graph.dot
================================================
digraph G {
rankdir=LR;
{ A [ label = "h = 3" ] }
{ rank = same; B [ label = "h = 2" ]; C [ label = "h = 2" ]; D [ label = "h = 2" ] }
{ rank = same; E [ label = "h = 1" ]; F [ label = "h = 1" ]; G [ label = "h = 1" ] }
{ H [ label = "h = 0", style = filled, color = green ] }
A -> { B C D }
B -> E
E -> F
D -> G
G -> H
}
================================================
FILE: A-Star/Images/step1.dot
================================================
digraph G {
rankdir=LR;
{ A [ label = "g = 0\nh = 3", style = filled, color = deepskyblue1 ] }
{ rank = same; B [ label = "g = 1\nh = 2", style = filled, color = lightgrey ]; C [ label = "g = 1\nh = 2", style = filled, color = lightgrey ]; D [ label = "g = 1\nh = 2", style = filled, color = lightgrey ] }
{ rank = same; E [ label = "g = \?\nh = 1" ]; F [ label = "g = \?\nh = 1" ]; G [ label = "g = \?\nh = 1" ] }
{ H [ label = "g = \?\nh = 0" ] }
A -> { B C D }
B -> E
E -> F
D -> G
G -> H
}
================================================
FILE: A-Star/Images/step2.dot
================================================
digraph G {
rankdir=LR;
{ A [ label = "g = 0\nh = 3", style = filled, color = lightblue ] }
{ rank = same; B [ label = "g = 1\nh = 2", style = filled, color = deepskyblue1 ]; C [ label = "g = 1\nh = 2", style = filled, color = lightgrey ]; D [ label = "g = 1\nh = 2", style = filled, color = lightgrey ] }
{ rank = same; E [ label = "g = 2\nh = 1", style = filled, color = lightgrey ]; F [ label = "g = \?\nh = 1" ]; G [ label = "g = \?\nh = 1" ] }
{ H [ label = "g = \?\nh = 0" ] }
A -> { B C D }
B -> E
E -> F
D -> G
G -> H
}
================================================
FILE: A-Star/Images/step3.dot
================================================
digraph G {
rankdir=LR;
{ A [ label = "g = 0\nh = 3", style = filled, color = lightblue ] }
{ rank = same; B [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; C [ label = "g = 1\nh = 2", style = filled, color = deepskyblue1 ]; D [ label = "g = 1\nh = 2", style = filled, color = lightgrey ] }
{ rank = same; E [ label = "g = 2\nh = 1", style = filled, color = lightgrey ]; F [ label = "g = \?\nh = 1" ]; G [ label = "g = \?\nh = 1" ] }
{ H [ label = "g = \?\nh = 0" ] }
A -> { B C D }
B -> E
E -> F
D -> G
G -> H
}
================================================
FILE: A-Star/Images/step4.dot
================================================
digraph G {
rankdir=LR;
{ A [ label = "g = 0\nh = 3", style = filled, color = lightblue ] }
{ rank = same; B [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; C [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; D [ label = "g = 1\nh = 2", style = filled, color = deepskyblue1 ] }
{ rank = same; E [ label = "g = 2\nh = 1", style = filled, color = lightgrey ]; F [ label = "g = \?\nh = 1" ]; G [ label = "g = 2\nh = 1", style = filled, color = lightgrey ] }
{ H [ label = "g = \?\nh = 0" ] }
A -> { B C D }
B -> E
E -> F
D -> G
G -> H
}
================================================
FILE: A-Star/Images/step5.dot
================================================
digraph G {
rankdir=LR;
{ A [ label = "g = 0\nh = 3", style = filled, color = lightblue ] }
{ rank = same; B [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; C [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; D [ label = "g = 1\nh = 2", style = filled, color = lightblue ] }
{ rank = same; E [ label = "g = 2\nh = 1", style = filled, color = deepskyblue1 ]; F [ label = "g = 3\nh = 1", style = filled, color = lightgrey ]; G [ label = "g = 2\nh = 1", style = filled, color = lightgrey ] }
{ H [ label = "g = \?\nh = 0" ] }
A -> { B C D }
B -> E
E -> F
D -> G
G -> H
}
================================================
FILE: A-Star/Images/step6.dot
================================================
digraph G {
rankdir=LR;
{ A [ label = "g = 0\nh = 3", style = filled, color = lightblue ] }
{ rank = same; B [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; C [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; D [ label = "g = 1\nh = 2", style = filled, color = lightblue ] }
{ rank = same; E [ label = "g = 2\nh = 1", style = filled, color = lightblue ]; F [ label = "g = 3\nh = 1", style = filled, color = lightgrey ]; G [ label = "g = 2\nh = 1", style = filled, color = deepskyblue1 ] }
{ H [ label = "g = 3\nh = 0", style = filled, color = lightgrey ] }
A -> { B C D }
B -> E
E -> F
D -> G
G -> H
}
================================================
FILE: A-Star/Images/step7.dot
================================================
digraph G {
rankdir=LR;
{ A [ label = "g = 0\nh = 3", style = filled, color = lightblue ] }
{ rank = same; B [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; C [ label = "g = 1\nh = 2", style = filled, color = lightblue ]; D [ label = "g = 1\nh = 2", style = filled, color = lightblue ] }
{ rank = same; E [ label = "g = 2\nh = 1", style = filled, color = lightblue ]; F [ label = "g = 3\nh = 1", style = filled, color = lightgrey ]; G [ label = "g = 2\nh = 1", style = filled, color = lightblue ] }
{ H [ label = "g = 3\nh = 0", style = filled, color = deepskyblue1 ] }
A -> { B C D }
B -> E
E -> F
D -> G
G -> H
}
================================================
FILE: A-Star/README.md
================================================
# A*
A* (pronounced "ay star") is a heuristic best-first search algorithm. A* minimizes node expansions, therefore minimizing the search time, by using a heuristic function. The heuristic function gives an estimate of the distance between two vertices. For instance if you are searching for a path between two points in a city, you can estimate the actual street distance with the straight-line distance.
A* works by expanding the most promising nodes first, according to the heuristic function. In the city example it would choose streets which go in the general direction of the target first and, only if those are dead ends, backtrack and try other streets. This speeds up search in most sitations.
A* is optimal (it always find the shortest path) if the heuristic function is admissible. A heuristic function is admissible if it never overestimates the cost of reaching the goal. In the extreme case of the heuristic function always retuning `0` A* acts exactly the same as [Dijkstra's Algorithm](../Dijkstra). The closer the heuristic function is to the actual distance the faster the search.
## Example
Let's run through an example on this simple directed graph. We are going to assume that all edges have a cost of 1 and the heuristic function is going to be the column starting at goal and going back:

On the first step we expand the root node on the left (blue). We set the cost `g` to zero and add all neighbors to the open list (grey).

We put the first node in the closed list (light blue) so that we don't try expanding it again if there were to be loops in the graph. Next we take the node on the open list with the smallest value of `g + h` where `g` is the current cost (0) plus the edge cost (1). Since all nodes in the open list have the same value we choose the top one.

We repeat the process and pick the next node from the open list. In this case there are no new nodes to add to the open list.

We expand the next node. One more node on the open list, but nothing exciting yet.

Sicne the top and the bottom nodes have the same value we choose the top one. This is not a great choice but we could do better if we had a better heuristic function.

Now we expand the bottom node because it has a smaller value than the middle node (2 + 1 < 3 + 1).

And we finally reach the goal! We never even expanded that middle node. We didn't have to because its value is 4, which is equal to the total lenght of our solution and therefore guaranteed to not be part of the optimal solution.

The final step is to backtrack from the goal node to buld the optimal path.
================================================
FILE: A-Star/Tests/AStarTests.swift
================================================
import Foundation
import XCTest
struct GridGraph: Graph {
struct Vertex: Hashable {
var x: Int
var y: Int
static func == (lhs: Vertex, rhs: Vertex) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
public var hashValue: Int {
return x.hashValue ^ y.hashValue
}
}
struct Edge: WeightedEdge {
var cost: Double
var target: Vertex
}
func edgesOutgoing(from vertex: Vertex) -> [Edge] {
return [
Edge(cost: 1, target: Vertex(x: vertex.x - 1, y: vertex.y)),
Edge(cost: 1, target: Vertex(x: vertex.x + 1, y: vertex.y)),
Edge(cost: 1, target: Vertex(x: vertex.x, y: vertex.y - 1)),
Edge(cost: 1, target: Vertex(x: vertex.x, y: vertex.y + 1)),
]
}
}
class AStarTests: XCTestCase {
func testSameStartAndEnd() {
let graph = GridGraph()
let astar = AStar(graph: graph, heuristic: manhattanDistance)
let path = astar.path(start: GridGraph.Vertex(x: 0, y: 0), target: GridGraph.Vertex(x: 0, y: 0))
XCTAssertEqual(path.count, 1)
XCTAssertEqual(path[0].x, 0)
XCTAssertEqual(path[0].y, 0)
}
func testDiagonal() {
let graph = GridGraph()
let astar = AStar(graph: graph, heuristic: manhattanDistance)
let path = astar.path(start: GridGraph.Vertex(x: 0, y: 0), target: GridGraph.Vertex(x: 10, y: 10))
XCTAssertEqual(path.count, 21)
XCTAssertEqual(path[0].x, 0)
XCTAssertEqual(path[0].y, 0)
XCTAssertEqual(path[20].x, 10)
XCTAssertEqual(path[20].y, 10)
}
func manhattanDistance(_ s: GridGraph.Vertex, _ t: GridGraph.Vertex) -> Double {
return Double(abs(s.x - t.x) + abs(s.y - t.y))
}
}
================================================
FILE: A-Star/Tests/AStarTests.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
611D099C1F8978AB00C7092B /* AStarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611D099B1F8978AB00C7092B /* AStarTests.swift */; };
611D099E1F8978BC00C7092B /* AStar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611D099D1F8978BB00C7092B /* AStar.swift */; };
611D09A01F89795100C7092B /* HashedHeap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611D099F1F89795100C7092B /* HashedHeap.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
611D099B1F8978AB00C7092B /* AStarTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AStarTests.swift; sourceTree = "<group>"; };
611D099D1F8978BB00C7092B /* AStar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AStar.swift; path = ../AStar.swift; sourceTree = "<group>"; };
611D099F1F89795100C7092B /* HashedHeap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HashedHeap.swift; path = "../../Hashed Heap/HashedHeap.swift"; sourceTree = "<group>"; };
7B2BBC801C779D720067B71D /* AStarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AStarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7B2BBC941C779E7B0067B71D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7B2BBC7D1C779D720067B71D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
7B2BBC681C779D710067B71D = {
isa = PBXGroup;
children = (
7B2BBC831C779D720067B71D /* Tests */,
7B2BBC721C779D710067B71D /* Products */,
);
sourceTree = "<group>";
};
7B2BBC721C779D710067B71D /* Products */ = {
isa = PBXGroup;
children = (
7B2BBC801C779D720067B71D /* AStarTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
7B2BBC831C779D720067B71D /* Tests */ = {
isa = PBXGroup;
children = (
611D099F1F89795100C7092B /* HashedHeap.swift */,
611D099D1F8978BB00C7092B /* AStar.swift */,
611D099B1F8978AB00C7092B /* AStarTests.swift */,
7B2BBC941C779E7B0067B71D /* Info.plist */,
);
name = Tests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7B2BBC7F1C779D720067B71D /* AStarTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7B2BBC8C1C779D720067B71D /* Build configuration list for PBXNativeTarget "AStarTests" */;
buildPhases = (
7B2BBC7C1C779D720067B71D /* Sources */,
7B2BBC7D1C779D720067B71D /* Frameworks */,
7B2BBC7E1C779D720067B71D /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = AStarTests;
productName = TestsTests;
productReference = 7B2BBC801C779D720067B71D /* AStarTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
7B2BBC691C779D710067B71D /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Swift Algorithm Club";
TargetAttributes = {
7B2BBC7F1C779D720067B71D = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0900;
};
};
};
buildConfigurationList = 7B2BBC6C1C779D710067B71D /* Build configuration list for PBXProject "AStarTests" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 7B2BBC681C779D710067B71D;
productRefGroup = 7B2BBC721C779D710067B71D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
7B2BBC7F1C779D720067B71D /* AStarTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
7B2BBC7E1C779D720067B71D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7B2BBC7C1C779D720067B71D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
611D099C1F8978AB00C7092B /* AStarTests.swift in Sources */,
611D099E1F8978BC00C7092B /* AStar.swift in Sources */,
611D09A01F89795100C7092B /* HashedHeap.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
7B2BBC871C779D720067B71D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
};
name = Debug;
};
7B2BBC881C779D720067B71D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
};
name = Release;
};
7B2BBC8D1C779D720067B71D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
7B2BBC8E1C779D720067B71D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7B2BBC6C1C779D710067B71D /* Build configuration list for PBXProject "AStarTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7B2BBC871C779D720067B71D /* Debug */,
7B2BBC881C779D720067B71D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7B2BBC8C1C779D720067B71D /* Build configuration list for PBXNativeTarget "AStarTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7B2BBC8D1C779D720067B71D /* Debug */,
7B2BBC8E1C779D720067B71D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 7B2BBC691C779D710067B71D /* Project object */;
}
================================================
FILE: A-Star/Tests/AStarTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Tests.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: A-Star/Tests/AStarTests.xcodeproj/xcshareddata/xcschemes/AStarTests.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "AStarTests.xctest"
BlueprintName = "AStarTests"
ReferencedContainer = "container:AStarTests.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: A-Star/Tests/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
================================================
FILE: AVL Tree/AVLTree.playground/Contents.swift
================================================
//: Playground - noun: a place where people can play
let tree = AVLTree<Int, String>()
tree.insert(key: 5, payload: "five")
print(tree)
tree.insert(key: 4, payload: "four")
print(tree)
tree.insert(key: 3, payload: "three")
print(tree)
tree.insert(key: 2, payload: "two")
print(tree)
tree.insert(key: 1, payload: "one")
print(tree)
print(tree.debugDescription)
let node = tree.search(input: 2) // "two"
tree.delete(key: 5)
tree.delete(key: 2)
tree.delete(key: 1)
tree.delete(key: 4)
tree.delete(key: 3)
================================================
FILE: AVL Tree/AVLTree.playground/Sources/AVLTree.swift
================================================
// The MIT License (MIT)
// Copyright (c) 2016 Mike Taghavi (mitghi[at]me.com)
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
public class TreeNode<Key: Comparable, Payload> {
public typealias Node = TreeNode<Key, Payload>
var payload: Payload?
fileprivate var key: Key
internal var leftChild: Node?
internal var rightChild: Node?
fileprivate var height: Int
weak fileprivate var parent: Node?
public init(key: Key, payload: Payload?, leftChild: Node?, rightChild: Node?, parent: Node?, height: Int) {
self.key = key
self.payload = payload
self.leftChild = leftChild
self.rightChild = rightChild
self.parent = parent
self.height = height
self.leftChild?.parent = self
self.rightChild?.parent = self
}
public convenience init(key: Key, payload: Payload?) {
self.init(key: key, payload: payload, leftChild: nil, rightChild: nil, parent: nil, height: 1)
}
public convenience init(key: Key) {
self.init(key: key, payload: nil)
}
var isRoot: Bool {
return parent == nil
}
var isLeaf: Bool {
return rightChild == nil && leftChild == nil
}
var isLeftChild: Bool {
return parent?.leftChild === self
}
var isRightChild: Bool {
return parent?.rightChild === self
}
var hasLeftChild: Bool {
return leftChild != nil
}
var hasRightChild: Bool {
return rightChild != nil
}
var hasAnyChild: Bool {
return leftChild != nil || rightChild != nil
}
var hasBothChildren: Bool {
return leftChild != nil && rightChild != nil
}
}
// MARK: - The AVL tree
open class AVLTree<Key: Comparable, Payload> {
public typealias Node = TreeNode<Key, Payload>
fileprivate(set) var root: Node?
fileprivate(set) var size = 0
public init() { }
}
// MARK: - Searching
extension TreeNode {
public func minimum() -> TreeNode? {
return leftChild?.minimum() ?? self
}
public func maximum() -> TreeNode? {
return rightChild?.maximum() ?? self
}
}
extension AVLTree {
subscript(key: Key) -> Payload? {
get { return search(input: key) }
set { insert(key: key, payload: newValue) }
}
public func search(input: Key) -> Payload? {
return search(key: input, node: root)?.payload
}
fileprivate func search(key: Key, node: Node?) -> Node? {
if let node = node {
if key == node.key {
return node
} else if key < node.key {
return search(key: key, node: node.leftChild)
} else {
return search(key: key, node: node.rightChild)
}
}
return nil
}
}
// MARK: - Inserting new items
extension AVLTree {
public func insert(key: Key, payload: Payload? = nil) {
if let root = root {
insert(input: key, payload: payload, node: root)
} else {
root = Node(key: key, payload: payload)
}
size += 1
}
private func insert(input: Key, payload: Payload?, node: Node) {
if input < node.key {
if let child = node.leftChild {
insert(input: input, payload: payload, node: child)
} else {
let child = Node(key: input, payload: payload, leftChild: nil, rightChild: nil, parent: node, height: 1)
node.leftChild = child
balance(node: child)
}
} else {
if let child = node.rightChild {
insert(input: input, payload: payload, node: child)
} else {
let child = Node(key: input, payload: payload, leftChild: nil, rightChild: nil, parent: node, height: 1)
node.rightChild = child
balance(node: child)
}
}
}
}
// MARK: - Balancing tree
extension AVLTree {
fileprivate func updateHeightUpwards(node: Node?) {
if let node = node {
let lHeight = node.leftChild?.height ?? 0
let rHeight = node.rightChild?.height ?? 0
node.height = max(lHeight, rHeight) + 1
updateHeightUpwards(node: node.parent)
}
}
fileprivate func lrDifference(node: Node?) -> Int {
let lHeight = node?.leftChild?.height ?? 0
let rHeight = node?.rightChild?.height ?? 0
return lHeight - rHeight
}
fileprivate func balance(node: Node?) {
guard let node = node else {
return
}
updateHeightUpwards(node: node.leftChild)
updateHeightUpwards(node: node.rightChild)
var nodes = [Node?](repeating: nil, count: 3)
var subtrees = [Node?](repeating: nil, count: 4)
let nodeParent = node.parent
let lrFactor = lrDifference(node: node)
if lrFactor > 1 {
// left-left or left-right
if lrDifference(node: node.leftChild) > 0 {
// left-left
nodes[0] = node
nodes[2] = node.leftChild
nodes[1] = nodes[2]?.leftChild
subtrees[0] = nodes[1]?.leftChild
subtrees[1] = nodes[1]?.rightChild
subtrees[2] = nodes[2]?.rightChild
subtrees[3] = nodes[0]?.rightChild
} else {
// left-right
nodes[0] = node
nodes[1] = node.leftChild
nodes[2] = nodes[1]?.rightChild
subtrees[0] = nodes[1]?.leftChild
subtrees[1] = nodes[2]?.leftChild
subtrees[2] = nodes[2]?.rightChild
subtrees[3] = nodes[0]?.rightChild
}
} else if lrFactor < -1 {
// right-left or right-right
if lrDifference(node: node.rightChild) < 0 {
// right-right
nodes[1] = node
nodes[2] = node.rightChild
nodes[0] = nodes[2]?.rightChild
subtrees[0] = nodes[1]?.leftChild
subtrees[1] = nodes[2]?.leftChild
subtrees[2] = nodes[0]?.leftChild
subtrees[3] = nodes[0]?.rightChild
} else {
// right-left
nodes[1] = node
nodes[0] = node.rightChild
nodes[2] = nodes[0]?.leftChild
subtrees[0] = nodes[1]?.leftChild
subtrees[1] = nodes[2]?.leftChild
subtrees[2] = nodes[2]?.rightChild
subtrees[3] = nodes[0]?.rightChild
}
} else {
// Don't need to balance 'node', go for parent
balance(node: node.parent)
return
}
// nodes[2] is always the head
if node.isRoot {
root = nodes[2]
root?.parent = nil
} else if node.isLeftChild {
nodeParent?.leftChild = nodes[2]
nodes[2]?.parent = nodeParent
} else if node.isRightChild {
nodeParent?.rightChild = nodes[2]
nodes[2]?.parent = nodeParent
}
nodes[2]?.leftChild = nodes[1]
nodes[1]?.parent = nodes[2]
nodes[2]?.rightChild = nodes[0]
nodes[0]?.parent = nodes[2]
nodes[1]?.leftChild = subtrees[0]
subtrees[0]?.parent = nodes[1]
nodes[1]?.rightChild = subtrees[1]
subtrees[1]?.parent = nodes[1]
nodes[0]?.leftChild = subtrees[2]
subtrees[2]?.parent = nodes[0]
nodes[0]?.rightChild = subtrees[3]
subtrees[3]?.parent = nodes[0]
updateHeightUpwards(node: nodes[1]) // Update height from left
updateHeightUpwards(node: nodes[0]) // Update height from right
balance(node: nodes[2]?.parent)
}
}
// MARK: - Displaying tree
extension AVLTree {
fileprivate func display(node: Node?, level: Int) {
if let node = node {
display(node: node.rightChild, level: level + 1)
print("")
if node.isRoot {
print("Root -> ", terminator: "")
}
for _ in 0..<level {
print(" ", terminator: "")
}
print("(\(node.key):\(node.height))", terminator: "")
display(node: node.leftChild, level: level + 1)
}
}
public func display(node: Node) {
display(node: node, level: 0)
print("")
}
}
// MARK: - Delete node
extension AVLTree {
public func delete(key: Key) {
if size == 1 {
root = nil
size -= 1
} else if let node = search(key: key, node: root) {
delete(node: node)
size -= 1
}
}
private func delete(node: Node) {
if node.isLeaf {
// Just remove and balance up
if let parent = node.parent {
guard node.isLeftChild || node.isRightChild else {
// just in case
fatalError("Error: tree is invalid.")
}
if node.isLeftChild {
parent.leftChild = nil
} else if node.isRightChild {
parent.rightChild = nil
}
balance(node: parent)
} else {
// at root
root = nil
}
} else {
// Handle stem cases
if let replacement = node.leftChild?.maximum(), replacement !== node {
node.key = replacement.key
node.payload = replacement.payload
delete(node: replacement)
} else if let replacement = node.rightChild?.minimum(), replacement !== node {
node.key = replacement.key
node.payload = replacement.payload
delete(node: replacement)
}
}
}
}
// MARK: - Debugging
extension TreeNode: CustomDebugStringConvertible {
public var debugDescription: String {
var s = "key: \(key), payload: \(payload), height: \(height)"
if let parent = parent {
s += ", parent: \(parent.key)"
}
if let left = leftChild {
s += ", left = [" + left.debugDescription + "]"
}
if let right = rightChild {
s += ", right = [" + right.debugDescription + "]"
}
return s
}
}
extension AVLTree: CustomDebugStringConvertible {
public var debugDescription: String {
return root?.debugDescription ?? "[]"
}
}
extension TreeNode: CustomStringConvertible {
public var description: String {
var s = ""
if let left = leftChild {
s += "(\(left.description)) <- "
}
s += "\(key)"
if let right = rightChild {
s += " -> (\(right.description))"
}
return s
}
}
extension AVLTree: CustomStringConvertible {
public var description: String {
return root?.description ?? "[]"
}
}
================================================
FILE: AVL Tree/AVLTree.playground/contents.xcplayground
================================================
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx'>
<timeline fileName='timeline.xctimeline'/>
</playground>
================================================
FILE: AVL Tree/AVLTree.playground/playground.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: AVL Tree/AVLTree.swift
================================================
// The MIT License (MIT)
// Copyright (c) 2016 Mike Taghavi (mitghi[at]me.com)
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
public class TreeNode<Key: Comparable, Payload> {
public typealias Node = TreeNode<Key, Payload>
var payload: Payload? // Value held by the node
fileprivate var key: Key // Node's name
internal var leftChild: Node?
internal var rightChild: Node?
fileprivate var height: Int
weak fileprivate var parent: Node?
public init(key: Key, payload: Payload?, leftChild: Node?, rightChild: Node?, parent: Node?, height: Int) {
self.key = key
self.payload = payload
self.leftChild = leftChild
self.rightChild = rightChild
self.parent = parent
self.height = height
self.leftChild?.parent = self
self.rightChild?.parent = self
}
public convenience init(key: Key, payload: Payload?) {
self.init(key: key, payload: payload, leftChild: nil, rightChild: nil, parent: nil, height: 1)
}
public convenience init(key: Key) {
self.init(key: key, payload: nil)
}
var isRoot: Bool {
return parent == nil
}
var isLeaf: Bool {
return rightChild == nil && leftChild == nil
}
var isLeftChild: Bool {
return parent?.leftChild === self
}
var isRightChild: Bool {
return parent?.rightChild === self
}
var hasLeftChild: Bool {
return leftChild != nil
}
var hasRightChild: Bool {
return rightChild != nil
}
var hasAnyChild: Bool {
return leftChild != nil || rightChild != nil
}
var hasBothChildren: Bool {
return leftChild != nil && rightChild != nil
}
}
// MARK: - The AVL tree
open class AVLTree<Key: Comparable, Payload> {
public typealias Node = TreeNode<Key, Payload>
fileprivate(set) var root: Node?
fileprivate(set) var size = 0
public init() { }
}
// MARK: - Searching
extension TreeNode {
public func minimum() -> TreeNode? {
return leftChild?.minimum() ?? self
}
public func maximum() -> TreeNode? {
return rightChild?.maximum() ?? self
}
}
extension AVLTree {
subscript(key: Key) -> Payload? {
get { return search(input: key) }
set { insert(key: key, payload: newValue) }
}
public func search(input: Key) -> Payload? {
return search(key: input, node: root)?.payload
}
fileprivate func search(key: Key, node: Node?) -> Node? {
if let node = node {
if key == node.key {
return node
} else if key < node.key {
return search(key: key, node: node.leftChild)
} else {
return search(key: key, node: node.rightChild)
}
}
return nil
}
}
// MARK: - Inserting new items
extension AVLTree {
public func insert(key: Key, payload: Payload? = nil) {
if let root = root {
insert(input: key, payload: payload, node: root)
} else {
root = Node(key: key, payload: payload)
}
size += 1
}
private func insert(input: Key, payload: Payload?, node: Node) {
if input < node.key {
if let child = node.leftChild {
insert(input: input, payload: payload, node: child)
} else {
let child = Node(key: input, payload: payload, leftChild: nil, rightChild: nil, parent: node, height: 1)
node.leftChild = child
balance(node: child)
}
} else if input != node.key {
if let child = node.rightChild {
insert(input: input, payload: payload, node: child)
} else {
let child = Node(key: input, payload: payload, leftChild: nil, rightChild: nil, parent: node, height: 1)
node.rightChild = child
balance(node: child)
}
}
}
}
// MARK: - Balancing tree
extension AVLTree {
fileprivate func updateHeightUpwards(node: Node?) {
if let node = node {
let lHeight = node.leftChild?.height ?? 0
let rHeight = node.rightChild?.height ?? 0
node.height = max(lHeight, rHeight) + 1
updateHeightUpwards(node: node.parent)
}
}
fileprivate func lrDifference(node: Node?) -> Int {
let lHeight = node?.leftChild?.height ?? 0
let rHeight = node?.rightChild?.height ?? 0
return lHeight - rHeight
}
fileprivate func balance(node: Node?) {
guard let node = node else {
return
}
updateHeightUpwards(node: node.leftChild)
updateHeightUpwards(node: node.rightChild)
var nodes = [Node?](repeating: nil, count: 3)
var subtrees = [Node?](repeating: nil, count: 4)
let nodeParent = node.parent
let lrFactor = lrDifference(node: node)
if lrFactor > 1 {
// left-left or left-right
if lrDifference(node: node.leftChild) > 0 {
// left-left
nodes[0] = node
nodes[2] = node.leftChild
nodes[1] = nodes[2]?.leftChild
subtrees[0] = nodes[1]?.leftChild
subtrees[1] = nodes[1]?.rightChild
subtrees[2] = nodes[2]?.rightChild
subtrees[3] = nodes[0]?.rightChild
} else {
// left-right
nodes[0] = node
nodes[1] = node.leftChild
nodes[2] = nodes[1]?.rightChild
subtrees[0] = nodes[1]?.leftChild
subtrees[1] = nodes[2]?.leftChild
subtrees[2] = nodes[2]?.rightChild
subtrees[3] = nodes[0]?.rightChild
}
} else if lrFactor < -1 {
// right-left or right-right
if lrDifference(node: node.rightChild) < 0 {
// right-right
nodes[1] = node
nodes[2] = node.rightChild
nodes[0] = nodes[2]?.rightChild
subtrees[0] = nodes[1]?.leftChild
subtrees[1] = nodes[2]?.leftChild
subtrees[2] = nodes[0]?.leftChild
subtrees[3] = nodes[0]?.rightChild
} else {
// right-left
nodes[1] = node
nodes[0] = node.rightChild
nodes[2] = nodes[0]?.leftChild
subtrees[0] = nodes[1]?.leftChild
subtrees[1] = nodes[2]?.leftChild
subtrees[2] = nodes[2]?.rightChild
subtrees[3] = nodes[0]?.rightChild
}
} else {
// Don't need to balance 'node', go for parent
balance(node: node.parent)
return
}
// nodes[2] is always the head
if node.isRoot {
root = nodes[2]
root?.parent = nil
} else if node.isLeftChild {
nodeParent?.leftChild = nodes[2]
nodes[2]?.parent = nodeParent
} else if node.isRightChild {
nodeParent?.rightChild = nodes[2]
nodes[2]?.parent = nodeParent
}
nodes[2]?.leftChild = nodes[1]
nodes[1]?.parent = nodes[2]
nodes[2]?.rightChild = nodes[0]
nodes[0]?.parent = nodes[2]
nodes[1]?.leftChild = subtrees[0]
subtrees[0]?.parent = nodes[1]
nodes[1]?.rightChild = subtrees[1]
subtrees[1]?.parent = nodes[1]
nodes[0]?.leftChild = subtrees[2]
subtrees[2]?.parent = nodes[0]
nodes[0]?.rightChild = subtrees[3]
subtrees[3]?.parent = nodes[0]
updateHeightUpwards(node: nodes[1]) // Update height from left
updateHeightUpwards(node: nodes[0]) // Update height from right
balance(node: nodes[2]?.parent)
}
}
// MARK: - Displaying tree
extension AVLTree {
fileprivate func display(node: Node?, level: Int) {
if let node = node {
display(node: node.rightChild, level: level + 1)
print("")
if node.isRoot {
print("Root -> ", terminator: "")
}
for _ in 0..<level {
print(" ", terminator: "")
}
print("(\(node.key):\(node.height))", terminator: "")
display(node: node.leftChild, level: level + 1)
}
}
public func display(node: Node) {
display(node: node, level: 0)
print("")
}
public func inorder(node: Node?) -> String {
var output = ""
if let node = node {
output = "\(inorder(node: node.leftChild)) \(print("\(node.key) ")) \(inorder(node: node.rightChild))"
}
return output
}
public func preorder(node: Node?) -> String {
var output = ""
if let node = node {
output = "\(preorder(node: node.leftChild)) \(print("\(node.key) ")) \(preorder(node: node.rightChild))"
}
return output
}
public func postorder(node: Node?) -> String {
var output = ""
if let node = node {
output = "\(postorder(node: node.leftChild)) \(print("\(node.key) ")) \(postorder(node: node.rightChild))"
}
return output
}
}
// MARK: - Delete node
extension AVLTree {
public func delete(key: Key) {
if size == 1 {
root = nil
size -= 1
} else if let node = search(key: key, node: root) {
delete(node: node)
size -= 1
}
}
private func delete(node: Node) {
if node.isLeaf {
// Just remove and balance up
if let parent = node.parent {
guard node.isLeftChild || node.isRightChild else {
// just in case
fatalError("Error: tree is invalid.")
}
if node.isLeftChild {
parent.leftChild = nil
} else if node.isRightChild {
parent.rightChild = nil
}
balance(node: parent)
} else {
// at root
root = nil
}
} else {
// Handle stem cases
if let replacement = node.leftChild?.maximum(), replacement !== node {
node.key = replacement.key
node.payload = replacement.payload
delete(node: replacement)
} else if let replacement = node.rightChild?.minimum(), replacement !== node {
node.key = replacement.key
node.payload = replacement.payload
delete(node: replacement)
}
}
}
}
// MARK: - Advanced Stuff
extension AVLTree {
public func doInOrder(node: Node?, _ completion: (Node) -> Void) {
if let node = node {
doInOrder(node: node.leftChild) { lnode in
completion(lnode)
}
completion(node)
doInOrder(node: node.rightChild) { rnode in
completion(rnode)
}
}
}
public func doInPreOrder(node: Node?, _ completion: (Node) -> Void) {
if let node = node {
completion(node)
doInPreOrder(node: node.leftChild) { lnode in
completion(lnode)
}
doInPreOrder(node: node.rightChild) { rnode in
completion(rnode)
}
}
}
public func doInPostOrder(node: Node?, _ completion: (Node) -> Void) {
if let node = node {
doInPostOrder(node: node.leftChild) { lnode in
completion(lnode)
}
doInPostOrder(node: node.rightChild) { rnode in
completion(rnode)
}
completion(node)
}
}
}
// MARK: - Debugging
extension TreeNode: CustomDebugStringConvertible {
public var debugDescription: String {
var s = "key: \(key), payload: \(payload), height: \(height)"
if let parent = parent {
s += ", parent: \(parent.key)"
}
if let left = leftChild {
s += ", left = [" + left.debugDescription + "]"
}
if let right = rightChild {
s += ", right = [" + right.debugDescription + "]"
}
return s
}
}
extension AVLTree: CustomDebugStringConvertible {
public var debugDescription: String {
return root?.debugDescription ?? "[]"
}
}
extension TreeNode: CustomStringConvertible {
public var description: String {
var s = ""
if let left = leftChild {
s += "(\(left.description)) <- "
}
s += "\(key)"
if let right = rightChild {
s += " -> (\(right.description))"
}
return s
}
}
extension AVLTree: CustomStringConvertible {
public var description: String {
return root?.description ?? "[]"
}
}
================================================
FILE: AVL Tree/README.markdown
================================================
# AVL Tree
An AVL tree is a self-balancing form of a [binary search tree](../Binary%20Search%20Tree/), in which the height of subtrees differ at most by only 1.
A binary tree is *balanced* when its left and right subtrees contain roughly the same number of nodes. That is what makes searching the tree really fast. But if a binary search tree is unbalanced, searching can become really slow.
This is an example of an unbalanced tree:

All the children are in the left branch and none are in the right. This is essentially the same as a [linked list](../Linked%20List/). As a result, searching takes **O(n)** time instead of the much faster **O(log n)** that you'd expect from a binary search tree.
A balanced version of that tree would look like this:

One way to make the binary search tree balanced is to insert the nodes in a totally random order. But that doesn't guarantee success, nor is it always practical.
The other solution is to use a *self-balancing* binary tree. This type of data structure adjusts the tree to keep it balanced after you insert or delete nodes. The height of such a tree is guaranteed to be *log(n)* where *n* is the number nodes. On a balanced tree all insert, remove, and search operations take only **O(log n)** time. That means fast. ;-)
## Introducing the AVL tree
An AVL tree fixes any imbalances by "rotating" the tree to the left or right.
A node in an AVL tree is considered balanced if its subtrees differ in "height" by at most 1. The tree itself is balanced if all its nodes are balanced.
The *height* of a node is how many steps it takes to get to that node's lowest leaf. For example, in the following tree it takes three steps to go from A to E, so the height of A is 3. The height of B is 2, the height of C is 1, and the height of the others is 0 because they are leaf nodes.

As mentioned, in an AVL tree a node is balanced if its left and right subtree have the same height. It doesn't have to be the exact same height, but the difference may not be greater than 1. These are all examples of balanced trees:

But the following are trees that are unbalanced, because the height of the left subtree is too large compared to the right subtree:

The difference between the heights of the left and right subtrees is called the *balance factor*. It is calculated as follows:
balance factor = abs(height(left subtree) - height(right subtree))
If after an insertion or deletion the balance factor becomes greater than 1, then we need to re-balance this part of the AVL tree. And that is done with rotations.
## Rotations
Each tree node keeps track of its current balance factor in a variable. After inserting a new node, we need to update the balance factor of its parent node. If that balance factor becomes greater than 1, we "rotate" part of that tree to restore the balance.

For the rotation we're using the terminology:
* *Root* - the parent node of the subtrees that will be rotated;
* *Pivot* - the node that will become parent (basically will be on the *Root*'s position) after rotation;
* *RotationSubtree* - subtree of the *Pivot* upon the side of rotation
* *OppositeSubtree* - subtree of the *Pivot* opposite the side of rotation
Let take an example of balancing the unbalanced tree using *Right* (clockwise direction) rotation:
  
The steps of rotation could be described by following:
1. Assign the *RotationSubtree* as a new *OppositeSubtree* for the *Root*;
2. Assign the *Root* as a new *RotationSubtree* for the *Pivot*;
3. Check the final result
In pseudocode the algorithm above could be written as follows:
```
Root.OS = Pivot.RS
Pivot.RS = Root
Root = Pivot
```
This is a constant time operation - __O(1)__
Insertion never needs more than 2 rotations. Removal might require up to __log(n)__ rotations.
## The code
Most of the code in [AVLTree.swift](AVLTree.swift) is just regular [binary search tree](../Binary%20Search%20Tree/) stuff. You'll find this in any implementation of a binary search tree. For example, searching the tree is exactly the same. The only things that an AVL tree does slightly differently are inserting and deleting the nodes.
> **Note:** If you're a bit fuzzy on the regular operations of a binary search tree, I suggest you [catch up on those first](../Binary%20Search%20Tree/). It will make the rest of the AVL tree easier to understand.
The interesting bits are in the `balance()` method which is called after inserting or deleting a node.
## See also
[AVL tree on Wikipedia](https://en.wikipedia.org/wiki/AVL_tree)
AVL tree was the first self-balancing binary tree. These days, the [red-black tree](../Red-Black%20Tree/) seems to be more popular.
*Written for Swift Algorithm Club by [Mike Taghavi](https://github.com/mitghi) and [Matthijs Hollemans](https://github.com/hollance)*
================================================
FILE: AVL Tree/Tests/AVLTreeTests.swift
================================================
//
// AVLTreeTestsTests.swift
// AVLTreeTestsTests
//
// Created by Barbara Rodeker on 2/19/16.
// Copyright © 2016 Swift Algorithm Club. All rights reserved.
//
import XCTest
class AVLTreeTests: XCTestCase {
var tree: AVLTree<Int, String>?
func testSwift4() {
// last checked with Xcode 9.0b4
#if swift(>=4.0)
print("Hello, Swift 4!")
#endif
}
override func setUp() {
super.setUp()
tree = AVLTree()
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testAVLTreeBalancedAutoPopulate() {
self.tree?.autopopulateWithNodes(10)
do {
try self.tree?.inOrderCheckBalanced(self.tree?.root)
} catch _ {
XCTFail("Tree is not balanced after autopopulate")
}
}
func testAVLTreeBalancedInsert() {
self.tree?.autopopulateWithNodes(5)
for i in 6...10 {
self.tree?.insert(key: i)
do {
try self.tree?.inOrderCheckBalanced(self.tree?.root)
} catch _ {
XCTFail("Tree is not balanced after inserting " + String(i))
}
}
}
func testAVLTreeBalancedDelete() {
self.tree?.autopopulateWithNodes(5)
for i in 1...6 {
self.tree?.delete(key: i)
do {
try self.tree?.inOrderCheckBalanced(self.tree?.root)
} catch _ {
XCTFail("Tree is not balanced after deleting " + String(i))
}
}
}
func testEmptyInitialization() {
let tree = AVLTree<Int, String>()
XCTAssertEqual(tree.size, 0)
XCTAssertNil(tree.root)
}
func testSingleInsertionPerformance() {
self.measure {
self.tree?.insert(key: 5, payload: "E")
}
}
func testMultipleInsertionsPerformance() {
self.measure {
self.tree?.autopopulateWithNodes(50)
}
}
func testSearchExistentOnSmallTreePerformance() {
self.measure {
print(self.tree?.search(input: 2))
}
}
func testSearchExistentElementOnLargeTreePerformance() {
self.measure {
self.tree?.autopopulateWithNodes(500)
print(self.tree?.search(input: 400))
}
}
func testMinimumOnPopulatedTree() {
self.tree?.autopopulateWithNodes(500)
let min = self.tree?.root?.minimum()
XCTAssertNotNil(min, "Minimum function not working")
}
func testMinimumOnSingleTreeNode() {
let treeNode = TreeNode(key: 1, payload: "A")
let min = treeNode.minimum()
XCTAssertNotNil(min, "Minimum on single node should be returned")
XCTAssertEqual(min?.payload, treeNode.payload)
}
func testDeleteExistentKey() {
self.tree?.delete(key: 1)
XCTAssertNil(self.tree?.search(input: 1), "Key should not exist anymore")
}
func testDeleteNotExistentKey() {
self.tree?.delete(key: 1056)
XCTAssertNil(self.tree?.search(input: 1056), "Key should not exist")
}
func testInsertSize() {
let tree = AVLTree<Int, String>()
for i in 0...5 {
tree.insert(key: i, payload: "")
XCTAssertEqual(tree.size, i + 1, "Insert didn't update size correctly!")
}
}
func testDelete() {
let permutations = [
[5, 1, 4, 2, 3],
[2, 3, 1, 5, 4],
[4, 5, 3, 2, 1],
[3, 2, 5, 4, 1],
]
for p in permutations {
let tree = AVLTree<Int, String>()
tree.insert(key: 1, payload: "five")
tree.insert(key: 2, payload: "four")
tree.insert(key: 3, payload: "three")
tree.insert(key: 4, payload: "two")
tree.insert(key: 5, payload: "one")
var count = tree.size
for i in p {
tree.delete(key: i)
count -= 1
XCTAssertEqual(tree.size, count, "Delete didn't update size correctly!")
}
}
}
}
extension AVLTree where Key : SignedInteger {
func autopopulateWithNodes(_ count: Int) {
var k: Key = 1
for _ in 0...count {
self.insert(key: k)
k = k + 1
}
}
}
enum AVLTreeError: Error {
case notBalanced
}
extension AVLTree where Key : SignedInteger {
func height(_ node: Node?) -> Int {
if let node = node {
let lHeight = height(node.leftChild)
let rHeight = height(node.rightChild)
return max(lHeight, rHeight) + 1
}
return 0
}
func inOrderCheckBalanced(_ node: Node?) throws {
if let node = node {
guard abs(height(node.leftChild) - height(node.rightChild)) <= 1 else {
throw AVLTreeError.notBalanced
}
try inOrderCheckBalanced(node.leftChild)
try inOrderCheckBalanced(node.rightChild)
}
}
}
================================================
FILE: AVL Tree/Tests/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
================================================
FILE: AVL Tree/Tests/Tests.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
7B80C3C91C77A112003CECC7 /* TreeNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B80C3C71C77A112003CECC7 /* TreeNodeTests.swift */; };
7B80C3CA1C77A112003CECC7 /* AVLTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B80C3C81C77A112003CECC7 /* AVLTreeTests.swift */; };
7B80C3CC1C77A120003CECC7 /* AVLTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B80C3CB1C77A120003CECC7 /* AVLTree.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
7B2BBC801C779D720067B71D /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7B2BBC941C779E7B0067B71D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
7B80C3C71C77A112003CECC7 /* TreeNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TreeNodeTests.swift; sourceTree = SOURCE_ROOT; };
7B80C3C81C77A112003CECC7 /* AVLTreeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AVLTreeTests.swift; sourceTree = SOURCE_ROOT; };
7B80C3CB1C77A120003CECC7 /* AVLTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AVLTree.swift; path = ../AVLTree.swift; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7B2BBC7D1C779D720067B71D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
7B2BBC681C779D710067B71D = {
isa = PBXGroup;
children = (
7B2BBC831C779D720067B71D /* Tests */,
7B2BBC721C779D710067B71D /* Products */,
);
sourceTree = "<group>";
};
7B2BBC721C779D710067B71D /* Products */ = {
isa = PBXGroup;
children = (
7B2BBC801C779D720067B71D /* Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
7B2BBC831C779D720067B71D /* Tests */ = {
isa = PBXGroup;
children = (
7B80C3CB1C77A120003CECC7 /* AVLTree.swift */,
7B80C3C81C77A112003CECC7 /* AVLTreeTests.swift */,
7B80C3C71C77A112003CECC7 /* TreeNodeTests.swift */,
7B2BBC941C779E7B0067B71D /* Info.plist */,
);
name = Tests;
path = TestsTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7B2BBC7F1C779D720067B71D /* Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7B2BBC8C1C779D720067B71D /* Build configuration list for PBXNativeTarget "Tests" */;
buildPhases = (
7B2BBC7C1C779D720067B71D /* Sources */,
7B2BBC7D1C779D720067B71D /* Frameworks */,
7B2BBC7E1C779D720067B71D /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Tests;
productName = TestsTests;
productReference = 7B2BBC801C779D720067B71D /* Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
7B2BBC691C779D710067B71D /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Swift Algorithm Club";
TargetAttributes = {
7B2BBC7F1C779D720067B71D = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800;
};
};
};
buildConfigurationList = 7B2BBC6C1C779D710067B71D /* Build configuration list for PBXProject "Tests" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 7B2BBC681C779D710067B71D;
productRefGroup = 7B2BBC721C779D710067B71D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
7B2BBC7F1C779D720067B71D /* Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
7B2BBC7E1C779D720067B71D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7B2BBC7C1C779D720067B71D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7B80C3CC1C77A120003CECC7 /* AVLTree.swift in Sources */,
7B80C3C91C77A112003CECC7 /* TreeNodeTests.swift in Sources */,
7B80C3CA1C77A112003CECC7 /* AVLTreeTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
7B2BBC871C779D720067B71D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
7B2BBC881C779D720067B71D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
};
name = Release;
};
7B2BBC8D1C779D720067B71D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
7B2BBC8E1C779D720067B71D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7B2BBC6C1C779D710067B71D /* Build configuration list for PBXProject "Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7B2BBC871C779D720067B71D /* Debug */,
7B2BBC881C779D720067B71D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7B2BBC8C1C779D720067B71D /* Build configuration list for PBXNativeTarget "Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7B2BBC8D1C779D720067B71D /* Debug */,
7B2BBC8E1C779D720067B71D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 7B2BBC691C779D710067B71D /* Project object */;
}
================================================
FILE: AVL Tree/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Tests.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: AVL Tree/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: AVL Tree/Tests/TreeNodeTests.swift
================================================
//
// TreeNodeTest.swift
// AVLTreeTests
//
// Created by Barbara Rodeker on 2/19/16.
// Copyright © 2016 Swift Algorithm Club. All rights reserved.
//
import XCTest
class TreeNodeTests: XCTestCase {
var root: TreeNode<String, String>?
var left: TreeNode<String, String>?
var right: TreeNode<String, String>?
func testSwift4() {
// last checked with Xcode 9.0b4
#if swift(>=4.0)
print("Hello, Swift 4!")
#endif
}
override func setUp() {
super.setUp()
left = TreeNode<String, String>(key: "Name", payload: "Left")
right = TreeNode<String, String>(key: "Name", payload: "Right")
root = TreeNode<String, String>(key: "Name", payload: "Root", leftChild: left, rightChild: right, parent: nil, height: 0)
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testSingleNodeCreationNOPayload() {
let treeNode = TreeNode<String, String>(key: "Building")
XCTAssertNil(treeNode.payload, "Payload for this case should be nil")
}
func testSingleNodeCreationWithPayload() {
XCTAssertNotNil(self.root!, "Payload for this case should not be nil")
}
func testIsRoot() {
XCTAssertTrue(self.root!.isRoot)
}
func testNotIsLeaf() {
XCTAssertFalse(self.root!.isLeaf, "root node is not leaf")
}
func testNotIsLeftChild() {
XCTAssertFalse(self.root!.isLeftChild, "root node is not left child")
}
func testNotIsRightChild() {
XCTAssertFalse(self.root!.isRightChild, "root node is not right child")
}
func testIsLeftChild() {
XCTAssertTrue(self.left!.isLeftChild)
}
func testIsRightChild() {
XCTAssertTrue(self.right!.isRightChild)
}
func isLeaf() {
XCTAssertTrue(self.left!.isLeaf)
}
func testHasAnyChild() {
XCTAssertTrue(self.root!.hasAnyChild)
}
func testNotHasAnyChild() {
XCTAssertFalse(self.left!.hasAnyChild)
}
func testHasBothChildren() {
XCTAssertTrue(self.root!.hasBothChildren)
}
func testNotHasBothChildren() {
XCTAssertFalse(self.left!.hasBothChildren)
}
}
================================================
FILE: Algorithm Design.markdown
================================================
# Algorithm design techniques
What to do when you're faced with a new problem and you need to find an algorithm for it.
### Is it similar to another problem?
If you can frame your problem in terms of another, more general problem, then you might be able to use an existing algorithm. Why reinvent the wheel?
One thing I like about [The Algorithm Design Manual](http://www.algorist.com) by Steven Skiena is that it includes a catalog of problems and solutions you can try. (See also his [algorithm repository](http://www3.cs.stonybrook.edu/~algorith/).)
### It's OK to start with brute force
Naive, brute force solutions are often too slow for practical use but they're a good starting point. By writing the brute force solution, you learn to understand what the problem is really all about.
Once you have a brute force implementation you can use that to verify that any improvements you come up with are correct.
And if you only work with small datasets, then a brute force approach may actually be good enough on its own. Don't fall into the trap of premature optimization!
### Divide and conquer
>"When you change the way you look at things, the things you look at change."</br>
>Max Planck, Quantum theorist and Nobel Prize Winner
Divide and conquer is a way of dealing with a large problem by breaking it down into bits and pieces and working your way up towards the solution.
Instead of seeing the whole problem as a single, huge and complex task you divide the problem in relatively smaller problems that are easier to understand and deal with.
You solve smaller problems and aggregate the solution until you are left with the solution only. At each step the problem at hand shrinks and the solution gets mature until you have the final correct solution.
Solving the smaller task and applying the same solution repetitively ( or often times recursively) to other chunks give you the result in less time.
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP/APSP.h
================================================
//
// APSP.h
// APSP
//
// Created by Andrew McKnight on 5/6/16.
//
#import <Cocoa/Cocoa.h>
//! Project version number for APSP.
FOUNDATION_EXPORT double APSPVersionNumber;
//! Project version string for APSP.
FOUNDATION_EXPORT const unsigned char APSPVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <APSP/PublicHeader.h>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP/APSP.swift
================================================
//
// Base.swift
// APSP
//
// Created by Andrew McKnight on 5/6/16.
//
import Foundation
import Graph
/**
`APSPAlgorithm` is a protocol for encapsulating an All-Pairs Shortest Paths algorithm.
It provides a single function `apply` that accepts a subclass of `AbstractGraph` and
returns an object conforming to `APSPResult`.
*/
public protocol APSPAlgorithm {
associatedtype Q: Hashable
associatedtype P: APSPResult
static func apply(_ graph: AbstractGraph<Q>) -> P
}
/**
`APSPResult` is a protocol defining functions `distance` and `path`, allowing for opaque
queries into the actual data structures that represent the APSP solution according to the algorithm used.
*/
public protocol APSPResult {
associatedtype T: Hashable
func distance(fromVertex from: Vertex<T>, toVertex to: Vertex<T>) -> Double?
func path(fromVertex from: Vertex<T>, toVertex to: Vertex<T>, inGraph graph: AbstractGraph<T>) -> [T]?
}
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP/FloydWarshall.swift
================================================
//
// FloydWarshall.swift
// APSP
//
// Created by Andrew McKnight on 5/5/16.
//
import Foundation
import Graph
private typealias Distances = [[Double]]
private typealias Predecessors = [[Int?]]
private typealias StepResult = (distances: Distances, predecessors: Predecessors)
/**
Encapsulation of the Floyd-Warshall All-Pairs Shortest Paths algorithm, conforming to the `APSPAlgorithm` protocol.
- note: In all complexity bounds, `V` is the number of vertices in the graph, and `E` is the number of edges.
*/
public struct FloydWarshall<T>: APSPAlgorithm where T: Hashable {
public typealias Q = T
public typealias P = FloydWarshallResult<T>
/**
Floyd-Warshall algorithm for computing all-pairs shortest paths in a weighted directed graph.
- precondition: `graph` must have no negative weight cycles
- complexity: `Θ(V^3)` time, `Θ(V^2)` space
- returns a `FloydWarshallResult` struct which can be queried for shortest paths and their total weights
*/
public static func apply<T>(_ graph: AbstractGraph<T>) -> FloydWarshallResult<T> {
var previousDistance = constructInitialDistanceMatrix(graph)
var previousPredecessor = constructInitialPredecessorMatrix(previousDistance)
for intermediateIdx in 0 ..< graph.vertices.count {
let nextResult = nextStep(intermediateIdx, previousDistances: previousDistance, previousPredecessors: previousPredecessor, graph: graph)
previousDistance = nextResult.distances
previousPredecessor = nextResult.predecessors
// // uncomment to see each new weight matrix
// print(" D(\(k)):\n")
// printMatrix(nextResult.distances)
//
// // uncomment to see each new predecessor matrix
// print(" ∏(\(k)):\n")
// printIntMatrix(nextResult.predecessors)
}
return FloydWarshallResult<T>(weights: previousDistance, predecessors: previousPredecessor)
}
/**
For each iteration of `intermediateIdx`, perform the comparison for the dynamic algorith,
checking for each pair of start/end vertices, whether a path taken through another vertex
produces a shorter path.
- complexity: `Θ(V^2)` time/space
- returns: a tuple containing the next distance matrix with weights of currently known
shortest paths and the corresponding predecessor matrix
*/
static fileprivate func nextStep<T>(_ intermediateIdx: Int, previousDistances: Distances,
previousPredecessors: Predecessors, graph: AbstractGraph<T>) -> StepResult {
let vertexCount = graph.vertices.count
var nextDistances = Array(repeating: Array(repeating: Double.infinity, count: vertexCount), count: vertexCount)
var nextPredecessors = Array(repeating: Array<Int?>(repeating: nil, count: vertexCount), count: vertexCount)
for fromIdx in 0 ..< vertexCount {
for toIndex in 0 ..< vertexCount {
// printMatrix(previousDistances, i: fromIdx, j: toIdx, k: intermediateIdx) // uncomment to see each comparison being made
let originalPathWeight = previousDistances[fromIdx][toIndex]
let newPathWeightBefore = previousDistances[fromIdx][intermediateIdx]
let newPathWeightAfter = previousDistances[intermediateIdx][toIndex]
let minimum = min(originalPathWeight, newPathWeightBefore + newPathWeightAfter)
nextDistances[fromIdx][toIndex] = minimum
var predecessor: Int?
if originalPathWeight <= newPathWeightBefore + newPathWeightAfter {
predecessor = previousPredecessors[fromIdx][toIndex]
} else {
predecessor = previousPredecessors[intermediateIdx][toIndex]
}
nextPredecessors[fromIdx][toIndex] = predecessor
}
}
return (nextDistances, nextPredecessors)
}
/**
We need to map the graph's weight domain onto the one required by the algorithm: the graph
stores either a weight as a `Double` or `nil` if no edge exists between two vertices, but
the algorithm needs a lack of an edge represented as ∞ for the `min` comparison to work correctly.
- complexity: `Θ(V^2)` time/space
- returns: weighted adjacency matrix in form ready for processing with Floyd-Warshall
*/
static fileprivate func constructInitialDistanceMatrix<T>(_ graph: AbstractGraph<T>) -> Distances {
let vertices = graph.vertices
let vertexCount = graph.vertices.count
var distances = Array(repeating: Array(repeating: Double.infinity, count: vertexCount), count: vertexCount)
for row in vertices {
for col in vertices {
let rowIdx = row.index
let colIdx = col.index
if rowIdx == colIdx {
distances[rowIdx][colIdx] = 0.0
} else if let w = graph.weightFrom(row, to: col) {
distances[rowIdx][colIdx] = w
}
}
}
return distances
}
/**
Make the initial predecessor index matrix. Initially each value is equal to it's row index, it's "from" index when querying into it.
- complexity: `Θ(V^2)` time/space
*/
static fileprivate func constructInitialPredecessorMatrix(_ distances: Distances) -> Predecessors {
let vertexCount = distances.count
var predecessors = Array(repeating: Array<Int?>(repeating: nil, count: vertexCount), count: vertexCount)
for fromIdx in 0 ..< vertexCount {
for toIdx in 0 ..< vertexCount {
if fromIdx != toIdx && distances[fromIdx][toIdx] < Double.infinity {
predecessors[fromIdx][toIdx] = fromIdx
}
}
}
return predecessors
}
}
/**
`FloydWarshallResult` encapsulates the result of the computation, namely the
minimized distance adjacency matrix, and the matrix of predecessor indices.
It conforms to the `APSPResult` procotol which provides methods to retrieve
distances and paths between given pairs of start and end nodes.
*/
public struct FloydWarshallResult<T>: APSPResult where T: Hashable {
fileprivate var weights: Distances
fileprivate var predecessors: Predecessors
/**
- returns: the total weight of the path from a starting vertex to a destination.
This value is the minimal connected weight between the two vertices, or `nil` if no path exists
- complexity: `Θ(1)` time/space
*/
public func distance(fromVertex from: Vertex<T>, toVertex to: Vertex<T>) -> Double? {
return weights[from.index][to.index]
}
/**
- returns: the reconstructed path from a starting vertex to a destination,
as an array containing the data property of each vertex, or `nil` if no path exists
- complexity: `Θ(V)` time, `Θ(V^2)` space
*/
public func path(fromVertex from: Vertex<T>, toVertex to: Vertex<T>, inGraph graph: AbstractGraph<T>) -> [T]? {
if let path = recursePathFrom(fromVertex: from, toVertex: to, path: [ to ], inGraph: graph) {
let pathValues = path.map { vertex in
vertex.data
}
return pathValues
}
return nil
}
/**
The recursive component to rebuilding the shortest path between
two vertices using the predecessor matrix.
- returns: the list of predecessors discovered so far
*/
fileprivate func recursePathFrom(fromVertex from: Vertex<T>, toVertex to: Vertex<T>, path: [Vertex<T>],
inGraph graph: AbstractGraph<T>) -> [Vertex<T>]? {
if from.index == to.index {
return [ from, to ]
}
if let predecessor = predecessors[from.index][to.index] {
let predecessorVertex = graph.vertices[predecessor]
if predecessor == from.index {
let newPath = [ from, to ]
return newPath
} else {
let buildPath = recursePathFrom(fromVertex: from, toVertex: predecessorVertex, path: path, inGraph: graph)
let newPath = buildPath! + [ to ]
return newPath
}
}
return nil
}
}
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP/Helpers.swift
================================================
//
// Helpers.swift
// APSP
//
// Created by Andrew McKnight on 5/6/16.
//
import Foundation
/**
Print a matrix, optionally specifying only the cells to display with the triplet (i, j, k) -> matrix[i][j], matrix[i][k], matrix[k][j]
*/
func printMatrix(_ matrix: [[Double]], i: Int = -1, j: Int = -1, k: Int = -1) {
if i >= 0 {
print(" k: \(k); i: \(i); j: \(j)\n")
}
var grid = [String]()
let n = matrix.count
for x in 0..<n {
var row = ""
for y in 0..<n {
if i < 0 || ( x == i && y == j ) || ( x == i && y == k ) || ( x == k && y == j ) {
let value = NSString(format: "%.1f", matrix[x][y])
row += "\(matrix[x][y] >= 0 ? " " : "")\(value) "
} else {
row += " . "
}
}
grid.append(row)
}
print((grid as NSArray).componentsJoined(by: "\n"))
print(" =======================")
}
func printIntMatrix(_ matrix: [[Int?]]) {
var grid = [String]()
let n = matrix.count
for x in 0..<n {
var row = ""
for y in 0..<n {
if let value = matrix[x][y] {
let valueString = NSString(format: "%i", value)
row += "\(value >= 0 ? " " : "")\(valueString) "
} else {
row += " ø "
}
}
grid.append(row)
}
print((grid as NSArray).componentsJoined(by: "\n"))
print(" =======================")
}
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.playground/Contents.swift
================================================
//: Playground - noun: a place where people can play
import Graph
import APSP
var graph = AdjacencyListGraph<String>()
let v1 = graph.createVertex("Montreal")
let v2 = graph.createVertex("New York")
let v3 = graph.createVertex("Boston")
let v4 = graph.createVertex("Portland")
let v5 = graph.createVertex("Portsmouth")
graph.addDirectedEdge(v1, to: v2, withWeight: 3)
graph.addDirectedEdge(v1, to: v5, withWeight: -4)
graph.addDirectedEdge(v1, to: v3, withWeight: 8)
graph.addDirectedEdge(v2, to: v4, withWeight: 1)
graph.addDirectedEdge(v2, to: v5, withWeight: 7)
graph.addDirectedEdge(v3, to: v2, withWeight: 4)
graph.addDirectedEdge(v4, to: v1, withWeight: 2)
graph.addDirectedEdge(v4, to: v3, withWeight: -5)
graph.addDirectedEdge(v5, to: v4, withWeight: 6)
let result = FloydWarshall<String>.apply(graph)
let path = result.path(fromVertex: v1, toVertex: v4, inGraph: graph)
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.playground/contents.xcplayground
================================================
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' last-migration='1010'>
<timeline fileName='timeline.xctimeline'/>
</playground>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.playground/playground.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.playground/timeline.xctimeline
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "file:///Users/kachen/src/swift-algorithm-club/All-Pairs%20Shortest%20Paths/APSP/APSP.playground#CharacterRangeLen=0&CharacterRangeLoc=971&EndingColumnNumber=68&EndingLineNumber=34&StartingColumnNumber=68&StartingLineNumber=34&Timestamp=523221730.015692"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "file:///Users/kachen/src/swift-algorithm-club/All-Pairs%20Shortest%20Paths/APSP/APSP.playground#CharacterRangeLen=4&CharacterRangeLoc=908&EndingColumnNumber=9&EndingLineNumber=34&StartingColumnNumber=5&StartingLineNumber=34&Timestamp=523221730.015887"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
491AA3821CE8C5F700A2E2C5 /* Graph.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 491AA37F1CE8C5C900A2E2C5 /* Graph.framework */; };
493D8DE31CDD2A1C0089795A /* APSPTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493D8DE21CDD2A1C0089795A /* APSPTests.swift */; };
493D8DF41CDD5B960089795A /* APSP.h in Headers */ = {isa = PBXBuildFile; fileRef = 493D8DF31CDD5B960089795A /* APSP.h */; settings = {ATTRIBUTES = (Public, ); }; };
493D8DF91CDD5B9B0089795A /* FloydWarshall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493D8DD81CDC38C60089795A /* FloydWarshall.swift */; };
493D8DFA1CDD5B9E0089795A /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493D8DDA1CDD29C80089795A /* Helpers.swift */; };
49BFA27A1CDD93F400522D66 /* APSP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49BFA2791CDD93F400522D66 /* APSP.swift */; };
49BFA2801CDE742900522D66 /* APSP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 493D8DF11CDD5B960089795A /* APSP.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
491AA37E1CE8C5C900A2E2C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 491AA3791CE8C5C900A2E2C5 /* Graph.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 49BFA2FD1CDF886B00522D66;
remoteInfo = Graph;
};
491AA3801CE8C5C900A2E2C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 491AA3791CE8C5C900A2E2C5 /* Graph.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 49BFA3071CDF886B00522D66;
remoteInfo = GraphTests;
};
491AA3831CE8C5F900A2E2C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 491AA3791CE8C5C900A2E2C5 /* Graph.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 49BFA2FC1CDF886B00522D66;
remoteInfo = Graph;
};
49BFA27E1CDE742700522D66 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 493D8D7E1CDC2DAE0089795A /* Project object */;
proxyType = 1;
remoteGlobalIDString = 493D8DF01CDD5B960089795A;
remoteInfo = APSP;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
491AA3791CE8C5C900A2E2C5 /* Graph.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Graph.xcodeproj; path = ../../Graph/Graph.xcodeproj; sourceTree = "<group>"; };
493D8DD81CDC38C60089795A /* FloydWarshall.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloydWarshall.swift; sourceTree = "<group>"; };
493D8DDA1CDD29C80089795A /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
493D8DE01CDD2A1C0089795A /* APSPTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APSPTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
493D8DE21CDD2A1C0089795A /* APSPTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APSPTests.swift; sourceTree = "<group>"; };
493D8DE41CDD2A1C0089795A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
493D8DF11CDD5B960089795A /* APSP.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = APSP.framework; sourceTree = BUILT_PRODUCTS_DIR; };
493D8DF31CDD5B960089795A /* APSP.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = APSP.h; sourceTree = "<group>"; };
493D8DF51CDD5B960089795A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
49BFA2791CDD93F400522D66 /* APSP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APSP.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
493D8DDD1CDD2A1C0089795A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
49BFA2801CDE742900522D66 /* APSP.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
493D8DED1CDD5B960089795A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
491AA3821CE8C5F700A2E2C5 /* Graph.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
491AA37A1CE8C5C900A2E2C5 /* Products */ = {
isa = PBXGroup;
children = (
491AA37F1CE8C5C900A2E2C5 /* Graph.framework */,
491AA3811CE8C5C900A2E2C5 /* GraphTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
493D8D7D1CDC2DAE0089795A = {
isa = PBXGroup;
children = (
491AA3791CE8C5C900A2E2C5 /* Graph.xcodeproj */,
493D8D881CDC2DAE0089795A /* APSP */,
493D8DE11CDD2A1C0089795A /* APSPTests */,
493D8D871CDC2DAE0089795A /* Products */,
);
sourceTree = "<group>";
};
493D8D871CDC2DAE0089795A /* Products */ = {
isa = PBXGroup;
children = (
493D8DE01CDD2A1C0089795A /* APSPTests.xctest */,
493D8DF11CDD5B960089795A /* APSP.framework */,
);
name = Products;
sourceTree = "<group>";
};
493D8D881CDC2DAE0089795A /* APSP */ = {
isa = PBXGroup;
children = (
493D8DF31CDD5B960089795A /* APSP.h */,
49BFA2791CDD93F400522D66 /* APSP.swift */,
493D8DD81CDC38C60089795A /* FloydWarshall.swift */,
493D8DDA1CDD29C80089795A /* Helpers.swift */,
493D8DF51CDD5B960089795A /* Info.plist */,
);
path = APSP;
sourceTree = "<group>";
};
493D8DE11CDD2A1C0089795A /* APSPTests */ = {
isa = PBXGroup;
children = (
493D8DE21CDD2A1C0089795A /* APSPTests.swift */,
493D8DE41CDD2A1C0089795A /* Info.plist */,
);
path = APSPTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
493D8DEE1CDD5B960089795A /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
493D8DF41CDD5B960089795A /* APSP.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
493D8DDF1CDD2A1C0089795A /* APSPTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 493D8DE51CDD2A1C0089795A /* Build configuration list for PBXNativeTarget "APSPTests" */;
buildPhases = (
493D8DDC1CDD2A1C0089795A /* Sources */,
493D8DDD1CDD2A1C0089795A /* Frameworks */,
493D8DDE1CDD2A1C0089795A /* Resources */,
);
buildRules = (
);
dependencies = (
49BFA27F1CDE742700522D66 /* PBXTargetDependency */,
);
name = APSPTests;
productName = APSPTests;
productReference = 493D8DE01CDD2A1C0089795A /* APSPTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
493D8DF01CDD5B960089795A /* APSP */ = {
isa = PBXNativeTarget;
buildConfigurationList = 493D8DF61CDD5B960089795A /* Build configuration list for PBXNativeTarget "APSP" */;
buildPhases = (
493D8DEC1CDD5B960089795A /* Sources */,
493D8DED1CDD5B960089795A /* Frameworks */,
493D8DEE1CDD5B960089795A /* Headers */,
493D8DEF1CDD5B960089795A /* Resources */,
);
buildRules = (
);
dependencies = (
491AA3841CE8C5F900A2E2C5 /* PBXTargetDependency */,
);
name = APSP;
productName = APSP;
productReference = 493D8DF11CDD5B960089795A /* APSP.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
493D8D7E1CDC2DAE0089795A /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 1010;
ORGANIZATIONNAME = "Swift Algorithm Club";
TargetAttributes = {
493D8DDF1CDD2A1C0089795A = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 1010;
};
493D8DF01CDD5B960089795A = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 1010;
};
};
};
buildConfigurationList = 493D8D811CDC2DAE0089795A /* Build configuration list for PBXProject "APSP" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 493D8D7D1CDC2DAE0089795A;
productRefGroup = 493D8D871CDC2DAE0089795A /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 491AA37A1CE8C5C900A2E2C5 /* Products */;
ProjectRef = 491AA3791CE8C5C900A2E2C5 /* Graph.xcodeproj */;
},
);
projectRoot = "";
targets = (
493D8DDF1CDD2A1C0089795A /* APSPTests */,
493D8DF01CDD5B960089795A /* APSP */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
491AA37F1CE8C5C900A2E2C5 /* Graph.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = Graph.framework;
remoteRef = 491AA37E1CE8C5C900A2E2C5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
491AA3811CE8C5C900A2E2C5 /* GraphTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = GraphTests.xctest;
remoteRef = 491AA3801CE8C5C900A2E2C5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
493D8DDE1CDD2A1C0089795A /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
493D8DEF1CDD5B960089795A /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
493D8DDC1CDD2A1C0089795A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
493D8DE31CDD2A1C0089795A /* APSPTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
493D8DEC1CDD5B960089795A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
49BFA27A1CDD93F400522D66 /* APSP.swift in Sources */,
493D8DF91CDD5B9B0089795A /* FloydWarshall.swift in Sources */,
493D8DFA1CDD5B9E0089795A /* Helpers.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
491AA3841CE8C5F900A2E2C5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Graph;
targetProxy = 491AA3831CE8C5F900A2E2C5 /* PBXContainerItemProxy */;
};
49BFA27F1CDE742700522D66 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 493D8DF01CDD5B960089795A /* APSP */;
targetProxy = 49BFA27E1CDE742700522D66 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
493D8D8B1CDC2DAE0089795A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
493D8D8C1CDC2DAE0089795A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
};
name = Release;
};
493D8DE61CDD2A1C0089795A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = APSPTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.swift-algorithm-club.APSPTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
};
name = Debug;
};
493D8DE71CDD2A1C0089795A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = APSPTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.swift-algorithm-club.APSPTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
};
name = Release;
};
493D8DF71CDD5B960089795A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = APSP/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.swift-algorithm-club.APSP";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.2;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
493D8DF81CDD5B960089795A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = APSP/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.swift-algorithm-club.APSP";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.2;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
493D8D811CDC2DAE0089795A /* Build configuration list for PBXProject "APSP" */ = {
isa = XCConfigurationList;
buildConfigurations = (
493D8D8B1CDC2DAE0089795A /* Debug */,
493D8D8C1CDC2DAE0089795A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
493D8DE51CDD2A1C0089795A /* Build configuration list for PBXNativeTarget "APSPTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
493D8DE61CDD2A1C0089795A /* Debug */,
493D8DE71CDD2A1C0089795A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
493D8DF61CDD5B960089795A /* Build configuration list for PBXNativeTarget "APSP" */ = {
isa = XCConfigurationList;
buildConfigurations = (
493D8DF71CDD5B960089795A /* Debug */,
493D8DF81CDD5B960089795A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 493D8D7E1CDC2DAE0089795A /* Project object */;
}
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
<false/>
</dict>
</plist>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.xcodeproj/xcshareddata/xcschemes/APSP.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "493D8DF01CDD5B960089795A"
BuildableName = "APSP.framework"
BlueprintName = "APSP"
ReferencedContainer = "container:APSP.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "493D8DF01CDD5B960089795A"
BuildableName = "APSP.framework"
BlueprintName = "APSP"
ReferencedContainer = "container:APSP.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "493D8DF01CDD5B960089795A"
BuildableName = "APSP.framework"
BlueprintName = "APSP"
ReferencedContainer = "container:APSP.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "493D8DF01CDD5B960089795A"
BuildableName = "APSP.framework"
BlueprintName = "APSP"
ReferencedContainer = "container:APSP.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.xcodeproj/xcshareddata/xcschemes/APSPTests.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "493D8DDF1CDD2A1C0089795A"
BuildableName = "APSPTests.xctest"
BlueprintName = "APSPTests"
ReferencedContainer = "container:APSP.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "493D8DDF1CDD2A1C0089795A"
BuildableName = "APSPTests.xctest"
BlueprintName = "APSPTests"
ReferencedContainer = "container:APSP.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "493D8DDF1CDD2A1C0089795A"
BuildableName = "APSPTests.xctest"
BlueprintName = "APSPTests"
ReferencedContainer = "container:APSP.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "493D8DDF1CDD2A1C0089795A"
BuildableName = "APSPTests.xctest"
BlueprintName = "APSPTests"
ReferencedContainer = "container:APSP.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:APSP.playground">
</FileRef>
<FileRef
location = "container:APSP.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSP.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
<false/>
</dict>
</plist>
================================================
FILE: All-Pairs Shortest Paths/APSP/APSPTests/APSPTests.swift
================================================
//
// APSPTests.swift
// APSPTests
//
// Created by Andrew McKnight on 5/6/16.
//
import APSP
import Graph
import XCTest
struct TestCase<T> where T: Hashable {
var from: Vertex<T>
var to: Vertex<T>
var expectedPath: [T]
var expectedDistance: Double
}
class APSPTests: XCTestCase {
/**
See Figure 25.1 of “Introduction to Algorithms” by Cormen et al, 3rd ed., pg 690
*/
func testExampleFromBook() {
let graph = AdjacencyMatrixGraph<Int>()
let v1 = graph.createVertex(1)
let v2 = graph.createVertex(2)
let v3 = graph.createVertex(3)
let v4 = graph.createVertex(4)
let v5 = graph.createVertex(5)
graph.addDirectedEdge(v1, to: v2, withWeight: 3)
graph.addDirectedEdge(v1, to: v5, withWeight: -4)
graph.addDirectedEdge(v1, to: v3, withWeight: 8)
graph.addDirectedEdge(v2, to: v4, withWeight: 1)
graph.addDirectedEdge(v2, to: v5, withWeight: 7)
graph.addDirectedEdge(v3, to: v2, withWeight: 4)
graph.addDirectedEdge(v4, to: v1, withWeight: 2)
graph.addDirectedEdge(v4, to: v3, withWeight: -5)
graph.addDirectedEdge(v5, to: v4, withWeight: 6)
let result = FloydWarshall<Int>.apply(graph)
let cases = [
TestCase<Int>(from: v1, to: v4, expectedPath: [1, 5, 4], expectedDistance: 2),
TestCase<Int>(from: v1, to: v5, expectedPath: [1, 5], expectedDistance: -4),
TestCase<Int>(from: v2, to: v1, expectedPath: [2, 4, 1], expectedDistance: 3),
TestCase<Int>(from: v2, to: v3, expectedPath: [2, 4, 3], expectedDistance: -4),
TestCase<Int>(from: v2, to: v4, expectedPath: [2, 4], expectedDistance: 1),
TestCase<Int>(from: v2, to: v5, expectedPath: [2, 4, 1, 5], expectedDistance: -1),
TestCase<Int>(from: v3, to: v1, expectedPath: [3, 2, 4, 1], expectedDistance: 7),
TestCase<Int>(from: v3, to: v2, expectedPath: [3, 2], expectedDistance: 4),
TestCase<Int>(from: v3, to: v4, expectedPath: [3, 2, 4], expectedDistance: 5),
TestCase<Int>(from: v3, to: v5, expectedPath: [3, 2, 4, 1, 5], expectedDistance: 3),
TestCase<Int>(from: v4, to: v1, expectedPath: [4, 1], expectedDistance: 2),
TestCase<Int>(from: v4, to: v2, expectedPath: [4, 3, 2], expectedDistance: -1),
TestCase<Int>(from: v4, to: v3, expectedPath: [4, 3], expectedDistance: -5),
TestCase<Int>(from: v4, to: v5, expectedPath: [4, 1, 5], expectedDistance: -2),
TestCase<Int>(from: v5, to: v1, expectedPath: [5, 4, 1], expectedDistance: 8),
TestCase<Int>(from: v5, to: v2, expectedPath: [5, 4, 3, 2], expectedDistance: 5),
TestCase<Int>(from: v5, to: v3, expectedPath: [5, 4, 3], expectedDistance: 1),
TestCase<Int>(from: v5, to: v4, expectedPath: [5, 4], expectedDistance: 6),
]
for testCase: TestCase<Int> in cases {
if let computedPath = result.path(fromVertex: testCase.from, toVertex: testCase.to, inGraph: graph),
let computedDistance = result.distance(fromVertex: testCase.from, toVertex: testCase.to) {
XCTAssert(computedDistance == testCase.expectedDistance, "expected distance \(testCase.expectedDistance) but got \(computedDistance)")
XCTAssert(computedPath == testCase.expectedPath, "expected path \(testCase.expectedPath) but got \(computedPath)")
}
}
}
func testExampleFromReadme() {
let graph = AdjacencyMatrixGraph<Int>()
let v1 = graph.createVertex(1)
let v2 = graph.createVertex(2)
let v3 = graph.createVertex(3)
let v4 = graph.createVertex(4)
graph.addDirectedEdge(v1, to: v2, withWeight: 4)
graph.addDirectedEdge(v1, to: v3, withWeight: 1)
graph.addDirectedEdge(v1, to: v4, withWeight: 3)
graph.addDirectedEdge(v2, to: v3, withWeight: 8)
graph.addDirectedEdge(v2, to: v4, withWeight: -2)
graph.addDirectedEdge(v3, to: v4, withWeight: -5)
let result = FloydWarshall<Int>.apply(graph)
let cases = [
TestCase<Int>(from: v1, to: v2, expectedPath: [1, 2], expectedDistance: 4),
TestCase<Int>(from: v1, to: v3, expectedPath: [1, 3], expectedDistance: 1),
TestCase<Int>(from: v1, to: v4, expectedPath: [1, 3, 4], expectedDistance: -4),
TestCase<Int>(from: v2, to: v3, expectedPath: [2, 3], expectedDistance: 8),
TestCase<Int>(from: v2, to: v4, expectedPath: [2, 4], expectedDistance: -2),
TestCase<Int>(from: v3, to: v4, expectedPath: [3, 4], expectedDistance: -5),
]
for testCase: TestCase<Int> in cases {
if let computedPath = result.path(fromVertex: testCase.from, toVertex: testCase.to, inGraph: graph),
let computedDistance = result.distance(fromVertex: testCase.from, toVertex: testCase.to) {
XCTAssert(computedDistance == testCase.expectedDistance, "expected distance \(testCase.expectedDistance) but got \(computedDistance)")
XCTAssert(computedPath == testCase.expectedPath, "expected path \(testCase.expectedPath) but got \(computedPath)")
}
}
}
}
================================================
FILE: All-Pairs Shortest Paths/APSP/APSPTests/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
================================================
FILE: All-Pairs Shortest Paths/README.markdown
================================================
# All-Pairs Shortest Paths
The All-Pairs shortest path problem simultaneously computes the shortest path from each node in the graph to each other node, provided a path exists for each pair. In the naive approach, we could simply compute a single-source shortest path from each node to each other node. The number of shortest paths computed is then bound by `O(V^2)`, where `V` is the number of vertices in the graph. Because SSSP is also bounded by `O(V^2)`, the total running time for the naive approach would be `O(V^4)`.
However, by applying a dynamic approach on the adjacency matrix of the graph, a running time of `O(V^3)` is achievable, using the `Floyd-Warshall` algorithm. Floyd-Warshall iterates through an adjacency matrix, and for each pair of start(`i`) and end(`j`) vertices it considers if the current distance between them is greater than a path taken through another vertex(`k`) in the graph (if paths `i` ~> `k` and `k` ~> `j` exist). It moves through an adjacency matrix for every vertex `k` applying its comparison for each pair (`i`, `j`), so for each `k` a new adjacency matrix `D(k)` is derived, where each value `d(k)[i][j]` is defined as:
<img src="img/weight_comparison_formula.png" width="400px" />
where `w[i][j]` is the weight of the edge connecting vertex `i` to vertex `j` in the graph's original adjacency matrix.
When the algorithm memoizes each refined adjacency and predecessor matrix, its space complexity is `O(V^3)`, which can be optimised to `O(V^2)` by only memoizing the latest refinements. Reconstructing paths is a recursive procedure which requires `O(V)` time and `O(V^2)` space.
# Example
For the following weighted directed graph
<img src="img/example_graph.png" width="200px" />
the adjacency matrix representation `w` is
<img src="img/original_adjacency_matrix.png" width="200px" />
### Calculating shortest paths' weights
At the beginning of the algorithm, `D(0)` is the same as `w`, with the following exceptions to accommodate the comparison function:
1. vertices with no path connecting them have the `ø` replaced with `∞`
2. the diagonal has all `0`s
Here are all the adjacency matrices derived when perform Floyd-Warshall on the above graph:
<img src="img/d0.png" width="200px" />
<img src="img/d1.png" width="200px" />
<img src="img/d2.png" width="200px" />
<img src="img/d3.png" width="200px" />
with the last being the result, which tells for each pair of starting and ending vertices, the total weight of the shortest path connecting them. During the step where `k = 2`, the comparison that winds up changing the top right value from `2` to `-4` goes like this:
k = 2, i = 0, j = 3
d(k-1)[i][j] => d(1)[0][3] = 2
d(k-1)[i][k] => d(1)[0][2] = 1
d(k-1)[j][k] => d(1)[2][3] = -5
therefore `min(2, 2 + -5) => min(2, -4)` produces a new weight of `-4` for the element at `d(2)[0][3]`, meaning that the shortest known path 1 ~> 4 before this step was from 1 -> 2 -> 4 with a total weight of -2, and afterwards we discovered a shorter path from 1 -> 3 -> 4 with a total weight of -4.
### Reconstructing shortest paths
This algorithm finds only the lengths of the shortest paths between all pairs of nodes; a separate bookkeeping structure must be maintained to track predecessors' indices and reconstruct the shortest paths afterwards. The predecessor matrices at each step for the above graph follow:
<img src="img/pi0.png" width="200px" />
<img src="img/pi1.png" width="200px" />
<img src="img/pi2.png" width="200px" />
<img src="img/pi3.png" width="200px" />
# Project Structure
The provided xcworkspace allows working in the playground, which imports the APSP framework target from the xcodeproj. Build the framework target and rerun the playground to get started. There is also a test target in the xcodeproj.
In the framework:
- protocols for All-Pairs Shortest Paths algorithms and results structures
- an implementation of the Floyd-Warshall algorithm
# TODO
- Implement naive `O(V^4)` method for comparison
- Implement Johnson's algorithm for sparse graphs
- Implement other cool optimized versions
# References
Chapter 25 of Introduction to Algorithms, Third Edition by Cormen, Leiserson, Rivest and Stein [https://mitpress.mit.edu/books/introduction-algorithms](https://mitpress.mit.edu/books/introduction-algorithms)
*Written for Swift Algorithm Club by [Andrew McKnight](https://github.com/armcknight)*
================================================
FILE: Array2D/Array2D.playground/Contents.swift
================================================
/*
Two-dimensional array with a fixed number of rows and columns.
This is mostly handy for games that are played on a grid, such as chess.
Performance is always O(1).
*/
public struct Array2D<T> {
public let columns: Int
public let rows: Int
fileprivate var array: [T]
public init(columns: Int, rows: Int, initialValue: T) {
self.columns = columns
self.rows = rows
array = .init(repeating: initialValue, count: rows*columns)
}
public subscript(column: Int, row: Int) -> T {
get {
precondition(column < columns, "Column \(column) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
precondition(row < rows, "Row \(row) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
return array[row*columns + column]
}
set {
precondition(column < columns, "Column \(column) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
precondition(row < rows, "Row \(row) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
array[row*columns + column] = newValue
}
}
}
// initialization
var matrix = Array2D(columns: 3, rows: 5, initialValue: 0)
// makes an array of rows * columns elements all filled with zero
print(matrix.array)
// setting numbers using subscript [x, y]
matrix[0, 0] = 1
matrix[1, 0] = 2
matrix[0, 1] = 3
matrix[1, 1] = 4
matrix[0, 2] = 5
matrix[1, 2] = 6
matrix[0, 3] = 7
matrix[1, 3] = 8
matrix[2, 3] = 9
// now the numbers are set in the array
print(matrix.array)
// print out the 2D array with a reference around the grid
for i in 0..<matrix.rows {
print("[", terminator: "")
for j in 0..<matrix.columns {
if j == matrix.columns - 1 {
print("\(matrix[j, i])", terminator: "")
} else {
print("\(matrix[j, i]) ", terminator: "")
}
}
print("]")
}
================================================
FILE: Array2D/Array2D.playground/contents.xcplayground
================================================
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios'>
<timeline fileName='timeline.xctimeline'/>
</playground>
================================================
FILE: Array2D/Array2D.playground/playground.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: Array2D/Array2D.swift
================================================
/*
Two-dimensional array with a fixed number of rows and columns.
This is mostly handy for games that are played on a grid, such as chess.
Performance is always O(1).
*/
public struct Array2D<T> {
public let columns: Int
public let rows: Int
fileprivate var array: [T]
public init(columns: Int, rows: Int, initialValue: T) {
self.columns = columns
self.rows = rows
array = .init(repeating: initialValue, count: rows*columns)
}
public subscript(column: Int, row: Int) -> T {
get {
precondition(column < columns, "Column \(column) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
precondition(row < rows, "Row \(row) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
return array[row*columns + column]
}
set {
precondition(column < columns, "Column \(column) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
precondition(row < rows, "Row \(row) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
array[row*columns + column] = newValue
}
}
}
================================================
FILE: Array2D/README.markdown
================================================
# Array2D
In C and Objective-C, you can write the following line,
int cookies[9][7];
to make a 9x7 grid of cookies. This creates a two-dimensional array of 63 elements. To find the cookie at column 3 and row 6, you can write:
myCookie = cookies[3][6];
This statement is not acceptable in Swift. To create a multi-dimensional array in Swift, you can write:
```swift
var cookies = [[Int]]()
for _ in 1...9 {
var row = [Int]()
for _ in 1...7 {
row.append(0)
}
cookies.append(row)
}
```
Then, to find a cookie, you can write:
```swift
let myCookie = cookies[3][6]
```
You can also create the array in a single line of code:
```swift
var cookies = [[Int]](repeating: [Int](repeating: 0, count: 7), count: 9)
```
This looks complicated, but you can simplify it with a helper function:
```swift
func dim<T>(_ count: Int, _ value: T) -> [T] {
return [T](repeating: value, count: count)
}
```
Then, you can create the array:
```swift
var cookies = dim(9, dim(7, 0))
```
Swift infers that the datatype of the array must be `Int` because you specified `0` as the default value of the array elements. To use a string instead, you can write:
```swift
var cookies = dim(9, dim(7, "yum"))
```
The `dim()` function makes it easy to go into even more dimensions:
```swift
var threeDimensions = dim(2, dim(3, dim(4, 0)))
```
The downside of using multi-dimensional arrays or multiple nested arrays in this way is to lose track of what dimension represents what.
Instead, you can create your own type that acts like a 2-D array which is more convenient to use:
```swift
public struct Array2D<T> {
public let columns: Int
public let rows: Int
fileprivate var array: [T]
public init(columns: Int, rows: Int, initialValue: T) {
self.columns = columns
self.rows = rows
array = .init(repeating: initialValue, count: rows*columns)
}
public subscript(column: Int, row: Int) -> T {
get {
precondition(column < columns, "Column \(column) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
precondition(row < rows, "Row \(row) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
return array[row*columns + column]
}
set {
precondition(column < columns, "Column \(column) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
precondition(row < rows, "Row \(row) Index is out of range. Array<T>(columns: \(columns), rows:\(rows))")
array[row*columns + column] = newValue
}
}
}
```
`Array2D` is a generic type, so it can hold any kind of object, not just numbers.
To create an instance of `Array2D`, you can write:
```swift
var cookies = Array2D(columns: 9, rows: 7, initialValue: 0)
```
By using the `subscript` function, you can retrieve an object from the array:
```swift
let myCookie = cookies[column, row]
```
Or, you can change it:
```swift
cookies[column, row] = newCookie
```
Internally, `Array2D` uses a single one-dimensional array to store the data. The index of an object in that array is given by `(row x numberOfColumns) + column`, but as a user of `Array2D`, you only need to think in terms of "column" and "row", and the details will be done by `Array2D`. This is the advantage of wrapping primitive types into a wrapper class or struct.
*Written for Swift Algorithm Club by Matthijs Hollemans*
================================================
FILE: Array2D/Tests/Array2DTests.swift
================================================
//
// Array2DTest.swift
// algorithmclub
//
// Created by Barbara Rodeker on 2/16/16.
// Copyright © 2016 Swift Algorithm Club. All rights reserved.
//
import XCTest
class Array2DTest: XCTestCase {
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
}
func testIntegerArrayWithPositiveRowsAndColumns() {
let array = Array2D<Int>(columns: 3, rows: 2, initialValue: 0)
XCTAssertEqual(array.columns, 3, "Column count setup failed")
XCTAssertEqual(array.rows, 2, "Rows count setup failed")
XCTAssertEqual(array[2, 1], 0, "Integer array: Initialization value is wrong")
}
func testStringArrayWithPositiveRowsAndColumns() {
let array = Array2D<String>(columns: 3, rows: 2, initialValue: "empty")
XCTAssertEqual(array.columns, 3, "Column count setup failed")
XCTAssertEqual(array.rows, 2, "Rows count setup failed")
XCTAssertEqual(array[2, 1], "empty", "String array: Initialization value is wrong")
}
func testCustomClassArrayWithPositiveRowsAndColumns() {
let array = Array2D<TestElement>(columns: 3, rows: 2, initialValue: TestElement(identifier: "pepe"))
XCTAssertEqual(array.columns, 3, "Column count setup failed")
XCTAssertEqual(array.rows, 2, "Rows count setup failed")
XCTAssertEqual(array[2, 1], TestElement(identifier: "pepe"), "Custom Class array: Initialization value is wrong")
}
func testPerformanceOnSmallArray() {
self.measure {
self.printArrayWith(columns: 2, rows: 2, inititalValue: 1)
}
}
// func testPerformanceOnLargeArray() {
// self.measureBlock {
// self.printArrayWith(columns: 2000, rows: 2000, inititalValue: 1)
// }
// }
fileprivate func printArrayWith(columns: Int, rows: Int, inititalValue: Int) {
let array = Array2D(columns: columns, rows: rows, initialValue: 4)
for r in 0..<array.rows {
for c in 0..<array.columns {
print("Array in [\(r), \(c)] value is: \(array[c, r])")
}
}
}
}
class TestElement: Equatable {
let identifier: String
init(identifier: String) {
self.identifier = identifier
}
}
func == (lhs: TestElement, rhs: TestElement) -> Bool {
return lhs.identifier == rhs.identifier
}
================================================
FILE: Array2D/Tests/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
================================================
FILE: Array2D/Tests/Tests.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
7B2BBC901C779DAC0067B71D /* Array2DTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2BBC8F1C779DAC0067B71D /* Array2DTests.swift */; };
7B2BBC991C77A04F0067B71D /* Array2D.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2BBC981C77A04F0067B71D /* Array2D.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
7B2BBC801C779D720067B71D /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7B2BBC8F1C779DAC0067B71D /* Array2DTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Array2DTests.swift; sourceTree = SOURCE_ROOT; };
7B2BBC941C779E7B0067B71D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
7B2BBC981C77A04F0067B71D /* Array2D.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Array2D.swift; path = ../Array2D.swift; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7B2BBC7D1C779D720067B71D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
7B2BBC681C779D710067B71D = {
isa = PBXGroup;
children = (
7B2BBC831C779D720067B71D /* Tests */,
7B2BBC721C779D710067B71D /* Products */,
);
sourceTree = "<group>";
};
7B2BBC721C779D710067B71D /* Products */ = {
isa = PBXGroup;
children = (
7B2BBC801C779D720067B71D /* Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
7B2BBC831C779D720067B71D /* Tests */ = {
isa = PBXGroup;
children = (
7B2BBC981C77A04F0067B71D /* Array2D.swift */,
7B2BBC8F1C779DAC0067B71D /* Array2DTests.swift */,
7B2BBC941C779E7B0067B71D /* Info.plist */,
);
name = Tests;
path = TestsTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7B2BBC7F1C779D720067B71D /* Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7B2BBC8C1C779D720067B71D /* Build configuration list for PBXNativeTarget "Tests" */;
buildPhases = (
7B2BBC7C1C779D720067B71D /* Sources */,
7B2BBC7D1C779D720067B71D /* Frameworks */,
7B2BBC7E1C779D720067B71D /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Tests;
productName = TestsTests;
productReference = 7B2BBC801C779D720067B71D /* Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
7B2BBC691C779D710067B71D /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Swift Algorithm Club";
TargetAttributes = {
7B2BBC7F1C779D720067B71D = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800;
};
};
};
buildConfigurationList = 7B2BBC6C1C779D710067B71D /* Build configuration list for PBXProject "Tests" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 7B2BBC681C779D710067B71D;
productRefGroup = 7B2BBC721C779D710067B71D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
7B2BBC7F1C779D720067B71D /* Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
7B2BBC7E1C779D720067B71D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7B2BBC7C1C779D720067B71D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7B2BBC901C779DAC0067B71D /* Array2DTests.swift in Sources */,
7B2BBC991C77A04F0067B71D /* Array2D.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
7B2BBC871C779D720067B71D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
7B2BBC881C779D720067B71D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
};
name = Release;
};
7B2BBC8D1C779D720067B71D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
};
name = Debug;
};
7B2BBC8E1C779D720067B71D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7B2BBC6C1C779D710067B71D /* Build configuration list for PBXProject "Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7B2BBC871C779D720067B71D /* Debug */,
7B2BBC881C779D720067B71D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7B2BBC8C1C779D720067B71D /* Build configuration list for PBXNativeTarget "Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7B2BBC8D1C779D720067B71D /* Debug */,
7B2BBC8E1C779D720067B71D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 7B2BBC691C779D710067B71D /* Project object */;
}
================================================
FILE: Array2D/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Tests.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: Array2D/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B2BBC7F1C779D720067B71D"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: B-Tree/BTree.playground/Contents.swift
================================================
//: Playground - noun: a place where people can play
import Foundation
// last checked with Xcode 10.0
let bTree = BTree<Int, Int>(order: 1)!
bTree.insert(1, for: 1)
bTree.insert(2, for: 2)
bTree.insert(3, for: 3)
bTree.insert(4, for: 4)
bTree.value(for: 3)
bTree[3]
bTree.remove(2)
bTree.traverseKeysInOrder { key in
print(key)
}
bTree.numberOfKeys
bTree.order
bTree.inorderArrayFromKeys
================================================
FILE: B-Tree/BTree.playground/Sources/BTree.swift
================================================
// The MIT License (MIT)
// Copyright (c) 2016 Viktor Szilárd Simkó (aqviktor[at]gmail.com)
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
/*
* B-Tree
*
* A B-Tree is a self-balancing search tree, in which nodes can have more than two children.
*/
// MARK: - BTreeNode class
class BTreeNode<Key: Comparable, Value> {
/**
* The tree that owns the node.
*/
unowned var owner: BTree<Key, Value>
fileprivate var keys = [Key]()
fileprivate var values = [Value]()
var children: [BTreeNode]?
var isLeaf: Bool {
return children == nil
}
var numberOfKeys: Int {
return keys.count
}
init(owner: BTree<Key, Value>) {
self.owner = owner
}
convenience init(owner: BTree<Key, Value>, keys: [Key],
values: [Value], children: [BTreeNode]? = nil) {
self.init(owner: owner)
self.keys += keys
self.values += values
self.children = children
}
}
// MARK: BTreeNode extesnion: Searching
extension BTreeNode {
/**
* Returns the value for a given `key`, returns nil if the `key` is not found.
*
* - Parameters:
* - key: the key of the value to be returned
*/
func value(for key: Key) -> Value? {
var index = keys.startIndex
while (index + 1) < keys.endIndex && keys[index] < key {
index = (index + 1)
}
if key == keys[index] {
return values[index]
} else if key < keys[index] {
return children?[index].value(for: key)
} else {
return children?[(index + 1)].value(for: key)
}
}
}
// MARK: BTreeNode extension: Traversals
extension BTreeNode {
/**
* Traverses the keys in order, executes `process` for every key.
*
* - Parameters:
* - process: the closure to be executed for every key
*/
func traverseKeysInOrder(_ process: (Key) -> Void) {
for i in 0..<numberOfKeys {
children?[i].traverseKeysInOrder(process)
process(keys[i])
}
children?.last?.traverseKeysInOrder(process)
}
}
// MARK: BTreeNode extension: Insertion
extension BTreeNode {
/**
* Inserts `value` for `key` to the node, or to one if its descendants.
*
* - Parameters:
* - value: the value to be inserted for `key`
* - key: the key for the `value`
*/
func insert(_ value: Value, for key: Key) {
var index = keys.startIndex
while index < keys.endIndex && keys[index] < key {
index = (index + 1)
}
if index < keys.endIndex && keys[index] == key {
values[index] = value
return
}
if isLeaf {
keys.insert(key, at: index)
values.insert(value, at: index)
owner.numberOfKeys += 1
} else {
children![index].insert(value, for: key)
if children![index].numberOfKeys > owner.order * 2 {
split(child: children![index], atIndex: index)
}
}
}
/**
* Splits `child` at `index`.
* The key-value pair at `index` gets moved up to the parent node,
* or if there is not an parent node, then a new parent node is created.
*
* - Parameters:
* - child: the child to be split
* - index: the index of the key, which will be moved up to the parent
*/
private func split(child: BTreeNode, atIndex index: Int) {
let middleIndex = child.numberOfKeys / 2
keys.insert(child.keys[middleIndex], at: index)
values.insert(child.values[middleIndex], at: index)
child.keys.remove(at: middleIndex)
child.values.remove(at: middleIndex)
let rightSibling = BTreeNode(
owner: owner,
keys: Array(child.keys[child.keys.indices.suffix(from: middleIndex)]),
values: Array(child.values[child.values.indices.suffix(from: middleIndex)])
)
child.keys.removeSubrange(child.keys.indices.suffix(from: middleIndex))
child.values.removeSubrange(child.values.indices.suffix(from: middleIndex))
children!.insert(rightSibling, at: (index + 1))
if child.children != nil {
rightSibling.children = Array(
child.children![child.children!.indices.suffix(from: (middleIndex + 1))]
)
child.children!.removeSubrange(child.children!.indices.suffix(from: (middleIndex + 1)))
}
}
}
// MARK: BTreeNode extension: Removal
/**
* An enumeration to indicate a node's position according to another node.
*
* Possible values:
* - left
* - right
*/
private enum BTreeNodePosition {
case left
case right
}
extension BTreeNode {
private var inorderPredecessor: BTreeNode {
if isLeaf {
return self
} else {
return children!.last!.inorderPredecessor
}
}
/**
* Removes `key` and the value associated with it from the node
* or one of its descendants.
*
* - Parameters:
* - key: the key to be removed
*/
func remove(_ key: Key) {
var index = keys.startIndex
while (index + 1) < keys.endIndex && keys[index] < key {
index = (index + 1)
}
if keys[index] == key {
if isLeaf {
keys.remove(at: index)
values.remove(at: index)
owner.numberOfKeys -= 1
} else {
let predecessor = children![index].inorderPredecessor
keys[index] = predecessor.keys.last!
values[index] = predecessor.values.last!
children![index].remove(keys[index])
if children![index].numberOfKeys < owner.order {
fix(childWithTooFewKeys: children![index], atIndex: index)
}
}
} else if key < keys[index] {
// We should go to left child...
if let leftChild = children?[index] {
leftChild.remove(key)
if leftChild.numberOfKeys < owner.order {
fix(childWithTooFewKeys: leftChild, atIndex: index)
}
} else {
print("The key:\(key) is not in the tree.")
}
} else {
// We should go to right child...
if let rightChild = children?[(index + 1)] {
rightChild.remove(key)
if rightChild.numberOfKeys < owner.order {
fix(childWithTooFewKeys: rightChild, atIndex: (index + 1))
}
} else {
print("The key:\(key) is not in the tree")
}
}
}
/**
* Fixes `childWithTooFewKeys` by either moving a key to it from
* one of its neighbouring nodes, or by merging.
*
* - Precondition:
* `childWithTooFewKeys` must have less keys than the order of the tree.
*
* - Parameters:
* - child: the child to be fixed
* - index: the index of the child to be fixed in the current node
*/
private func fix(childWithTooFewKeys child: BTreeNode, atIndex index: Int) {
if (index - 1) >= 0 && children![(index - 1)].numberOfKeys > owner.order {
move(keyAtIndex: (index - 1), to: child, from: children![(index - 1)], at: .left)
} else if (index + 1) < children!.count && children![(index + 1)].numberOfKeys > owner.order {
move(keyAtIndex: index, to: child, from: children![(index + 1)], at: .right)
} else if (index - 1) >= 0 {
merge(child: child, atIndex: index, to: .left)
} else {
merge(child: child, atIndex: index, to: .right)
}
}
/**
* Moves the key at the specified `index` from `node` to
* the `targetNode` at `position`
*
* - Parameters:
* - index: the index of the key to be moved in `node`
* - targetNode: the node to move the key into
* - node: the node to move the key from
* - position: the position of the from node relative to the targetNode
*/
private func move(keyAtIndex index: Int, to targetNode: BTreeNode,
from node: BTreeNode, at position: BTreeNodePosition) {
switch position {
case .left:
targetNode.keys.insert(keys[index], at: targetNode.keys.startIndex)
targetNode.values.insert(values[index], at: targetNode.values.startIndex)
keys[index] = node.keys.last!
values[index] = node.values.last!
node.keys.removeLast()
node.values.removeLast()
if !targetNode.isLeaf {
targetNode.children!.insert(node.children!.last!,
at: targetNode.children!.startIndex)
node.children!.removeLast()
}
case .right:
targetNode.keys.insert(keys[index], at: targetNode.keys.endIndex)
targetNode.values.insert(values[index], at: targetNode.values.endIndex)
keys[index] = node.keys.first!
values[index] = node.values.first!
node.keys.removeFirst()
node.values.removeFirst()
if !targetNode.isLeaf {
targetNode.children!.insert(node.children!.first!,
at: targetNode.children!.endIndex)
node.children!.removeFirst()
}
}
}
/**
* Merges `child` at `position` to the node at the `position`.
*
* - Parameters:
* - child: the child to be merged
* - index: the index of the child in the current node
* - position: the position of the node to merge into
*/
private func merge(child: BTreeNode, atIndex index: Int, to position: BTreeNodePosition) {
switch position {
case .left:
// We can merge to the left sibling
children![(index - 1)].keys = children![(index - 1)].keys +
[keys[(index - 1)]] + child.keys
children![(index - 1)].values = children![(index - 1)].values +
[values[(index - 1)]] + child.values
keys.remove(at: (index - 1))
values.remove(at: (index - 1))
if !child.isLeaf {
children![(index - 1)].children =
children![(index - 1)].children! + child.children!
}
case .right:
// We should merge to the right sibling
children![(index + 1)].keys = child.keys + [keys[index]] +
children![(index + 1)].keys
children![(index + 1)].values = child.values + [values[index]] +
children![(index + 1)].values
keys.remove(at: index)
values.remove(at: index)
if !child.isLeaf {
children![(index + 1)].children =
child.children! + children![(index + 1)].children!
}
}
children!.remove(at: index)
}
}
// MARK: BTreeNode extension: Conversion
extension BTreeNode {
/**
* Returns an array which contains the keys from the current node
* and its descendants in order.
*/
var inorderArrayFromKeys: [Key] {
var array = [Key] ()
for i in 0..<numberOfKeys {
if let returnedArray = children?[i].inorderArrayFromKeys {
array += returnedArray
}
array += [keys[i]]
}
if let returnedArray = children?.last?.inorderArrayFromKeys {
array += returnedArray
}
return array
}
}
// MARK: BTreeNode extension: Description
extension BTreeNode: CustomStringConvertible {
/**
* Returns a String containing the preorder representation of the nodes.
*/
var description: String {
var str = "\(keys)"
if !isLeaf {
for child in children! {
str += child.description
}
}
return str
}
}
// MARK: - BTree class
public class BTree<Key: Comparable, Value> {
/**
* The order of the B-Tree
*
* The number of keys in every node should be in the [order, 2*order] range,
* except the root node which is allowed to contain less keys than the value of order.
*/
public let order: Int
/**
* The root node of the tree
*/
var rootNode: BTreeNode<Key, Value>!
fileprivate(set) public var numberOfKeys = 0
/**
* Designated initializer for the tree
*
* - Parameters:
* - order: The order of the tree.
*/
public init?(order: Int) {
guard order > 0 else {
print("Order has to be greater than 0.")
return nil
}
self.order = order
rootNode = BTreeNode<Key, Value>(owner: self)
}
}
// MARK: BTree extension: Traversals
extension BTree {
/**
* Traverses the keys in order, executes `process` for every key.
*
* - Parameters:
* - process: the closure to be executed for every key
*/
public func traverseKeysInOrder(_ process: (Key) -> Void) {
rootNode.traverseKeysInOrder(process)
}
}
// MARK: BTree extension: Subscript
extension BTree {
/**
* Returns the value for a given `key`, returns nil if the `key` is not found.
*
* - Parameters:
* - key: the key of the value to be returned
*/
public subscript (key: Key) -> Value? {
return value(for: key)
}
}
// MARK: BTree extension: Value for Key
extension BTree {
/**
* Returns the value for a given `key`, returns nil if the `key` is not found.
*
* - Parameters:
* - key: the key of the value to be returned
*/
public func value(for key: Key) -> Value? {
guard rootNode.numberOfKeys > 0 else {
return nil
}
return rootNode.value(for: key)
}
}
// MARK: BTree extension: Insertion
extension BTree {
/**
* Inserts the `value` for the `key` into the tree.
*
* - Parameters:
* - value: the value to be inserted for `key`
* - key: the key for the `value`
*/
public func insert(_ value: Value, for key: Key) {
rootNode.insert(value, for: key)
if rootNode.numberOfKeys > order * 2 {
splitRoot()
}
}
/**
* Splits the root node of the tree.
*
* - Precondition:
* The root node of the tree contains `order` * 2 keys.
*/
private func splitRoot() {
let middleIndexOfOldRoot = rootNode.numberOfKeys / 2
let newRoot = BTreeNode<Key, Value>(
owner: self,
keys: [rootNode.keys[middleIndexOfOldRoot]],
values: [rootNode.values[middleIndexOfOldRoot]],
children: [rootNode]
)
rootNode.keys.remove(at: middleIndexOfOldRoot)
rootNode.values.remove(at: middleIndexOfOldRoot)
let newRightChild = BTreeNode<Key, Value>(
owner: self,
keys: Array(rootNode.keys[rootNode.keys.indices.suffix(from: middleIndexOfOldRoot)]),
values: Array(rootNode.values[rootNode.values.indices.suffix(from: middleIndexOfOldRoot)])
)
rootNode.keys.removeSubrange(rootNode.keys.indices.suffix(from: middleIndexOfOldRoot))
rootNode.values.removeSubrange(rootNode.values.indices.suffix(from: middleIndexOfOldRoot))
if rootNode.children != nil {
newRightChild.children = Array(
rootNode.children![rootNode.children!.indices.suffix(from: (middleIndexOfOldRoot + 1))]
)
rootNode.children!.removeSubrange(
rootNode.children!.indices.suffix(from: (middleIndexOfOldRoot + 1))
)
}
newRoot.children!.append(newRightChild)
rootNode = newRoot
}
}
// MARK: BTree extension: Removal
extension BTree {
/**
* Removes `key` and the value associated with it from the tree.
*
* - Parameters:
* - key: the key to remove
*/
public func remove(_ key: Key) {
guard rootNode.numberOfKeys > 0 else {
return
}
rootNode.remove(key)
if rootNode.numberOfKeys == 0 && !rootNode.isLeaf {
rootNode = rootNode.children!.first!
}
}
}
// MARK: BTree extension: Conversion
extension BTree {
/**
* The keys of the tree in order.
*/
public var inorderArrayFromKeys: [Key] {
return rootNode.inorderArrayFromKeys
}
}
// MARK: BTree extension: Decription
extension BTree: CustomStringConvertible {
/**
* Returns a String containing the preorder representation of the nodes.
*/
public var description: String {
return rootNode.description
}
}
================================================
FILE: B-Tree/BTree.playground/contents.xcplayground
================================================
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx'>
<timeline fileName='timeline.xctimeline'/>
</playground>
================================================
FILE: B-Tree/BTree.playground/playground.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: B-Tree/BTree.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: B-Tree/BTree.swift
================================================
// The MIT License (MIT)
// Copyright (c) 2016 Viktor Szilárd Simkó (aqviktor[at]gmail.com)
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
/*
* B-Tree
*
* A B-Tree is a self-balancing search tree, in which nodes can have more than two children.
*/
// MARK: - BTreeNode class
class BTreeNode<Key: Comparable, Value> {
/**
* The tree that owns the node.
*/
unowned var owner: BTree<Key, Value>
fileprivate var keys = [Key]()
fileprivate var values = [Value]()
var children: [BTreeNode]?
var isLeaf: Bool {
return children == nil
}
var numberOfKeys: Int {
return keys.count
}
init(owner: BTree<Key, Value>) {
self.owner = owner
}
convenience init(owner: BTree<Key, Value>, keys: [Key],
values: [Value], children: [BTreeNode]? = nil) {
self.init(owner: owner)
self.keys += keys
self.values += values
self.children = children
}
}
// MARK: BTreeNode extesnion: Searching
extension BTreeNode {
/**
* Returns the value for a given `key`, returns nil if the `key` is not found.
*
* - Parameters:
* - key: the key of the value to be returned
*/
func value(for key: Key) -> Value? {
var index = keys.startIndex
while (index + 1) < keys.endIndex && keys[index] < key {
index = (index + 1)
}
if key == keys[index] {
return values[index]
} else if key < keys[index] {
return children?[index].value(for: key)
} else {
return children?[(index + 1)].value(for: key)
}
}
}
// MARK: BTreeNode extension: Travelsals
extension BTreeNode {
/**
* Traverses the keys in order, executes `process` for every key.
*
* - Parameters:
* - process: the closure to be executed for every key
*/
func traverseKeysInOrder(_ process: (Key) -> Void) {
for i in 0..<numberOfKeys {
children?[i].traverseKeysInOrder(process)
process(keys[i])
}
children?.last?.traverseKeysInOrder(process)
}
}
// MARK: BTreeNode extension: Insertion
extension BTreeNode {
/**
* Inserts `value` for `key` to the node, or to one if its descendants.
*
* - Parameters:
* - value: the value to be inserted for `key`
* - key: the key for the `value`
*/
func insert(_ value: Value, for key: Key) {
var index = keys.startIndex
while index < keys.endIndex && keys[index] < key {
index = (index + 1)
}
if index < keys.endIndex && keys[index] == key {
values[index] = value
return
}
if isLeaf {
keys.insert(key, at: index)
values.insert(value, at: index)
owner.numberOfKeys += 1
} else {
children![index].insert(value, for: key)
if children![index].numberOfKeys > owner.order * 2 {
split(child: children![index], atIndex: index)
}
}
}
/**
* Splits `child` at `index`.
* The key-value pair at `index` gets moved up to the parent node,
* or if there is not an parent node, then a new parent node is created.
*
* - Parameters:
* - child: the child to be split
* - index: the index of the key, which will be moved up to the parent
*/
private func split(child: BTreeNode, atIndex index: Int) {
let middleIndex = child.numberOfKeys / 2
keys.
gitextract_cau619vu/ ├── .github/ │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .swiftlint.yml ├── 3Sum and 4Sum/ │ ├── 3Sum.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── 4Sum.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── README.md ├── A-Star/ │ ├── AStar.swift │ ├── Images/ │ │ ├── graph.dot │ │ ├── step1.dot │ │ ├── step2.dot │ │ ├── step3.dot │ │ ├── step4.dot │ │ ├── step5.dot │ │ ├── step6.dot │ │ └── step7.dot │ ├── README.md │ └── Tests/ │ ├── AStarTests.swift │ ├── AStarTests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── AStarTests.xcscheme │ └── Info.plist ├── AVL Tree/ │ ├── AVLTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── AVLTree.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── AVLTree.swift │ ├── Images/ │ │ ├── BalanceNotOK.graffle │ │ ├── BalanceOK.graffle │ │ ├── Balanced.graffle │ │ ├── Height.graffle │ │ └── Unbalanced.graffle │ ├── README.markdown │ └── Tests/ │ ├── AVLTreeTests.swift │ ├── Info.plist │ ├── Tests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Tests.xcscheme │ └── TreeNodeTests.swift ├── Algorithm Design.markdown ├── All-Pairs Shortest Paths/ │ ├── APSP/ │ │ ├── APSP/ │ │ │ ├── APSP.h │ │ │ ├── APSP.swift │ │ │ ├── FloydWarshall.swift │ │ │ ├── Helpers.swift │ │ │ └── Info.plist │ │ ├── APSP.playground/ │ │ │ ├── Contents.swift │ │ │ ├── contents.xcplayground │ │ │ ├── playground.xcworkspace/ │ │ │ │ └── contents.xcworkspacedata │ │ │ └── timeline.xctimeline │ │ ├── APSP.xcodeproj/ │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace/ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata/ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ └── xcshareddata/ │ │ │ └── xcschemes/ │ │ │ ├── APSP.xcscheme │ │ │ └── APSPTests.xcscheme │ │ ├── APSP.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ └── APSPTests/ │ │ ├── APSPTests.swift │ │ └── Info.plist │ └── README.markdown ├── Array2D/ │ ├── Array2D.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── Array2D.swift │ ├── README.markdown │ └── Tests/ │ ├── Array2DTests.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── B-Tree/ │ ├── BTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── BTree.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── BTree.swift │ ├── README.md │ └── Tests/ │ ├── Tests/ │ │ ├── BTreeNodeTests.swift │ │ ├── BTreeTests.swift │ │ └── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Big-O Notation.markdown ├── Binary Search/ │ ├── BinarySearch.playground/ │ │ ├── Contents.swift │ │ └── contents.xcplayground │ ├── BinarySearch.swift │ ├── README.markdown │ └── Tests/ │ ├── BinarySearchTests.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Binary Search Tree/ │ ├── Images/ │ │ ├── DeleteLeaf.graffle │ │ ├── DeleteOneChild.graffle │ │ ├── DeleteTwoChildren.graffle │ │ ├── MinimumMaximum.graffle │ │ ├── Searching.graffle │ │ ├── Traversing.graffle │ │ ├── Tree1.graffle │ │ └── Tree2.graffle │ ├── README.markdown │ ├── Solution 1/ │ │ ├── BinarySearchTree.playground/ │ │ │ ├── Contents.swift │ │ │ ├── Sources/ │ │ │ │ └── BinarySearchTree.swift │ │ │ ├── contents.xcplayground │ │ │ └── playground.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── Tests/ │ │ ├── BinarySearchTreeTests.swift │ │ ├── Info.plist │ │ └── Tests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Tests.xcscheme │ └── Solution 2/ │ ├── BinarySearchTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── BinarySearchTree.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── BinarySearchTree.swift ├── Binary Tree/ │ ├── BinaryTree.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── BinaryTree.swift │ ├── Images/ │ │ ├── BinaryTree.graffle │ │ └── Operations.graffle │ └── README.markdown ├── Bit Set/ │ ├── BitSet.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── BitSet.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── README.markdown ├── Bloom Filter/ │ ├── BloomFilter.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── BloomFilter.swift │ ├── README.markdown │ └── Tests/ │ ├── BloomFilterTests.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Bounded Priority Queue/ │ ├── BoundedPriorityQueue.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── BoundedPriorityQueue.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── BoundedPriorityQueue.swift │ ├── README.markdown │ └── Tests/ │ ├── BoundedPriorityQueueTests.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Boyer-Moore-Horspool/ │ ├── BoyerMooreHorspool.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ ├── playground.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── timeline.xctimeline │ ├── BoyerMooreHorspool.swift │ ├── README.markdown │ └── Tests/ │ ├── BoyerMooreHorspoolTests.swift │ ├── BoyerMooreTests.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Breadth-First Search/ │ ├── BreadthFirstSearch.playground/ │ │ ├── Pages/ │ │ │ └── Simple example.xcplaygroundpage/ │ │ │ └── Contents.swift │ │ ├── Sources/ │ │ │ ├── Edge.swift │ │ │ ├── Graph.swift │ │ │ ├── Node.swift │ │ │ └── Queue.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── BreadthFirstSearch.swift │ ├── Images/ │ │ ├── AnimatedExample.graffle │ │ ├── AnimatedExample.psd │ │ └── TraversalTree.graffle │ ├── README.markdown │ └── Tests/ │ ├── BreadthFirstSearchTests.swift │ ├── Graph.swift │ ├── Info.plist │ ├── Queue.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Brute-Force String Search/ │ ├── BruteForceStringSearch.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── BruteForceStringSearch.swift │ └── README.markdown ├── Bubble Sort/ │ ├── MyPlayground.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── BubbleSort.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── README.markdown ├── Bucket Sort/ │ ├── BucketSort.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── BucketSort.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── BucketSort.swift │ ├── README.markdown │ └── Tests/ │ ├── Info.plist │ ├── Tests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Closest Pair/ │ ├── ClosestPair.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── README.markdown ├── Comb Sort/ │ ├── Comb Sort.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── Comb Sort.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── Comb Sort.swift │ ├── README.markdown │ └── Tests/ │ ├── CombSortTests.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Combinatorics/ │ ├── Combinatorics.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── README.markdown ├── Convex Hull/ │ ├── Convex Hull/ │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets/ │ │ │ └── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ └── LaunchScreen.storyboard │ │ ├── Info.plist │ │ └── View.swift │ ├── Convex Hull.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Tests.xcscheme │ ├── README.md │ └── Tests/ │ ├── Info.plist │ └── Tests.swift ├── Count Occurrences/ │ ├── CountOccurrences.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── CountOccurrences.swift │ └── README.markdown ├── CounterClockWise/ │ ├── CounterClockWise.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── CounterClockWise.swift │ └── README.md ├── Counting Sort/ │ ├── CountingSort.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── CountingSort.swift │ ├── README.markdown │ └── Tests/ │ ├── CountingSortTest.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Depth-First Search/ │ ├── DepthFirstSearch.playground/ │ │ ├── Edge.o │ │ ├── Graph.o │ │ ├── Node.o │ │ ├── Pages/ │ │ │ └── Simple Example.xcplaygroundpage/ │ │ │ └── Contents.swift │ │ ├── Sources/ │ │ │ ├── Edge.swift │ │ │ ├── Graph.swift │ │ │ └── Node.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── DepthFirstSearch.swift │ ├── Images/ │ │ ├── AnimatedExample.graffle │ │ ├── AnimatedExample.psd │ │ └── TraversalTree.graffle │ ├── README.markdown │ └── Tests/ │ ├── DepthFirstSearchTests.swift │ ├── Graph.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Deque/ │ ├── Deque-Optimized.swift │ ├── Deque-Simple.swift │ ├── Deque.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── README.markdown ├── Dijkstra Algorithm/ │ ├── Dijkstra.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ ├── Dijkstra.swift │ │ │ └── Vertex.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── README.md │ └── VisualizedDijkstra.playground/ │ ├── Contents.swift │ ├── Sources/ │ │ ├── CustomUI/ │ │ │ ├── EdgeRepresentation.swift │ │ │ ├── ErrorView.swift │ │ │ ├── MyShapeLayer.swift │ │ │ ├── RoundedButton.swift │ │ │ └── VertexView.swift │ │ ├── Graph.swift │ │ ├── GraphColors.swift │ │ ├── GraphView.swift │ │ ├── SimpleObjects/ │ │ │ ├── Edge.swift │ │ │ └── Vertex.swift │ │ └── Window.swift │ ├── contents.xcplayground │ └── playground.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── DiningPhilosophers/ │ ├── DiningPhilosophers.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ ├── DiningPhilosophers.xcscheme │ │ └── xcschememanagement.plist │ ├── LICENSE │ ├── Package.swift │ ├── README.md │ └── Sources/ │ └── main.swift ├── Egg Drop Problem/ │ ├── EggDrop.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── EggDrop.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ ├── EggDrop.swift │ └── README.markdown ├── Encode and Decode Tree/ │ ├── EncodeAndDecodeTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── EncodeAndDecodeTree.swift │ │ └── contents.xcplayground │ ├── EncodeAndDecodeTree.swift │ └── readme.md ├── Fixed Size Array/ │ ├── FixedSizeArray.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ ├── playground.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── timeline.xctimeline │ ├── Images/ │ │ └── FixedSizeArrays.graffle │ └── README.markdown ├── Fizz Buzz/ │ ├── FizzBuzz.playground/ │ │ └── Contents.swift │ ├── FizzBuzz.swift │ └── README.markdown ├── GCD/ │ ├── GCD.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── GCD.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── README.markdown ├── Genetic/ │ ├── README.markdown │ ├── gen.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── gen.swift ├── Graph/ │ ├── Graph/ │ │ ├── AdjacencyListGraph.swift │ │ ├── AdjacencyMatrixGraph.swift │ │ ├── Edge.swift │ │ ├── Graph.h │ │ ├── Graph.swift │ │ ├── Info.plist │ │ └── Vertex.swift │ ├── Graph.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ ├── playground.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── timeline.xctimeline │ ├── Graph.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ ├── Graph.xcscheme │ │ └── GraphTests.xcscheme │ ├── Graph.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ ├── GraphTests/ │ │ ├── GraphTests.swift │ │ └── Info.plist │ ├── Images/ │ │ ├── AdjacencyList.graffle │ │ ├── AdjacencyMatrix.graffle │ │ ├── ChordMap.graffle │ │ ├── CoreData.graffle │ │ ├── DAG.graffle │ │ ├── Demo1.graffle │ │ ├── Flights.graffle │ │ ├── FlightsDirected.graffle │ │ ├── Graph.graffle │ │ ├── SocialNetwork.graffle │ │ ├── StateMachine.graffle │ │ ├── Tasks.graffle │ │ └── TreeAndList.graffle │ └── README.markdown ├── Hash Set/ │ ├── HashSet.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── HashSet.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── HashSet.swift │ ├── Images/ │ │ └── CombineSets.graffle │ └── README.markdown ├── Hash Table/ │ ├── HashTable.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── HashTable.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── README.markdown ├── Hashed Heap/ │ ├── HashedHeap.swift │ ├── README.markdown │ └── Tests/ │ ├── Hashed Heap Tests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Hashed Heap Tests.xcscheme │ ├── HashedHeapTests.swift │ └── Info.plist ├── HaversineDistance/ │ ├── HaversineDistance.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── README.md ├── Heap/ │ ├── Heap.swift │ ├── Images/ │ │ ├── Array.graffle │ │ ├── Heap1.graffle │ │ ├── HeapShape.graffle │ │ ├── Insert1.graffle │ │ ├── Insert2.graffle │ │ ├── Insert3.graffle │ │ ├── LargeHeap.graffle │ │ ├── RegularTree.graffle │ │ ├── Remove1.graffle │ │ ├── Remove2.graffle │ │ ├── Remove3.graffle │ │ ├── Remove4.graffle │ │ ├── Remove5.graffle │ │ └── SortedArray.graffle │ ├── README.markdown │ └── Tests/ │ ├── HeapTests.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Heap Sort/ │ ├── HeapSort.swift │ ├── Images/ │ │ └── MaxHeap.graffle │ ├── README.markdown │ └── Tests/ │ ├── HeapSortTests.swift │ ├── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Huffman Coding/ │ ├── Huffman.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ ├── Heap.swift │ │ │ ├── Huffman.swift │ │ │ ├── NSData+Bits.swift │ │ │ └── PriorityQueue.swift │ │ ├── contents.xcplayground │ │ ├── playground.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── timeline.xctimeline │ ├── Huffman.swift │ ├── Images/ │ │ ├── BuildTree.graffle │ │ ├── BuildTree.psd │ │ ├── Compression.graffle │ │ ├── Decompression.graffle │ │ └── Tree.graffle │ ├── NSData+Bits.swift │ └── README.markdown ├── Insertion Sort/ │ ├── InsertionSort.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── InsertionSort.swift │ ├── README.markdown │ └── Tests/ │ ├── Info.plist │ ├── InsertionSortTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Introsort/ │ ├── HeapSort.swift │ ├── InsertionSort.swift │ ├── IntroSort.swift │ ├── Introsort.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ ├── HeapSort.swift │ │ │ ├── InsertionSort.swift │ │ │ ├── Partition.swift │ │ │ ├── Randomize.swift │ │ │ └── Sort3.swift │ │ └── contents.xcplayground │ ├── Partition.swift │ ├── README.markdown │ ├── Randomize.swift │ └── Sort3.swift ├── K-Means/ │ ├── KMeans.swift │ ├── README.markdown │ └── Tests/ │ ├── Info.plist │ ├── KMeansTests.swift │ ├── Tests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Tests.xcscheme │ └── Vector.swift ├── Karatsuba Multiplication/ │ ├── KaratsubaMultiplication.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── KaratsubaMultiplication.swift │ ├── README.markdown │ └── Tests/ │ ├── KaratsubaMultiplicationTests.swift │ ├── Tests/ │ │ └── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Knuth-Morris-Pratt/ │ ├── KnuthMorrisPratt.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── KnuthMorrisPratt.swift │ └── README.markdown ├── Kth Largest Element/ │ ├── README.markdown │ └── kthLargest.playground/ │ ├── Contents.swift │ ├── Sources/ │ │ └── kthLargest.swift │ ├── contents.xcplayground │ └── playground.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── kthLargest.xcscmblueprint ├── LICENSE.txt ├── LRU Cache/ │ ├── LRUCache.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ ├── LRUCache.swift │ │ │ └── LinkedList.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── LRUCache.swift │ └── Readme.md ├── Linear Regression/ │ ├── LinearRegression.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── README.markdown ├── Linear Search/ │ ├── LinearSearch.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── LinearSearch.swift │ └── README.markdown ├── Linked List/ │ ├── LinkedList.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── LinkedList.swift │ ├── README.markdown │ └── Tests/ │ ├── Info.plist │ ├── LinkedListTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Longest Common Subsequence/ │ ├── LongestCommonSubsequence.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── LongestCommonSubsequence.swift │ ├── README.markdown │ └── Tests/ │ ├── LongestCommonSubsequenceTests.swift │ ├── Tests/ │ │ └── Info.plist │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Merge Sort/ │ ├── MergeSort.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── MergeSort.swift │ └── README.markdown ├── Miller-Rabin Primality Test/ │ ├── MRPrimality.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── MillerRabin.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── MRPrimality.swift │ └── README.markdown ├── Minimum Edit Distance/ │ ├── MinimumEditDistance.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── README.markdown ├── Minimum Spanning Tree/ │ ├── Kruskal.swift │ ├── MinimumSpanningTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ ├── Graph.swift │ │ │ ├── Heap.swift │ │ │ ├── PriorityQueue.swift │ │ │ └── UnionFind.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── Prim.swift │ └── README.markdown ├── Minimum Spanning Tree (Unweighted)/ │ ├── Images/ │ │ ├── Graph.sketch │ │ ├── MinimumSpanningTree.sketch │ │ └── Tree.graffle │ ├── MinimumSpanningTree.playground/ │ │ ├── Pages/ │ │ │ └── Minimum spanning tree example.xcplaygroundpage/ │ │ │ └── Contents.swift │ │ ├── Sources/ │ │ │ ├── Edge.swift │ │ │ ├── Graph.swift │ │ │ ├── Node.swift │ │ │ └── Queue.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── MinimumSpanningTree.swift │ ├── README.markdown │ └── Tests/ │ ├── Graph.swift │ ├── Info.plist │ ├── MinimumSpanningTreeTests.swift │ ├── Queue.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── MinimumCoinChange/ │ ├── LICENSE │ ├── Package.swift │ ├── README.md │ ├── Sources/ │ │ └── MinimumCoinChange.swift │ └── Tests/ │ ├── LinuxMain.swift │ └── MinimumCoinChangeTests/ │ └── MinimumCoinChangeTests.swift ├── Monty Hall Problem/ │ ├── MontyHall.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── README.markdown ├── Multiset/ │ ├── Multiset.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── Multiset.swift │ │ └── contents.xcplayground │ └── README.markdown ├── Myers Difference Algorithm/ │ ├── MyersDifferenceAlgorithm.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── MyersDifferenceAlgorithm.swift │ │ └── contents.xcplayground │ ├── MyersDifferenceAlgorithm.swift │ └── README.md ├── Naive Bayes Classifier/ │ ├── NaiveBayes.playground/ │ │ ├── Contents.swift │ │ ├── Resources/ │ │ │ └── wine.csv │ │ ├── Sources/ │ │ │ └── NaiveBayes.swift │ │ ├── contents.xcplayground │ │ ├── playground.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── timeline.xctimeline │ ├── NaiveBayes.swift │ └── README.md ├── Octree/ │ ├── Octree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── Octree.swift │ │ ├── contents.xcplayground │ │ └── timeline.xctimeline │ └── README.md ├── Ordered Array/ │ ├── OrderedArray.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── OrderedArray.swift │ └── README.markdown ├── Ordered Set/ │ ├── OrderedSet.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── OrderedSet.swift │ │ └── contents.xcplayground │ ├── OrderedSet.swift │ └── README.markdown ├── Palindromes/ │ ├── Palindromes.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── Palindrome.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── README.markdown │ └── Test/ │ ├── Palindrome.swift │ ├── Test/ │ │ ├── Info.plist │ │ └── Test.swift │ └── Test.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Test.xcscheme ├── Points Lines Planes/ │ ├── Points Lines Planes/ │ │ ├── 2D/ │ │ │ ├── Line2D.swift │ │ │ └── Point2D.swift │ │ └── main.swift │ ├── Points Lines Planes.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── README.md ├── Priority Queue/ │ ├── PriorityQueue.swift │ ├── README.markdown │ └── Tests/ │ ├── Info.plist │ ├── PriorityQueueTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── QuadTree/ │ ├── QuadTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── QuadTree.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── README.md │ └── Tests/ │ ├── Tests/ │ │ ├── Info.plist │ │ └── Tests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ └── project.xcworkspace/ │ └── contents.xcworkspacedata ├── Queue/ │ ├── Queue-Optimized.swift │ ├── Queue-Simple.swift │ ├── Queue.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── README.markdown │ └── Tests/ │ ├── Info.plist │ ├── QueueTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Quicksort/ │ ├── Images/ │ │ └── Example.graffle │ ├── Quicksort.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── Quicksort.swift │ ├── README.markdown │ └── Tests/ │ ├── Info.plist │ ├── QuicksortTests.swift │ ├── SortingTestHelpers.swift │ └── Tests-Quicksort.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests-Quicksort.xcscheme ├── README.markdown ├── Rabin-Karp/ │ ├── README.markdown │ ├── Rabin-Karp.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── rabin-karp.swift ├── Radix Sort/ │ ├── RadixSort.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── radixSort.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── RadixSortExample.swift │ ├── ReadMe.md │ ├── Tests/ │ │ ├── Info.plist │ │ ├── RadixSortTests.swift │ │ └── Tests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Tests.xcscheme │ └── radixSort.swift ├── Radix Tree/ │ ├── README.markdown │ ├── RadixTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── RadixTree.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── RadixTree.swift ├── Red-Black Tree/ │ ├── README.markdown │ ├── RedBlackTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── RedBlackTree.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── RedBlackTree.swift ├── Ring Buffer/ │ ├── README.markdown │ ├── RingBuffer.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── RingBuffer.swift ├── Rootish Array Stack/ │ ├── README.md │ ├── RootishArrayStack.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── RootishArrayStack.swift │ └── Tests/ │ ├── Info.plist │ ├── RootishArrayStack.swift │ ├── RootishArrayStackTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Run-Length Encoding/ │ ├── README.markdown │ └── RLE.playground/ │ ├── Contents.swift │ ├── Sources/ │ │ └── RLE.swift │ ├── contents.xcplayground │ └── playground.xcworkspace/ │ └── contents.xcworkspacedata ├── Segment Tree/ │ ├── LazyPropagation/ │ │ ├── LazyPropagation.playground/ │ │ │ ├── Contents.swift │ │ │ ├── contents.xcplayground │ │ │ └── playground.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── README.markdown │ ├── README.markdown │ ├── SegmentTree.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── SegmentTree.swift ├── Select Minimum Maximum/ │ ├── Maximum.swift │ ├── Minimum.swift │ ├── MinimumMaximumPairs.swift │ ├── README.markdown │ ├── SelectMinimumMaximum.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── Tests/ │ ├── Info.plist │ ├── MaximumTests.swift │ ├── MinimumMaximumPairsTests.swift │ ├── MinimumTests.swift │ ├── TestHelper.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Selection Sampling/ │ ├── README.markdown │ ├── SelectionSampling.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── SelectionSampling.swift ├── Selection Sort/ │ ├── README.markdown │ ├── SelectionSort.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── SelectionSort.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── SelectionSort.swift │ └── Tests/ │ ├── Info.plist │ ├── SelectionSortTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Set Cover (Unweighted)/ │ ├── README.markdown │ ├── SetCover.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ ├── RandomArrayOfSets.swift │ │ │ └── SetCover.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── SetCover.swift ├── Shell Sort/ │ ├── README.markdown │ ├── Shell Sort.playground/ │ │ ├── Contents.swift │ │ └── contents.xcplayground │ ├── ShellSortExample.swift │ ├── Tests/ │ │ ├── Info.plist │ │ ├── ShellSortTests.swift │ │ └── Tests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Tests.xcscheme │ └── shellsort.swift ├── Shortest Path (Unweighted)/ │ ├── Images/ │ │ └── Graph.graffle │ ├── README.markdown │ ├── ShortestPath.playground/ │ │ ├── Pages/ │ │ │ └── Shortest path example.xcplaygroundpage/ │ │ │ └── Contents.swift │ │ ├── Sources/ │ │ │ ├── Edge.swift │ │ │ ├── Graph.swift │ │ │ ├── Node.swift │ │ │ └── Queue.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── ShortestPath.swift │ └── Tests/ │ ├── Graph.swift │ ├── Info.plist │ ├── Queue.swift │ ├── ShortestPathTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Shuffle/ │ ├── README.markdown │ ├── Shuffle.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── Shuffle.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── Shuffle.swift ├── Shunting Yard/ │ ├── README.markdown │ ├── ShuntingYard.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── Stack.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── ShuntingYard.swift ├── Simulated annealing/ │ ├── README.md │ ├── simann.swift │ └── simann_example.swift ├── Single-Source Shortest Paths (Weighted)/ │ ├── README.markdown │ ├── SSSP/ │ │ ├── BellmanFord.swift │ │ ├── Info.plist │ │ ├── SSSP.h │ │ └── SSSP.swift │ ├── SSSP.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── SSSP.xcodeproj/ │ │ ├── project.pbxproj │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ ├── SSSP.xcscheme │ │ └── SSSPTests.xcscheme │ ├── SSSP.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── WorkspaceSettings.xcsettings │ └── SSSPTests/ │ ├── Info.plist │ └── SSSPTests.swift ├── Singly Linked List/ │ ├── KeyValuePair.swift │ ├── README.markdown │ ├── SinglyLinkedList.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── SinglyLinkedList.swift │ └── Tests/ │ ├── Tests/ │ │ ├── Info.plist │ │ └── SinglyLinkedListTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Skip-List/ │ ├── README.md │ ├── SkipList.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── SkipList.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── SkipList.swift ├── Slow Sort/ │ ├── README.markdown │ ├── SlowSort.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── SlowSort.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── SlowSort.swift ├── Sorted Set/ │ ├── README.markdown │ ├── SortedSet.playground/ │ │ ├── Pages/ │ │ │ ├── Example 1.xcplaygroundpage/ │ │ │ │ ├── Contents.swift │ │ │ │ └── timeline.xctimeline │ │ │ ├── Example 2.xcplaygroundpage/ │ │ │ │ └── Contents.swift │ │ │ └── Example 3.xcplaygroundpage/ │ │ │ └── Contents.swift │ │ ├── Sources/ │ │ │ ├── Player.swift │ │ │ ├── Random.swift │ │ │ └── SortedSet.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── SortedSet.swift ├── Sparse Table/ │ ├── README.markdown │ └── Sparse Table.playground/ │ ├── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace/ │ └── contents.xcworkspacedata ├── Splay Tree/ │ ├── SplayTree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── SplayTree.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── SplayTree.swift │ ├── Tests/ │ │ ├── Info.plist │ │ ├── SplayTreeTests.swift │ │ ├── Tests-Bridging-Header.h │ │ └── Tests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Tests.xcscheme │ └── readme.md ├── Stack/ │ ├── README.markdown │ ├── Stack.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── Stack.swift │ └── Tests/ │ ├── Info.plist │ ├── StackTests.swift │ └── Tests.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ └── Tests.xcscheme ├── Strassen Matrix Multiplication/ │ ├── README.markdown │ └── StrassensMatrixMultiplication.playground/ │ ├── Contents.swift │ ├── Sources/ │ │ ├── Matrix.swift │ │ └── Number.swift │ ├── contents.xcplayground │ └── playground.xcworkspace/ │ └── contents.xcworkspacedata ├── Ternary Search Tree/ │ ├── README.markdown │ ├── TST.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ ├── TSTNode.swift │ │ │ ├── TernarySearchTree.swift │ │ │ └── Utils.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── TSTNode.swift │ ├── TernarySearchTree.swift │ ├── Tests/ │ │ ├── Info.plist │ │ ├── TernarySearchTreeTests.swift │ │ └── Tests.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Tests.xcscheme │ └── Utils.swift ├── Threaded Binary Tree/ │ ├── README.markdown │ └── ThreadedBinaryTree.playground/ │ ├── Contents.swift │ ├── Sources/ │ │ └── ThreadedBinaryTree.swift │ ├── contents.xcplayground │ └── playground.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── Topological Sort/ │ ├── Graph.swift │ ├── Images/ │ │ ├── Algorithms.graffle │ │ ├── Example.graffle │ │ ├── Graph.graffle │ │ ├── GraphResult.graffle │ │ ├── InvalidSort.graffle │ │ └── TopologicalSort.graffle │ ├── README.markdown │ ├── Tests/ │ │ ├── Info.plist │ │ ├── Tests.xcodeproj/ │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace/ │ │ │ │ └── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── xcschemes/ │ │ │ └── Tests.xcscheme │ │ └── TopologicalSortTests.swift │ ├── Topological Sort.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ ├── Graph.swift │ │ │ ├── TopologicalSort1.swift │ │ │ ├── TopologicalSort2.swift │ │ │ └── TopologicalSort3.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── TopologicalSort1.swift │ ├── TopologicalSort2.swift │ └── TopologicalSort3.swift ├── Treap/ │ ├── Treap/ │ │ ├── Treap/ │ │ │ └── Info.plist │ │ ├── Treap.xcodeproj/ │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace/ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata/ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ └── xcshareddata/ │ │ │ └── xcschemes/ │ │ │ └── Tests.xcscheme │ │ └── TreapTests/ │ │ ├── Info.plist │ │ └── TreapTests.swift │ ├── Treap.swift │ ├── TreapCollectionType.swift │ └── TreapMergeSplit.swift ├── Tree/ │ ├── Images/ │ │ ├── Cycles.graffle │ │ ├── Example.graffle │ │ ├── ParentChildren.graffle │ │ └── Tree.graffle │ ├── README.markdown │ ├── Tree.playground/ │ │ ├── Contents.swift │ │ ├── Sources/ │ │ │ └── Tree.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── Tree.swift ├── Trie/ │ ├── ReadMe.md │ └── Trie/ │ ├── Trie/ │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets/ │ │ │ └── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── ReadMe.md │ │ ├── Trie.swift │ │ ├── ViewController.swift │ │ └── dictionary.txt │ ├── Trie.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata/ │ │ └── xcbaselines/ │ │ └── EB798E0A1DFEF79900F0628D.xcbaseline/ │ │ ├── 6ABF2F62-9363-4450-8DE1-D20F57026950.plist │ │ └── Info.plist │ ├── TrieTests/ │ │ ├── Info.plist │ │ └── TrieTests.swift │ └── TrieUITests/ │ ├── Info.plist │ └── TrieUITests.swift ├── Two-Sum Problem/ │ ├── README.markdown │ ├── Solution 1/ │ │ └── 2Sum.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── Solution 2/ │ └── 2Sum.playground/ │ ├── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── Under Construction.markdown ├── Union-Find/ │ ├── README.markdown │ └── UnionFind.playground/ │ ├── Contents.swift │ ├── Sources/ │ │ ├── UnionFindQuickFind.swift │ │ ├── UnionFindQuickUnion.swift │ │ ├── UnionFindWeightedQuickFind.swift │ │ ├── UnionFindWeightedQuickUnion.swift │ │ └── UnionFindWeightedQuickUnionPathCompression.swift │ ├── contents.xcplayground │ └── playground.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── What are Algorithms.markdown ├── Why Algorithms.markdown ├── Z-Algorithm/ │ ├── README.markdown │ ├── ZAlgorithm.swift │ ├── ZetaAlgorithm.playground/ │ │ ├── Contents.swift │ │ ├── contents.xcplayground │ │ └── playground.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── ZetaAlgorithm.swift ├── gfm-render.sh └── install_swiftlint.sh
Condensed preview — 1063 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,751K chars).
[
{
"path": ".github/CONTRIBUTING.md",
"chars": 3221,
"preview": "# Contributing Guidelines\n\nWant to help out with the Swift Algorithm Club? Great! While we don't have strict templates o"
},
{
"path": ".github/ISSUE_TEMPLATE.md",
"chars": 188,
"preview": "### Brief Intro\n\n<!-- Describe the issue briefly.-->\n\n### More Details\n\n<!-- If necessary, start off with the code snipp"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 439,
"preview": "<!-- Thanks for contributing to the SAC! Before you submit your pull request, please make sure to check the following bo"
},
{
"path": ".gitignore",
"chars": 346,
"preview": "# Xcode\nbuild/\nDerivedData/\n\n*.pbxuser\n*.mode1v3\n*.mode2v3\n*.perspectivev3\n*.xccheckout\n*.moved-aside\n*.xcuserstate\n\nxcu"
},
{
"path": ".swiftlint.yml",
"chars": 499,
"preview": "cyclomatic_complexity: 12\nfile_length: 550\nfunction_body_length: 80\nfunction_parameter_count: 8\nline_length: 150\ntype_bo"
},
{
"path": "3Sum and 4Sum/3Sum.playground/Contents.swift",
"chars": 2098,
"preview": "// last checked with Xcode 10.1\n#if swift(>=4.2)\nprint(\"Hello, Swift 4.2!\")\n#endif\n\nextension Collection where Element: "
},
{
"path": "3Sum and 4Sum/3Sum.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='ios'>\n <timeline f"
},
{
"path": "3Sum and 4Sum/3Sum.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "3Sum and 4Sum/3Sum.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "3Sum and 4Sum/4Sum.playground/Contents.swift",
"chars": 2178,
"preview": "// last checked with Xcode 10.1\n#if swift(>=4.2)\nprint(\"Hello, Swift 4.2!\")\n#endif\n\nextension Collection where Element: "
},
{
"path": "3Sum and 4Sum/4Sum.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='ios'>\n <timeline f"
},
{
"path": "3Sum and 4Sum/4Sum.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "3Sum and 4Sum/4Sum.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "3Sum and 4Sum/README.md",
"chars": 5227,
"preview": "# 3Sum and 4Sum\n\n3Sum and 4Sum are extensions of a popular algorithm question, the [2Sum][5]. \n\n## 3Sum\n\n> Given an arra"
},
{
"path": "A-Star/AStar.swift",
"chars": 4579,
"preview": "// Written by Alejandro Isaza.\n\nimport Foundation\n\npublic protocol Graph {\n associatedtype Vertex: Hashable\n assoc"
},
{
"path": "A-Star/Images/graph.dot",
"chars": 363,
"preview": "digraph G {\n rankdir=LR;\n { A [ label = \"h = 3\" ] }\n { rank = same; B [ label = \"h = 2\" ]; C [ label = \"h = 2\" "
},
{
"path": "A-Star/Images/step1.dot",
"chars": 535,
"preview": "digraph G {\n rankdir=LR;\n { A [ label = \"g = 0\\nh = 3\", style = filled, color = deepskyblue1 ] }\n { rank = same"
},
{
"path": "A-Star/Images/step2.dot",
"chars": 569,
"preview": "digraph G {\n rankdir=LR;\n { A [ label = \"g = 0\\nh = 3\", style = filled, color = lightblue ] }\n { rank = same; B"
},
{
"path": "A-Star/Images/step3.dot",
"chars": 569,
"preview": "digraph G {\n rankdir=LR;\n { A [ label = \"g = 0\\nh = 3\", style = filled, color = lightblue ] }\n { rank = same; B"
},
{
"path": "A-Star/Images/step4.dot",
"chars": 603,
"preview": "digraph G {\n rankdir=LR;\n { A [ label = \"g = 0\\nh = 3\", style = filled, color = lightblue ] }\n { rank = same; B"
},
{
"path": "A-Star/Images/step5.dot",
"chars": 637,
"preview": "digraph G {\n rankdir=LR;\n { A [ label = \"g = 0\\nh = 3\", style = filled, color = lightblue ] }\n { rank = same; B"
},
{
"path": "A-Star/Images/step6.dot",
"chars": 671,
"preview": "digraph G {\n rankdir=LR;\n { A [ label = \"g = 0\\nh = 3\", style = filled, color = lightblue ] }\n { rank = same; B"
},
{
"path": "A-Star/Images/step7.dot",
"chars": 671,
"preview": "digraph G {\n rankdir=LR;\n { A [ label = \"g = 0\\nh = 3\", style = filled, color = lightblue ] }\n { rank = same; B"
},
{
"path": "A-Star/README.md",
"chars": 2815,
"preview": "# A*\n\nA* (pronounced \"ay star\") is a heuristic best-first search algorithm. A* minimizes node expansions, therefore mini"
},
{
"path": "A-Star/Tests/AStarTests.swift",
"chars": 1795,
"preview": "import Foundation\nimport XCTest\n\nstruct GridGraph: Graph {\n struct Vertex: Hashable {\n var x: Int\n var "
},
{
"path": "A-Star/Tests/AStarTests.xcodeproj/project.pbxproj",
"chars": 10360,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "A-Star/Tests/AStarTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Tests.xcodeproj"
},
{
"path": "A-Star/Tests/AStarTests.xcodeproj/xcshareddata/xcschemes/AStarTests.xcscheme",
"chars": 2312,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0900\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "A-Star/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "AVL Tree/AVLTree.playground/Contents.swift",
"chars": 513,
"preview": "//: Playground - noun: a place where people can play\n\n\nlet tree = AVLTree<Int, String>()\n\ntree.insert(key: 5, payload: \""
},
{
"path": "AVL Tree/AVLTree.playground/Sources/AVLTree.swift",
"chars": 10698,
"preview": "// The MIT License (MIT)\n\n// Copyright (c) 2016 Mike Taghavi (mitghi[at]me.com)\n\n// Permission is hereby granted, free o"
},
{
"path": "AVL Tree/AVLTree.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx'>\n <timeline f"
},
{
"path": "AVL Tree/AVLTree.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "AVL Tree/AVLTree.swift",
"chars": 12567,
"preview": "// The MIT License (MIT)\n\n// Copyright (c) 2016 Mike Taghavi (mitghi[at]me.com)\n\n// Permission is hereby granted, free o"
},
{
"path": "AVL Tree/README.markdown",
"chars": 5253,
"preview": "# AVL Tree\r\n\r\nAn AVL tree is a self-balancing form of a [binary search tree](../Binary%20Search%20Tree/), in which the h"
},
{
"path": "AVL Tree/Tests/AVLTreeTests.swift",
"chars": 4534,
"preview": "//\n// AVLTreeTestsTests.swift\n// AVLTreeTestsTests\n//\n// Created by Barbara Rodeker on 2/19/16.\n// Copyright © 2016 "
},
{
"path": "AVL Tree/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "AVL Tree/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 9593,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "AVL Tree/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Tests.xcodeproj"
},
{
"path": "AVL Tree/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0800\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "AVL Tree/Tests/TreeNodeTests.swift",
"chars": 2311,
"preview": "//\n// TreeNodeTest.swift\n// AVLTreeTests\n//\n// Created by Barbara Rodeker on 2/19/16.\n// Copyright © 2016 Swift Algo"
},
{
"path": "Algorithm Design.markdown",
"chars": 1925,
"preview": "# Algorithm design techniques\n\nWhat to do when you're faced with a new problem and you need to find an algorithm for it."
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP/APSP.h",
"chars": 408,
"preview": "//\n// APSP.h\n// APSP\n//\n// Created by Andrew McKnight on 5/6/16.\n//\n\n#import <Cocoa/Cocoa.h>\n\n//! Project version num"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP/APSP.swift",
"chars": 939,
"preview": "//\n// Base.swift\n// APSP\n//\n// Created by Andrew McKnight on 5/6/16.\n//\n\nimport Foundation\nimport Graph\n\n/**\n `APSPAl"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP/FloydWarshall.swift",
"chars": 7773,
"preview": "//\n// FloydWarshall.swift\n// APSP\n//\n// Created by Andrew McKnight on 5/5/16.\n//\n\nimport Foundation\nimport Graph\n\npri"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP/Helpers.swift",
"chars": 1334,
"preview": "//\n// Helpers.swift\n// APSP\n//\n// Created by Andrew McKnight on 5/6/16.\n//\n\nimport Foundation\n\n/**\n Print a matrix, o"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP/Info.plist",
"chars": 806,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.playground/Contents.swift",
"chars": 889,
"preview": "//: Playground - noun: a place where people can play\n\nimport Graph\nimport APSP\n\nvar graph = AdjacencyListGraph<String>()"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.playground/contents.xcplayground",
"chars": 187,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx' last-migration='"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.playground/timeline.xctimeline",
"chars": 1060,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Timeline\n version = \"3.0\">\n <TimelineItems>\n <LoggerValueHistoryTimelin"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.xcodeproj/project.pbxproj",
"chars": 18505,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 264,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.xcodeproj/xcshareddata/xcschemes/APSP.xcscheme",
"chars": 3291,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1010\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.xcodeproj/xcshareddata/xcschemes/APSPTests.xcscheme",
"chars": 3262,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1010\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.xcworkspace/contents.xcworkspacedata",
"chars": 222,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:APSP.playgroun"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSP.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 264,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSPTests/APSPTests.swift",
"chars": 4929,
"preview": "//\n// APSPTests.swift\n// APSPTests\n//\n// Created by Andrew McKnight on 5/6/16.\n//\n\nimport APSP\nimport Graph\nimport XC"
},
{
"path": "All-Pairs Shortest Paths/APSP/APSPTests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "All-Pairs Shortest Paths/README.markdown",
"chars": 4405,
"preview": "# All-Pairs Shortest Paths\n\nThe All-Pairs shortest path problem simultaneously computes the shortest path from each node"
},
{
"path": "Array2D/Array2D.playground/Contents.swift",
"chars": 1839,
"preview": "/*\n Two-dimensional array with a fixed number of rows and columns.\n This is mostly handy for games that are played on a "
},
{
"path": "Array2D/Array2D.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='ios'>\n <timeline f"
},
{
"path": "Array2D/Array2D.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Array2D/Array2D.swift",
"chars": 1102,
"preview": "/*\n Two-dimensional array with a fixed number of rows and columns.\n This is mostly handy for games that are played on "
},
{
"path": "Array2D/README.markdown",
"chars": 3362,
"preview": "# Array2D\n\nIn C and Objective-C, you can write the following line,\n\n\tint cookies[9][7];\n\t\nto make a 9x7 grid of cookies."
},
{
"path": "Array2D/Tests/Array2DTests.swift",
"chars": 2255,
"preview": "//\n// Array2DTest.swift\n// algorithmclub\n//\n// Created by Barbara Rodeker on 2/16/16.\n// Copyright © 2016 Swift Algo"
},
{
"path": "Array2D/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Array2D/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 9075,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Array2D/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Tests.xcodeproj"
},
{
"path": "Array2D/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0800\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "B-Tree/BTree.playground/Contents.swift",
"chars": 403,
"preview": "//: Playground - noun: a place where people can play\n\nimport Foundation\n\n// last checked with Xcode 10.0\n\nlet bTree = BT"
},
{
"path": "B-Tree/BTree.playground/Sources/BTree.swift",
"chars": 16368,
"preview": "// The MIT License (MIT)\n\n// Copyright (c) 2016 Viktor Szilárd Simkó (aqviktor[at]gmail.com)\n\n// Permission is hereby gr"
},
{
"path": "B-Tree/BTree.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx'>\n <timeline f"
},
{
"path": "B-Tree/BTree.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "B-Tree/BTree.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "B-Tree/BTree.swift",
"chars": 16368,
"preview": "// The MIT License (MIT)\n\n// Copyright (c) 2016 Viktor Szilárd Simkó (aqviktor[at]gmail.com)\n\n// Permission is hereby gr"
},
{
"path": "B-Tree/README.md",
"chars": 6903,
"preview": "# B-Tree\n\nA B-Tree is a self-balancing search tree, in which nodes can have more than two children.\n\n### Properties\n\nA B"
},
{
"path": "B-Tree/Tests/Tests/BTreeNodeTests.swift",
"chars": 1435,
"preview": "//\n// BTreeNodeTests.swift\n// BTree\n//\n// Created by Viktor Szilárd Simkó on 13/06/16.\n// Copyright © 2016 Viktor Sz"
},
{
"path": "B-Tree/Tests/Tests/BTreeTests.swift",
"chars": 4524,
"preview": "//\n// BTreeTests.swift\n// BTreeTests\n//\n// Created by Viktor Szilárd Simkó on 09/06/16.\n// Copyright © 2016 Viktor S"
},
{
"path": "B-Tree/Tests/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "B-Tree/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 10398,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "B-Tree/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Tests.xcodeproj"
},
{
"path": "B-Tree/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "B-Tree/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3648,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1000\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Big-O Notation.markdown",
"chars": 6175,
"preview": "# A note on Big-O notation\n\nIt's useful to know how fast an algorithm is and how much space it needs. This allows you to"
},
{
"path": "Binary Search/BinarySearch.playground/Contents.swift",
"chars": 770,
"preview": "//: Playground - noun: a place where people can play\n\n// An unsorted array of numbers\nlet numbers = [11, 59, 3, 2, 53, 1"
},
{
"path": "Binary Search/BinarySearch.playground/contents.xcplayground",
"chars": 187,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx' last-migration='"
},
{
"path": "Binary Search/BinarySearch.swift",
"chars": 1491,
"preview": "/**\n Binary Search\n \n Recursively splits the array in half until the value is found.\n \n If there is more than one occurr"
},
{
"path": "Binary Search/README.markdown",
"chars": 10517,
"preview": "# Binary Search\n\nGoal: Quickly find an element in an array.\n\nLet's say you have an array of numbers and you want to dete"
},
{
"path": "Binary Search/Tests/BinarySearchTests.swift",
"chars": 1349,
"preview": "import Foundation\nimport XCTest\n\nclass BinarySearchTest: XCTestCase {\n var searchList = [Int]()\n\n override func setUp("
},
{
"path": "Binary Search/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Binary Search/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 9140,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Binary Search/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Tests.xcodeproj"
},
{
"path": "Binary Search/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0800\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Binary Search Tree/README.markdown",
"chars": 24691,
"preview": "# Binary Search Tree (BST)\n\n> This topic has been tutorialized [here](https://www.raywenderlich.com/139821/swift-algorit"
},
{
"path": "Binary Search Tree/Solution 1/BinarySearchTree.playground/Contents.swift",
"chars": 1348,
"preview": "//: Playground - noun: a place where people can play\n\nlet tree = BinarySearchTree<Int>(value: 7)\ntree.insert(value: 2)\nt"
},
{
"path": "Binary Search Tree/Solution 1/BinarySearchTree.playground/Sources/BinarySearchTree.swift",
"chars": 8162,
"preview": "/*\n A binary search tree.\n\n Each node stores a value and two children. The left child contains a smaller\n value; the "
},
{
"path": "Binary Search Tree/Solution 1/BinarySearchTree.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx'>\n <timeline f"
},
{
"path": "Binary Search Tree/Solution 1/BinarySearchTree.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Binary Search Tree/Solution 1/BinarySearchTree.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Binary Search Tree/Solution 1/Tests/BinarySearchTreeTests.swift",
"chars": 10958,
"preview": "import Foundation\nimport XCTest\n\nclass BinarySearchTreeTest: XCTestCase {\n func testRootNode() {\n let tree = BinaryS"
},
{
"path": "Binary Search Tree/Solution 1/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Binary Search Tree/Solution 1/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 10024,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Binary Search Tree/Solution 1/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Tests.xcodeproj"
},
{
"path": "Binary Search Tree/Solution 1/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Binary Search Tree/Solution 1/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 264,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Binary Search Tree/Solution 1/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1000\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Binary Search Tree/Solution 2/BinarySearchTree.playground/Contents.swift",
"chars": 391,
"preview": "//: Playground - noun: a place where people can play\n\n// Each time you insert something, you get back a completely new t"
},
{
"path": "Binary Search Tree/Solution 2/BinarySearchTree.playground/Sources/BinarySearchTree.swift",
"chars": 2940,
"preview": "/*\n Binary search tree using value types\n\n The tree is immutable. Any insertions or deletions will create a new tree.\n"
},
{
"path": "Binary Search Tree/Solution 2/BinarySearchTree.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx'>\n <timeline f"
},
{
"path": "Binary Search Tree/Solution 2/BinarySearchTree.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Binary Search Tree/Solution 2/BinarySearchTree.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Binary Search Tree/Solution 2/BinarySearchTree.swift",
"chars": 2912,
"preview": "/*\n Binary search tree using value types\n\n The tree is immutable. Any insertions or deletions will create a new tree.\n"
},
{
"path": "Binary Tree/BinaryTree.playground/Contents.swift",
"chars": 2187,
"preview": "//: Playground - noun: a place where people can play\n\npublic indirect enum BinaryTree<T> {\n case node(BinaryTree<T>, T,"
},
{
"path": "Binary Tree/BinaryTree.playground/contents.xcplayground",
"chars": 187,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx' last-migration='"
},
{
"path": "Binary Tree/BinaryTree.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Binary Tree/BinaryTree.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Binary Tree/BinaryTree.swift",
"chars": 1557,
"preview": "/*\n A general-purpose binary tree.\n\n Nodes don't have a reference to their parent.\n*/\npublic indirect enum BinaryTree<"
},
{
"path": "Binary Tree/README.markdown",
"chars": 5718,
"preview": "# Binary Tree\n\nA binary tree is a [tree](../Tree/) where each node has 0, 1, or 2 children. This is a binary tree:\n\n![A "
},
{
"path": "Bit Set/BitSet.playground/Contents.swift",
"chars": 2590,
"preview": "//: Playground - noun: a place where people can play\n\n// Create a bit set that stores 140 bits\nvar bits = BitSet(size: 1"
},
{
"path": "Bit Set/BitSet.playground/Sources/BitSet.swift",
"chars": 7262,
"preview": "/*\n A fixed-size sequence of n bits. Bits have indices 0 to n-1.\n*/\npublic struct BitSet {\n /* How many bits this obje"
},
{
"path": "Bit Set/BitSet.playground/contents.xcplayground",
"chars": 187,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx' last-migration='"
},
{
"path": "Bit Set/BitSet.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Bit Set/BitSet.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bit Set/README.markdown",
"chars": 13660,
"preview": "# Bit Set\n\nA fixed-size sequence of *n* bits. Also known as bit array or bit vector.\n\nTo store whether something is true"
},
{
"path": "Bloom Filter/BloomFilter.playground/Contents.swift",
"chars": 2193,
"preview": "//: Playground - noun: a place where people can play\n\npublic class BloomFilter<T> {\n fileprivate var array: [Bool]\n pr"
},
{
"path": "Bloom Filter/BloomFilter.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx'>\n <timeline f"
},
{
"path": "Bloom Filter/BloomFilter.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Bloom Filter/BloomFilter.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bloom Filter/BloomFilter.swift",
"chars": 1330,
"preview": "public class BloomFilter<T> {\n private var array: [Bool]\n private var hashFunctions: [(T) -> Int]\n\n public init(size:"
},
{
"path": "Bloom Filter/README.markdown",
"chars": 8362,
"preview": "# Bloom Filter\n\n## Introduction\n\nA Bloom Filter is a space-efficient data structure that tells you whether or not an ele"
},
{
"path": "Bloom Filter/Tests/BloomFilterTests.swift",
"chars": 1785,
"preview": "import XCTest\n\n/* Two hash functions, adapted from\n http://www.cse.yorku.ca/~oz/hash.html */\n\nfunc djb2(_ x: String) -> "
},
{
"path": "Bloom Filter/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bloom Filter/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 9893,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Bloom Filter/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Tests.xcodeproj"
},
{
"path": "Bloom Filter/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bloom Filter/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1000\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Bounded Priority Queue/BoundedPriorityQueue.playground/Contents.swift",
"chars": 1892,
"preview": "struct Message: Comparable, CustomStringConvertible {\n let name: String\n let priority: Int\n\n var description: String "
},
{
"path": "Bounded Priority Queue/BoundedPriorityQueue.playground/Sources/BoundedPriorityQueue.swift",
"chars": 3368,
"preview": "public class LinkedListNode<T: Comparable> {\n var value: T\n var next: LinkedListNode?\n var previous: LinkedListNode?\n"
},
{
"path": "Bounded Priority Queue/BoundedPriorityQueue.playground/contents.xcplayground",
"chars": 187,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx' last-migration='"
},
{
"path": "Bounded Priority Queue/BoundedPriorityQueue.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Bounded Priority Queue/BoundedPriorityQueue.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bounded Priority Queue/BoundedPriorityQueue.swift",
"chars": 3376,
"preview": "open class LinkedListNode<T: Comparable> {\n var value: T\n var next: LinkedListNode?\n var previous: LinkedListNode?\n\n "
},
{
"path": "Bounded Priority Queue/README.markdown",
"chars": 5556,
"preview": "# Bounded Priority queue\n\nA bounded priority queue is similar to a regular [priority queue](../Priority%20Queue/), excep"
},
{
"path": "Bounded Priority Queue/Tests/BoundedPriorityQueueTests.swift",
"chars": 3369,
"preview": "//\n// BoundedPriorityQueueTests.swift\n//\n// Created by John Gill on 2/28/16.\n//\n\nimport Foundation\nimport XCTest\n\npriv"
},
{
"path": "Bounded Priority Queue/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bounded Priority Queue/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 10422,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Bounded Priority Queue/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Bounded Priority Queue/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bounded Priority Queue/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 264,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bounded Priority Queue/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0820\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Boyer-Moore-Horspool/BoyerMooreHorspool.playground/Contents.swift",
"chars": 3597,
"preview": "//: Playground - noun: a place where people can play\n\n/*\n Boyer-Moore string search\n\n This code is based on the articl"
},
{
"path": "Boyer-Moore-Horspool/BoyerMooreHorspool.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx'>\n <timeline f"
},
{
"path": "Boyer-Moore-Horspool/BoyerMooreHorspool.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Boyer-Moore-Horspool/BoyerMooreHorspool.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Boyer-Moore-Horspool/BoyerMooreHorspool.playground/timeline.xctimeline",
"chars": 1581,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Timeline\n version = \"3.0\">\n <TimelineItems>\n <LoggerValueHistoryTimelin"
},
{
"path": "Boyer-Moore-Horspool/BoyerMooreHorspool.swift",
"chars": 3315,
"preview": "/*\n Boyer-Moore string search\n\n This code is based on the article \"Faster String Searches\" by Costas Menico\n from Dr "
},
{
"path": "Boyer-Moore-Horspool/README.markdown",
"chars": 10512,
"preview": "# Boyer-Moore String Search\n\n> This topic has been tutorialized [here](https://www.raywenderlich.com/163964/swift-algori"
},
{
"path": "Boyer-Moore-Horspool/Tests/BoyerMooreHorspoolTests.swift",
"chars": 305,
"preview": "//\n// BoyerMooreHorspoolTests.swift\n// Tests\n//\n// Created by Matias Mazzei on 12/24/16.\n// Copyright © 2016 Swift A"
},
{
"path": "Boyer-Moore-Horspool/Tests/BoyerMooreTests.swift",
"chars": 2842,
"preview": "//\n// BoyerMooreHorspoolTests.swift\n// Tests\n//\n// Created by Matias Mazzei on 12/24/16.\n// Copyright © 2016 Swift A"
},
{
"path": "Boyer-Moore-Horspool/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Boyer-Moore-Horspool/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 10863,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Boyer-Moore-Horspool/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 150,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:Tests.xcodeproj"
},
{
"path": "Boyer-Moore-Horspool/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Boyer-Moore-Horspool/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 264,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Boyer-Moore-Horspool/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1000\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Breadth-First Search/BreadthFirstSearch.playground/Pages/Simple example.xcplaygroundpage/Contents.swift",
"chars": 1187,
"preview": "\nfunc breadthFirstSearch(_ graph: Graph, source: Node) -> [String] {\n var queue = Queue<Node>()\n queue.enqueue(source)"
},
{
"path": "Breadth-First Search/BreadthFirstSearch.playground/Sources/Edge.swift",
"chars": 220,
"preview": "public class Edge: Equatable {\n public var neighbor: Node\n\n public init(_ neighbor: Node) {\n self.neighbor = neighb"
},
{
"path": "Breadth-First Search/BreadthFirstSearch.playground/Sources/Graph.swift",
"chars": 1297,
"preview": "public class Graph: CustomStringConvertible, Equatable {\n public private(set) var nodes: [Node]\n\n public init() {\n "
},
{
"path": "Breadth-First Search/BreadthFirstSearch.playground/Sources/Node.swift",
"chars": 764,
"preview": "public class Node: CustomStringConvertible, Equatable {\n public var neighbors: [Edge]\n\n public private(set) var label:"
},
{
"path": "Breadth-First Search/BreadthFirstSearch.playground/Sources/Queue.swift",
"chars": 470,
"preview": "public struct Queue<T> {\n private var array: [T]\n\n public init() {\n array = []\n }\n\n public var isEmpty: Bool {\n "
},
{
"path": "Breadth-First Search/BreadthFirstSearch.playground/contents.xcplayground",
"chars": 146,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='6.0' target-platform='ios' display-mode='ra"
},
{
"path": "Breadth-First Search/BreadthFirstSearch.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Breadth-First Search/BreadthFirstSearch.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Breadth-First Search/BreadthFirstSearch.swift",
"chars": 496,
"preview": "func breadthFirstSearch(_ graph: Graph, source: Node) -> [String] {\n var queue = Queue<Node>()\n queue.enqueue(source)\n"
},
{
"path": "Breadth-First Search/README.markdown",
"chars": 5058,
"preview": "# Breadth-First Search\n\n> This topic has been tutorialized [here](https://www.raywenderlich.com/155801/swift-algorithm-c"
},
{
"path": "Breadth-First Search/Tests/BreadthFirstSearchTests.swift",
"chars": 2736,
"preview": "import XCTest\n\nclass BreadthFirstSearchTests: XCTestCase {\n\n func testExploringTree() {\n let tree = Graph()\n\n let"
},
{
"path": "Breadth-First Search/Tests/Graph.swift",
"chars": 2325,
"preview": "// MARK: - Edge\n\npublic class Edge: Equatable {\n public var neighbor: Node\n\n public init(neighbor: Node) {\n self.ne"
},
{
"path": "Breadth-First Search/Tests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Breadth-First Search/Tests/Queue.swift",
"chars": 470,
"preview": "public struct Queue<T> {\n private var array: [T]\n\n public init() {\n array = []\n }\n\n public var isEmpty: Bool {\n "
},
{
"path": "Breadth-First Search/Tests/Tests.xcodeproj/project.pbxproj",
"chars": 10851,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Breadth-First Search/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Breadth-First Search/Tests/Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Breadth-First Search/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
"chars": 3234,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1000\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Brute-Force String Search/BruteForceStringSearch.playground/Contents.swift",
"chars": 714,
"preview": "//: Playground - noun: a place where people can play\n\n// last checked with Xcode 9.0b4\n#if swift(>=4.0)\nprint(\"Hello, Sw"
},
{
"path": "Brute-Force String Search/BruteForceStringSearch.playground/contents.xcplayground",
"chars": 165,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='osx'>\n <timeline f"
},
{
"path": "Brute-Force String Search/BruteForceStringSearch.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Brute-Force String Search/BruteForceStringSearch.swift",
"chars": 532,
"preview": "/*\n Brute-force string search\n*/\nextension String {\n func indexOf(_ pattern: String) -> String.Index? {\n for i in s"
},
{
"path": "Brute-Force String Search/README.markdown",
"chars": 2072,
"preview": "# Brute-Force String Search\n\nHow would you go about writing a string search algorithm in pure Swift if you were not allo"
},
{
"path": "Bubble Sort/MyPlayground.playground/Contents.swift",
"chars": 176,
"preview": "import Foundation\n\nvar array = [4,2,1,3]\n\nprint(\"before:\",array)\nprint(\"after:\", bubbleSort(array))\nprint(\"after:\", bubb"
},
{
"path": "Bubble Sort/MyPlayground.playground/Sources/BubbleSort.swift",
"chars": 1813,
"preview": "//\n// BubbleSort.swift\n//\n// Created by Julio Brazil on 1/10/18.\n//\n// Permission is hereby granted, free of charge, "
},
{
"path": "Bubble Sort/MyPlayground.playground/contents.xcplayground",
"chars": 196,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='ios' executeOnSourceC"
},
{
"path": "Bubble Sort/MyPlayground.playground/playground.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Bubble Sort/MyPlayground.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Bubble Sort/README.markdown",
"chars": 4909,
"preview": "# Bubble Sort\n\nBubble sort is a sorting algorithm that is implemented by starting in the beginning of the array and swap"
},
{
"path": "Bucket Sort/BucketSort.playground/Contents.swift",
"chars": 1732,
"preview": "//\n// BucketSort.playground\n//\n// Created by Barbara Rodeker on 4/4/16.\n//\n// Permission is hereby granted, free of c"
},
{
"path": "Bucket Sort/BucketSort.playground/Sources/BucketSort.swift",
"chars": 5067,
"preview": "//\n// BucketSort.swift\n//\n// Created by Barbara Rodeker on 4/4/16.\n//\n// Permission is hereby granted, free of charge"
},
{
"path": "Bucket Sort/BucketSort.playground/contents.xcplayground",
"chars": 196,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='ios' executeOnSourceC"
}
]
// ... and 863 more files (download for full content)
About this extraction
This page contains the full source code of the kodecocodes/swift-algorithm-club GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1063 files (4.1 MB), approximately 1.1M tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.