├── Algorithms ├── Sorting │ ├── Heapsort │ │ └── TODO.txt │ ├── BubbleSort │ │ └── TODO.txt │ ├── InsertionSort │ │ └── TODO.txt │ ├── MergeSort │ │ └── TODO.txt │ ├── Quicksort │ │ └── TODO.txt │ └── SelectionSort │ │ └── TODO.txt ├── StringSearching │ ├── Sources │ │ └── StringSearching │ │ │ ├── RobinKarp.swift │ │ │ ├── KnuthMorrisPratt.swift │ │ │ ├── NaiveStringSearch.swift │ │ │ ├── BoyerMooreHorspool.swift │ │ │ └── BoyerMoore.swift │ ├── Tests │ │ ├── StringSearchingTests │ │ │ ├── BoyerMooreTests.swift │ │ │ ├── RobinKarpTests.swift │ │ │ ├── KnuthMorrisPrattTests.swift │ │ │ ├── XCTestManifests.swift │ │ │ ├── NaiveStringSearchTests.swift │ │ │ └── BoyerMooreHorspoolTests.swift │ │ └── LinuxMain.swift │ └── Package.swift └── RunLengthEncoding │ ├── Tests │ ├── LinuxMain.swift │ └── RunLengthEncodingTests │ │ ├── XCTestManifests.swift │ │ └── RunLengthEncodingTests.swift │ ├── Package.swift │ └── Sources │ └── RunLengthEncoding │ └── RunLengthEncoding.swift ├── .gitignore ├── Resources ├── Stanfrod-CS106 │ ├── StanfordCPPLib.zip │ ├── Handouts │ │ ├── 03 - Honor Code.pdf │ │ ├── 36 - Final Exam.pdf │ │ ├── 04 - Intro to C++.pdf │ │ ├── 05M - Using XCode.pdf │ │ ├── 11 - Grading Scale.pdf │ │ ├── 14 - Class Client.pdf │ │ ├── 25 - Midterm Exam.pdf │ │ ├── 01 - Course Placement.pdf │ │ ├── 13 - Decomp Example.pdf │ │ ├── 21 - Linked List Code.pdf │ │ ├── 38 - C++ Sans CS106.pdf │ │ ├── 10 - Library Reference.pdf │ │ ├── 02 - General Information.pdf │ │ ├── 07M - Debugging with Xcode.pdf │ │ ├── 12 - Developing Good Style.pdf │ │ ├── 37 - Final Exam Solutions.pdf │ │ ├── 26 - Midterm Exam Solutions.pdf │ │ ├── 24 - Exam Strategy and Tactics.pdf │ │ └── 19 - Exhaustive Recursion and Backtracking.pdf │ ├── ProgrammingAssignments │ │ ├── Source.zip │ │ ├── 18 - Programming Project 3.pdf │ │ ├── 22 - Programming Project 4.pdf │ │ ├── 29 - Programming Project 5.pdf │ │ ├── 32 - Programming Project 6.pdf │ │ ├── 09 - Programming Assignment 1.pdf │ │ ├── 16 - Programming Assignment 2.pdf │ │ └── 34 - Programming Assignment 7.pdf │ └── SectionAssignments │ │ ├── Solutions.zip │ │ ├── 08 - Problem Set 1.pdf │ │ ├── 15 - Problem Set 2.pdf │ │ ├── 17 - Problem Set 3.pdf │ │ ├── 20 - Problem Set 4.pdf │ │ ├── 23 - Problem Set 5.pdf │ │ ├── 27 - Problem Set 6.pdf │ │ ├── 30 - Problem Set 7.pdf │ │ ├── 33 - Problem Set 8.pdf │ │ └── 35 - Problem Set 9.pdf └── Stanford-CS-Education-Library │ ├── BinaryTrees.pdf │ ├── TreeListRecursion.pdf │ └── LinkedListProblems.pdf ├── DataStructures ├── Heap │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── HeapTests │ │ │ ├── XCTestManifests.swift │ │ │ └── HeapTests.swift │ ├── Package.swift │ └── Sources │ │ └── Heap │ │ └── Heap.swift ├── Queue │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── QueueTests │ │ │ ├── XCTestManifests.swift │ │ │ └── QueueTests.swift │ ├── Package.swift │ └── Sources │ │ └── Queue │ │ └── Queue.swift ├── Stack │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── StackTests │ │ │ ├── XCTestManifests.swift │ │ │ └── StackTests.swift │ ├── Package.swift │ └── Sources │ │ └── Stack │ │ └── Stack.swift ├── Trie │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── TrieTests │ │ │ ├── XCTestManifests.swift │ │ │ └── TrieTests.swift │ ├── Package.swift │ └── Sources │ │ └── Trie │ │ ├── TrieNode.swift │ │ └── Trie.swift ├── ArrayDeque │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── ArrayDequeTests │ │ │ └── XCTestManifests.swift │ └── Package.swift ├── BinaryTree │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── BinaryTreeTests │ │ │ ├── BinaryTreeNextNodeSample.graffle │ │ │ ├── XCTestManifests.swift │ │ │ └── BinaryTreeTests.swift │ ├── Package.swift │ └── Sources │ │ └── BinaryTree │ │ └── BinaryTree.swift ├── CountedSet │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── CountedSetTests │ │ │ ├── XCTestManifests.swift │ │ │ └── CountedSetTests.swift │ ├── Package.swift │ └── Sources │ │ └── CountedSet │ │ └── CountedSet.swift ├── LinkedList │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── LinkedListTests │ │ │ ├── XCTestManifests.swift │ │ │ └── LinkedListTests.swift │ ├── Package.swift │ └── Sources │ │ └── LinkedList │ │ ├── LinkedListNode.swift │ │ └── LinkedList.swift ├── Polynomial │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── PolynomialTests │ │ │ ├── XCTestManifests.swift │ │ │ └── PolynomialTests.swift │ ├── Package.swift │ └── Sources │ │ └── Polynomial │ │ └── Polynomial.swift ├── ExpiringDictionary │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── ExpiringDictionaryTests │ │ │ ├── XCTestManifests.swift │ │ │ └── ExpiringDictionaryTests.swift │ ├── Package.swift │ └── Sources │ │ └── ExpiringDictionary │ │ └── ExpiringDictionary.swift └── PriorityQueue │ ├── Sources │ └── PriorityQueue │ │ └── PriorityQueue.swift │ └── Package.swift ├── Problems ├── Fibonacci │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── FibonacciTests │ │ │ ├── XCTestManifests.swift │ │ │ └── FibonacciTests.swift │ ├── Package.swift │ └── Sources │ │ └── Fibonacci │ │ └── Fibonacci.swift ├── BinarySearch │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── BinarySearchTests │ │ │ ├── XCTestManifests.swift │ │ │ └── BinarySearchTests.swift │ ├── Package.swift │ └── Sources │ │ └── BinarySearch │ │ └── Collection+BinarySearch.swift ├── StringReverse │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── StringReverseTests │ │ │ ├── XCTestManifests.swift │ │ │ └── StringReverseTests.swift │ ├── Package.swift │ └── Sources │ │ └── StringReverse │ │ └── String+StringReverse.swift ├── IntersectingSetsMerger │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── IntersectingSetsMergerTests │ │ │ ├── XCTestManifests.swift │ │ │ └── IntersectingSetsMergerTests.swift │ ├── Package.swift │ └── Sources │ │ └── IntersectingSetsMerger │ │ └── IntersectingSetsMerger.swift ├── RecursiveReverseStack │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── RecursiveReverseStackTests │ │ │ ├── XCTestManifests.swift │ │ │ └── RecursiveReverseStackTests.swift │ ├── Sources │ │ └── RecursiveReverseStack │ │ │ └── RecursiveReverseStack.swift │ └── Package.swift ├── StableMarriageProblem │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── StableMarriageProblemTests │ │ │ ├── XCTestManifests.swift │ │ │ └── StableMarriageProblemTests.swift │ ├── Package.swift │ └── Sources │ │ └── StableMarriageProblem │ │ └── StableMarriageProblem.swift ├── SetsOfNumbersThatAddUpTo │ ├── Tests │ │ ├── LinuxMain.swift │ │ └── SetsOfNumbersThatAddUpToTests │ │ │ ├── XCTestManifests.swift │ │ │ └── SetsOfNumbersThatAddUpToTests.swift │ ├── Package.swift │ └── Sources │ │ └── SetsOfNumbersThatAddUpTo │ │ └── SetsOfNumbersThatAddUpTo.swift ├── Fractals │ ├── Fractals.xcodeproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── FractalsTests │ │ ├── Info.plist │ │ └── FractalsTests.swift │ └── Fractals │ │ ├── FractalView.swift │ │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── TriangleFractalView.swift │ │ ├── MondrianFractalView.swift │ │ └── AppDelegate.swift ├── AckermannFunction │ ├── BUILD │ ├── AckermannFunction.swift │ ├── Tests │ │ ├── BUILD │ │ └── AckermannFunctionTests.swift │ └── App │ │ ├── BUILD │ │ └── main.swift ├── AnagramFinder │ ├── AnagramFinder.xcodeproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── SampleInput │ │ └── anagrams.txt │ ├── AnagramFinder │ │ ├── Utilities.swift │ │ ├── AnagramClusterer.swift │ │ ├── Images.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── AppDelegate.swift │ └── AnagramFinderTests │ │ ├── Info.plist │ │ └── AnagramFinderTests.swift ├── TowerOfHanoi │ ├── TowerOfHanoi.xcodeproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── TowerOfHanoi │ │ ├── Disk.swift │ │ ├── TowerOfHanoi.swift │ │ ├── Images.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── AppDelegate.swift │ │ └── DrawingView.swift │ └── TowerOfHanoiTests │ │ ├── TowerOfHanoiTests.swift │ │ └── Info.plist ├── LargestSumSequence │ ├── LargestSumSequence.xcodeproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── LargestSumSequence │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── ViewController.swift │ │ └── LargestSumSequenceCalculator.swift │ └── LargestSumSequenceTests │ │ ├── Info.plist │ │ └── LargestSumSequenceTests.swift ├── StringPermutations │ ├── StringPermutations.xcodeproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── StringPermutations │ │ ├── AppDelegate.swift │ │ ├── StringPermutations.swift │ │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── ViewController.swift ├── PalindromeDetector │ ├── BUILD │ ├── App │ │ ├── main.swift │ │ └── BUILD │ ├── Tests │ │ ├── BUILD │ │ └── PalindromeDetectorTests.swift │ └── String+PalindromeDetector.swift └── EightQueensPuzzle.txt ├── Misc ├── ReadLineAnyGenerator │ └── ReadLineAnyGenerator.swift └── HelloBashCursor │ └── HelloBashCursor.swift └── README.md /Algorithms/Sorting/Heapsort/TODO.txt: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /Algorithms/Sorting/BubbleSort/TODO.txt: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /Algorithms/Sorting/InsertionSort/TODO.txt: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /Algorithms/Sorting/MergeSort/TODO.txt: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /Algorithms/Sorting/Quicksort/TODO.txt: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /Algorithms/Sorting/SelectionSort/TODO.txt: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Sources/StringSearching/RobinKarp.swift: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Sources/StringSearching/KnuthMorrisPratt.swift: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .build 3 | Packages/ 4 | *.xcodeproj 5 | xcuserdata/ 6 | -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/StanfordCPPLib.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/StanfordCPPLib.zip -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/03 - Honor Code.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/03 - Honor Code.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/36 - Final Exam.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/36 - Final Exam.pdf -------------------------------------------------------------------------------- /Algorithms/StringSearching/Tests/StringSearchingTests/BoyerMooreTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import StringSearching 3 | 4 | final class BoyerMooreTests: XCTestCase { 5 | } 6 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Tests/StringSearchingTests/RobinKarpTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import StringSearching 3 | 4 | final class RobinKarpTests: XCTestCase { 5 | } 6 | -------------------------------------------------------------------------------- /DataStructures/Heap/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import Heap 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += HeapTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /DataStructures/Queue/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import Queue 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += QueueTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /DataStructures/Stack/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import Stack 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += StackTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /DataStructures/Trie/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import Trie 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += TrieTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Resources/Stanford-CS-Education-Library/BinaryTrees.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanford-CS-Education-Library/BinaryTrees.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/04 - Intro to C++.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/04 - Intro to C++.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/05M - Using XCode.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/05M - Using XCode.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/11 - Grading Scale.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/11 - Grading Scale.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/14 - Class Client.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/14 - Class Client.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/25 - Midterm Exam.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/25 - Midterm Exam.pdf -------------------------------------------------------------------------------- /Problems/Fibonacci/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import Fibonacci 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += FibonacciTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/01 - Course Placement.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/01 - Course Placement.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/13 - Decomp Example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/13 - Decomp Example.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/21 - Linked List Code.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/21 - Linked List Code.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/38 - C++ Sans CS106.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/38 - C++ Sans CS106.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/ProgrammingAssignments/Source.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/ProgrammingAssignments/Source.zip -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/Solutions.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/Solutions.zip -------------------------------------------------------------------------------- /Resources/Stanford-CS-Education-Library/TreeListRecursion.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanford-CS-Education-Library/TreeListRecursion.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/10 - Library Reference.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/10 - Library Reference.pdf -------------------------------------------------------------------------------- /Algorithms/StringSearching/Tests/StringSearchingTests/KnuthMorrisPrattTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import StringSearching 3 | 4 | final class KnuthMorrisPrattTests: XCTestCase { 5 | } 6 | -------------------------------------------------------------------------------- /DataStructures/ArrayDeque/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import ArrayDeque 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += ArrayDequeTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /DataStructures/BinaryTree/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import BinaryTree 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += BinaryTreeTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /DataStructures/CountedSet/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import CountedSet 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += CountedSetTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /DataStructures/LinkedList/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import LinkedList 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += LinkedListTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /DataStructures/Polynomial/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import Polynomial 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += PolynomialTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Problems/BinarySearch/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import BinarySearch 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += BinarySearchTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Resources/Stanford-CS-Education-Library/LinkedListProblems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanford-CS-Education-Library/LinkedListProblems.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/02 - General Information.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/02 - General Information.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/07M - Debugging with Xcode.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/07M - Debugging with Xcode.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/12 - Developing Good Style.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/12 - Developing Good Style.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/37 - Final Exam Solutions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/37 - Final Exam Solutions.pdf -------------------------------------------------------------------------------- /Problems/StringReverse/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import StringReverse 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += StringReverseTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/26 - Midterm Exam Solutions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/26 - Midterm Exam Solutions.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/08 - Problem Set 1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/08 - Problem Set 1.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/15 - Problem Set 2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/15 - Problem Set 2.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/17 - Problem Set 3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/17 - Problem Set 3.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/20 - Problem Set 4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/20 - Problem Set 4.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/23 - Problem Set 5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/23 - Problem Set 5.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/27 - Problem Set 6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/27 - Problem Set 6.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/30 - Problem Set 7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/30 - Problem Set 7.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/33 - Problem Set 8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/33 - Problem Set 8.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/SectionAssignments/35 - Problem Set 9.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/SectionAssignments/35 - Problem Set 9.pdf -------------------------------------------------------------------------------- /Algorithms/StringSearching/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import StringSearching 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += StringSearchingTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/24 - Exam Strategy and Tactics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/24 - Exam Strategy and Tactics.pdf -------------------------------------------------------------------------------- /Algorithms/RunLengthEncoding/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import RunLengthEncoding 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += RunLengthEncodingTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /DataStructures/ExpiringDictionary/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import ExpiringDictionary 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += ExpiringDictionaryTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Problems/IntersectingSetsMerger/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import IntersectingSetsMerger 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += IntersectingSetsMergerTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Problems/RecursiveReverseStack/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import RecursiveReverseStack 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += RecursiveReverseStackTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Problems/StableMarriageProblem/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import StableMarriageProblem 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += StableMarriageProblemTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/ProgrammingAssignments/18 - Programming Project 3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/ProgrammingAssignments/18 - Programming Project 3.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/ProgrammingAssignments/22 - Programming Project 4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/ProgrammingAssignments/22 - Programming Project 4.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/ProgrammingAssignments/29 - Programming Project 5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/ProgrammingAssignments/29 - Programming Project 5.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/ProgrammingAssignments/32 - Programming Project 6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/ProgrammingAssignments/32 - Programming Project 6.pdf -------------------------------------------------------------------------------- /DataStructures/BinaryTree/Tests/BinaryTreeTests/BinaryTreeNextNodeSample.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/DataStructures/BinaryTree/Tests/BinaryTreeTests/BinaryTreeNextNodeSample.graffle -------------------------------------------------------------------------------- /Problems/SetsOfNumbersThatAddUpTo/Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import SetsOfNumbersThatAddUpTo 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += SetsOfNumbersThatAddUpToTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/Handouts/19 - Exhaustive Recursion and Backtracking.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/Handouts/19 - Exhaustive Recursion and Backtracking.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/ProgrammingAssignments/09 - Programming Assignment 1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/ProgrammingAssignments/09 - Programming Assignment 1.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/ProgrammingAssignments/16 - Programming Assignment 2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/ProgrammingAssignments/16 - Programming Assignment 2.pdf -------------------------------------------------------------------------------- /Resources/Stanfrod-CS106/ProgrammingAssignments/34 - Programming Assignment 7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cananito/SwiftComputerScience/HEAD/Resources/Stanfrod-CS106/ProgrammingAssignments/34 - Programming Assignment 7.pdf -------------------------------------------------------------------------------- /DataStructures/Heap/Tests/HeapTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(HeapTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /DataStructures/Queue/Tests/QueueTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(QueueTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /DataStructures/Stack/Tests/StackTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(StackTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /DataStructures/Trie/Tests/TrieTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(TrieTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/Fibonacci/Tests/FibonacciTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(FibonacciTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/Fractals/Fractals.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DataStructures/ArrayDeque/Tests/ArrayDequeTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(ArrayDequeTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /DataStructures/BinaryTree/Tests/BinaryTreeTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(BinaryTreeTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /DataStructures/CountedSet/Tests/CountedSetTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(CountedSetTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /DataStructures/LinkedList/Tests/LinkedListTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(LinkedListTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /DataStructures/Polynomial/Tests/PolynomialTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(PolynomialTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/BinarySearch/Tests/BinarySearchTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(BinarySearchTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/StringReverse/Tests/StringReverseTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(StringReverseTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Tests/StringSearchingTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(StringSearchingTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/AckermannFunction/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:public"]) 2 | 3 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 4 | 5 | swift_library( 6 | name = "AckermannFunction", 7 | srcs = ["AckermannFunction.swift"], 8 | ) 9 | -------------------------------------------------------------------------------- /Problems/AnagramFinder/AnagramFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoi.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Algorithms/RunLengthEncoding/Tests/RunLengthEncodingTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(RunLengthEncodingTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/AckermannFunction/AckermannFunction.swift: -------------------------------------------------------------------------------- 1 | public func ackermann(_ m: Int, _ n: Int) -> Int { 2 | if (m == 0) { 3 | return n + 1 4 | } 5 | if (n == 0) { 6 | return ackermann(m - 1, 1) 7 | } 8 | return ackermann(m - 1, ackermann(m, n - 1)) 9 | } 10 | -------------------------------------------------------------------------------- /DataStructures/ExpiringDictionary/Tests/ExpiringDictionaryTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(ExpiringDictionaryTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/LargestSumSequence/LargestSumSequence.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Problems/StringPermutations/StringPermutations.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Problems/IntersectingSetsMerger/Tests/IntersectingSetsMergerTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(IntersectingSetsMergerTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/RecursiveReverseStack/Tests/RecursiveReverseStackTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(RecursiveReverseStackTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/StableMarriageProblem/Tests/StableMarriageProblemTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(StableMarriageProblemTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoi/Disk.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Disk.swift 3 | // SwiftTowerOfHanoi 4 | // 5 | // Created by Rogelio Gudino on 8/3/14. 6 | // Copyright (c) 2014 Cananito. All rights reserved. 7 | // 8 | 9 | public struct Disk { 10 | public let identifier: Int 11 | } 12 | -------------------------------------------------------------------------------- /Problems/SetsOfNumbersThatAddUpTo/Tests/SetsOfNumbersThatAddUpToTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(SetsOfNumbersThatAddUpToTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoiTests/TowerOfHanoiTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TowerOfHanoiTests.swift 3 | // TowerOfHanoiTests 4 | // 5 | // Created by Rogelio Gudino on 2/8/15. 6 | // Copyright (c) 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import XCTest 11 | 12 | class TowerOfHanoiTests: XCTestCase { 13 | } 14 | -------------------------------------------------------------------------------- /DataStructures/PriorityQueue/Sources/PriorityQueue/PriorityQueue.swift: -------------------------------------------------------------------------------- 1 | public protocol PriorityQueue { 2 | associatedtype Element: Comparable 3 | init(leftIsHigherPriority: @escaping (Element, Element) -> Bool) 4 | func isEmpty() -> Bool 5 | func count() -> Int 6 | func peek() -> Element? 7 | mutating func insert(element: Element) 8 | mutating func remove() -> Element? 9 | } 10 | -------------------------------------------------------------------------------- /Problems/PalindromeDetector/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:public"]) 2 | 3 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 4 | 5 | swift_library( 6 | name = "PalindromeDetector", 7 | srcs = ["String+PalindromeDetector.swift"], 8 | deps = [ 9 | "//DataStructures/LinkedList", 10 | "//DataStructures/Stack", 11 | ], 12 | ) 13 | -------------------------------------------------------------------------------- /Problems/AnagramFinder/SampleInput/anagrams.txt: -------------------------------------------------------------------------------- 1 | aba 2 | baa 3 | aca 4 | caa 5 | ada 6 | daa 7 | ok 8 | ko 9 | qw 10 | wq 11 | er 12 | re 13 | po 14 | op 15 | zx 16 | xz 17 | xc 18 | cx 19 | cv 20 | vc 21 | bv 22 | vb 23 | bn 24 | nb 25 | fg 26 | gf 27 | jd 28 | dj 29 | asd 30 | dsa 31 | sad 32 | das 33 | pil 34 | lip 35 | qaz 36 | zaq 37 | wsx 38 | xsw 39 | edc 40 | cde 41 | rfv 42 | vfr 43 | tgb 44 | bgt 45 | yhn 46 | nhy 47 | -------------------------------------------------------------------------------- /Problems/LargestSumSequence/LargestSumSequence/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // LargestSumSequence 4 | // 5 | // Created by Rogelio Gudino on 8/22/15. 6 | // Copyright © 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | func applicationDidFinishLaunching(aNotification: NSNotification) { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Problems/EightQueensPuzzle.txt: -------------------------------------------------------------------------------- 1 | bool Solve(Grid, &board, int col) { 2 | if (col >- board.numCols()) { 3 | return true; 4 | } 5 | 6 | for (int rowToTry = 0; rowToTry < board.numbRows(); rowsToTry++) { 7 | if (IsSafe(board.rowToTry.col)) { 8 | PlaceQueen(board, rowToTry, col); 9 | if (Solve(board, col + 1)) { 10 | return true; 11 | } 12 | RemoveQueen(board, rowToTry, col); 13 | } 14 | } 15 | 16 | return false; 17 | } 18 | -------------------------------------------------------------------------------- /Problems/PalindromeDetector/App/main.swift: -------------------------------------------------------------------------------- 1 | import Problems_PalindromeDetector_PalindromeDetector 2 | 3 | func printInputRequest() { 4 | print("> Enter a word to check if it's palindrome:") 5 | } 6 | 7 | printInputRequest() 8 | while let input = readLine() { 9 | if input.isEmpty { 10 | print("Empty so... sure?") 11 | } else if input.lowercased().withoutWhiteSpaces().isPalindrome() { 12 | print("Yep") 13 | } else { 14 | print("Nope") 15 | } 16 | printInputRequest() 17 | } 18 | -------------------------------------------------------------------------------- /DataStructures/PriorityQueue/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "PriorityQueue", 8 | products: [ 9 | .library( 10 | name: "PriorityQueue", 11 | targets: ["PriorityQueue"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "PriorityQueue", 17 | dependencies: [] 18 | ), 19 | ] 20 | ) 21 | -------------------------------------------------------------------------------- /Problems/AckermannFunction/Tests/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:private"]) 2 | 3 | load("@build_bazel_rules_apple//apple:macos.bzl", "macos_unit_test") 4 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 5 | 6 | macos_unit_test( 7 | name = "Tests", 8 | minimum_os_version = "10.13", 9 | deps = [":TestsLib"], 10 | ) 11 | 12 | swift_library( 13 | name = "TestsLib", 14 | srcs = ["AckermannFunctionTests.swift"], 15 | deps = ["//Problems/AckermannFunction"], 16 | ) 17 | -------------------------------------------------------------------------------- /Problems/AckermannFunction/App/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:private"]) 2 | 3 | load("@build_bazel_rules_apple//apple:macos.bzl", "macos_command_line_application") 4 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 5 | 6 | macos_command_line_application( 7 | name = "App", 8 | minimum_os_version = "10.13", 9 | deps = [":AppLib"], 10 | ) 11 | 12 | swift_library( 13 | name = "AppLib", 14 | srcs = ["main.swift"], 15 | deps = ["//Problems/AckermannFunction"], 16 | ) 17 | -------------------------------------------------------------------------------- /Problems/PalindromeDetector/App/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:private"]) 2 | 3 | load("@build_bazel_rules_apple//apple:macos.bzl", "macos_command_line_application") 4 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 5 | 6 | macos_command_line_application( 7 | name = "App", 8 | minimum_os_version = "10.13", 9 | deps = [":AppLib"], 10 | ) 11 | 12 | swift_library( 13 | name = "AppLib", 14 | srcs = ["main.swift"], 15 | deps = ["//Problems/PalindromeDetector"], 16 | ) 17 | -------------------------------------------------------------------------------- /Problems/PalindromeDetector/Tests/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:private"]) 2 | 3 | load("@build_bazel_rules_apple//apple:macos.bzl", "macos_unit_test") 4 | load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") 5 | 6 | macos_unit_test( 7 | name = "Tests", 8 | minimum_os_version = "10.13", 9 | deps = [":TestsLib"], 10 | ) 11 | 12 | swift_library( 13 | name = "TestsLib", 14 | srcs = ["PalindromeDetectorTests.swift"], 15 | deps = ["//Problems/PalindromeDetector"], 16 | ) 17 | -------------------------------------------------------------------------------- /Problems/StringPermutations/StringPermutations/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // StringPermutations 4 | // 5 | // Created by Rogelio Gudino on 10/5/15. 6 | // Copyright © 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | func applicationDidFinishLaunching(aNotification: NSNotification) { 14 | } 15 | 16 | func applicationWillTerminate(aNotification: NSNotification) { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /DataStructures/Trie/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Trie", 8 | products: [ 9 | .library( 10 | name: "Trie", 11 | targets: ["Trie"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "Trie", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "TrieTests", 21 | dependencies: ["Trie"] 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /Problems/Fibonacci/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Fibonacci", 8 | products: [ 9 | .library( 10 | name: "Fibonacci", 11 | targets: ["Fibonacci"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "Fibonacci" 17 | ), 18 | .testTarget( 19 | name: "FibonacciTests", 20 | dependencies: ["Fibonacci"] 21 | ), 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoi/TowerOfHanoi.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TowerOfHanoi.swift 3 | // SwiftTowerOfHanoi 4 | // 5 | // Created by Rogelio Gudino on 8/3/14. 6 | // Copyright (c) 2014 Cananito. All rights reserved. 7 | // 8 | 9 | public struct TowerOfHanoi { 10 | public var sourcePole: [Disk] = [] 11 | public var destinationPole: [Disk] = [] 12 | public var temporaryPole: [Disk] = [] 13 | 14 | public func totalDiskCount() -> Int { 15 | return self.sourcePole.count + self.destinationPole.count + self.temporaryPole.count 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /DataStructures/Queue/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Queue", 8 | products: [ 9 | .library( 10 | name: "Queue", 11 | targets: ["Queue"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "Queue", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "QueueTests", 21 | dependencies: ["Queue"] 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /Problems/BinarySearch/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "BinarySearch", 8 | products: [ 9 | .library( 10 | name: "BinarySearch", 11 | targets: ["BinarySearch"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "BinarySearch" 17 | ), 18 | .testTarget( 19 | name: "BinarySearchTests", 20 | dependencies: ["BinarySearch"] 21 | ), 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /Misc/ReadLineAnyGenerator/ReadLineAnyGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReadLineAnyGenerator.swift 3 | // ReadLineAnyGenerator 4 | // 5 | // Created by Rogelio Gudino on 7/16/16. 6 | // Copyright © 2016 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | // https://twitter.com/kametrixom/status/739960738794594309 10 | print("Type 3 lines:") 11 | 12 | let g = AnyIterator { 13 | readLine() 14 | } 15 | 16 | //let threeLines = Array(g.prefix(3)) 17 | //print("First 3 lines:\n\(threeLines)") 18 | 19 | let a = Array(g.prefix(3)) 20 | for (i, l) in a.enumerated() { 21 | print("\(i + 1) - \(l)") 22 | } 23 | -------------------------------------------------------------------------------- /DataStructures/ArrayDeque/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "ArrayDeque", 8 | products: [ 9 | .library( 10 | name: "ArrayDeque", 11 | targets: ["ArrayDeque"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "ArrayDeque", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "ArrayDequeTests", 21 | dependencies: ["ArrayDeque"] 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /DataStructures/CountedSet/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "CountedSet", 8 | products: [ 9 | .library( 10 | name: "CountedSet", 11 | targets: ["CountedSet"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "CountedSet", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "CountedSetTests", 21 | dependencies: ["CountedSet"] 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /DataStructures/LinkedList/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "LinkedList", 8 | products: [ 9 | .library( 10 | name: "LinkedList", 11 | targets: ["LinkedList"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "LinkedList", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "LinkedListTests", 21 | dependencies: ["LinkedList"] 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /DataStructures/Polynomial/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Polynomial", 8 | products: [ 9 | .library( 10 | name: "Polynomial", 11 | targets: ["Polynomial"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "Polynomial", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "PolynomialTests", 21 | dependencies: ["Polynomial"] 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "StringSearching", 8 | products: [ 9 | .library( 10 | name: "StringSearching", 11 | targets: ["StringSearching"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "StringSearching", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "StringSearchingTests", 21 | dependencies: ["StringSearching"] 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /Problems/StableMarriageProblem/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "StableMarriageProblem", 8 | products: [ 9 | .library( 10 | name: "StableMarriageProblem", 11 | targets: ["StableMarriageProblem"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "StableMarriageProblem" 17 | ), 18 | .testTarget( 19 | name: "StableMarriageProblemTests", 20 | dependencies: ["StableMarriageProblem"] 21 | ), 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /Algorithms/RunLengthEncoding/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "RunLengthEncoding", 8 | products: [ 9 | .library( 10 | name: "RunLengthEncoding", 11 | targets: ["RunLengthEncoding"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "RunLengthEncoding", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "RunLengthEncodingTests", 21 | dependencies: ["RunLengthEncoding"] 22 | ), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /DataStructures/Heap/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Heap", 8 | products: [ 9 | .library( 10 | name: "Heap", 11 | targets: ["Heap"] 12 | ), 13 | ], 14 | dependencies: [ 15 | .package(path: "../PriorityQueue") 16 | ], 17 | targets: [ 18 | .target( 19 | name: "Heap", 20 | dependencies: ["PriorityQueue"] 21 | ), 22 | .testTarget( 23 | name: "HeapTests", 24 | dependencies: ["Heap"] 25 | ), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /DataStructures/Stack/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Stack", 8 | products: [ 9 | .library( 10 | name: "Stack", 11 | targets: ["Stack"] 12 | ), 13 | ], 14 | dependencies: [ 15 | .package(path: "../ArrayDeque") 16 | ], 17 | targets: [ 18 | .target( 19 | name: "Stack", 20 | dependencies: ["ArrayDeque"] 21 | ), 22 | .testTarget( 23 | name: "StackTests", 24 | dependencies: ["Stack"] 25 | ), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /Problems/IntersectingSetsMerger/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "IntersectingSetsMerger", 8 | products: [ 9 | .library( 10 | name: "IntersectingSetsMerger", 11 | targets: ["IntersectingSetsMerger"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "IntersectingSetsMerger" 17 | ), 18 | .testTarget( 19 | name: "IntersectingSetsMergerTests", 20 | dependencies: ["IntersectingSetsMerger"] 21 | ), 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /DataStructures/Queue/Sources/Queue/Queue.swift: -------------------------------------------------------------------------------- 1 | public struct Queue { 2 | private var array = [T]() 3 | 4 | public init() { 5 | } 6 | 7 | public init(elements: [T]) { 8 | self.array = elements 9 | } 10 | 11 | public func count() -> Int { 12 | return self.array.count 13 | } 14 | 15 | public func peek() -> T { 16 | return self.array[0] 17 | } 18 | 19 | public mutating func add(_ element: T) { 20 | self.array.append(element) 21 | } 22 | 23 | public mutating func next() -> T? { 24 | if self.array.count < 1 { 25 | return nil 26 | } 27 | let element = array.remove(at: 0) 28 | return element 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Problems/SetsOfNumbersThatAddUpTo/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "SetsOfNumbersThatAddUpTo", 8 | products: [ 9 | .library( 10 | name: "SetsOfNumbersThatAddUpTo", 11 | targets: ["SetsOfNumbersThatAddUpTo"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "SetsOfNumbersThatAddUpTo" 17 | ), 18 | .testTarget( 19 | name: "SetsOfNumbersThatAddUpToTests", 20 | dependencies: ["SetsOfNumbersThatAddUpTo"] 21 | ), 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /DataStructures/BinaryTree/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "BinaryTree", 8 | products: [ 9 | .library( 10 | name: "BinaryTree", 11 | targets: ["BinaryTree"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "BinaryTree", 17 | dependencies: [] 18 | ), 19 | .testTarget( 20 | name: "BinaryTreeTests", 21 | dependencies: ["BinaryTree"], 22 | exclude: [ 23 | "BinaryTreeNextNodeSample.graffle", 24 | ] 25 | ), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /Problems/StringReverse/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "StringReverse", 8 | products: [ 9 | .library( 10 | name: "StringReverse", 11 | targets: ["StringReverse"] 12 | ), 13 | ], 14 | dependencies: [ 15 | .package(path: "../../DataStructures/Stack") 16 | ], 17 | targets: [ 18 | .target( 19 | name: "StringReverse", 20 | dependencies: ["Stack"] 21 | ), 22 | .testTarget( 23 | name: "StringReverseTests", 24 | dependencies: ["StringReverse"] 25 | ), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /Problems/RecursiveReverseStack/Sources/RecursiveReverseStack/RecursiveReverseStack.swift: -------------------------------------------------------------------------------- 1 | import Stack 2 | 3 | public extension Stack { 4 | static func reverseStack(_ stack: inout Stack) { 5 | if stack.count() < 2 { 6 | return 7 | } 8 | 9 | let value = stack.pop() 10 | if stack.count() != 1 { 11 | reverseStack(&stack) 12 | } 13 | pushToBottom(value, stack: &stack) 14 | } 15 | 16 | private static func pushToBottom(_ bottomValue: T, stack: inout Stack) { 17 | let value = stack.pop() 18 | if stack.count() != 0 { 19 | pushToBottom(bottomValue, stack: &stack) 20 | } else { 21 | stack.push(bottomValue) 22 | } 23 | stack.push(value) 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /DataStructures/ExpiringDictionary/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "ExpiringDictionary", 8 | products: [ 9 | .library( 10 | name: "ExpiringDictionary", 11 | targets: ["ExpiringDictionary"] 12 | ), 13 | ], 14 | dependencies: [ 15 | .package(path: "../Heap") 16 | ], 17 | targets: [ 18 | .target( 19 | name: "ExpiringDictionary", 20 | dependencies: ["Heap"] 21 | ), 22 | .testTarget( 23 | name: "ExpiringDictionaryTests", 24 | dependencies: ["ExpiringDictionary"] 25 | ), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /Problems/RecursiveReverseStack/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "RecursiveReverseStack", 8 | products: [ 9 | .library( 10 | name: "RecursiveReverseStack", 11 | targets: ["RecursiveReverseStack"] 12 | ), 13 | ], 14 | dependencies: [ 15 | .package(path: "../../DataStructures/Stack") 16 | ], 17 | targets: [ 18 | .target( 19 | name: "RecursiveReverseStack", 20 | dependencies: ["Stack"] 21 | ), 22 | .testTarget( 23 | name: "RecursiveReverseStackTests", 24 | dependencies: ["RecursiveReverseStack"] 25 | ), 26 | ] 27 | ) 28 | -------------------------------------------------------------------------------- /Problems/BinarySearch/Tests/BinarySearchTests/BinarySearchTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import BinarySearch 3 | 4 | class BinarySearchTests: XCTestCase { 5 | func testBinarySearch() { 6 | let array = [ 1, 3, 4, 7, 8, 10, 11, 30 ] 7 | XCTAssertEqual(array.binarySearch(1), 0) 8 | XCTAssertNil(array.binarySearch(2)) 9 | XCTAssertEqual(array.binarySearch(3), 1) 10 | XCTAssertEqual(array.binarySearch(4), 2) 11 | XCTAssertNil(array.binarySearch(5)) 12 | XCTAssertEqual(array.binarySearch(7), 3) 13 | XCTAssertEqual(array.binarySearch(8), 4) 14 | XCTAssertEqual(array.binarySearch(10), 5) 15 | XCTAssertEqual(array.binarySearch(11), 6) 16 | XCTAssertEqual(array.binarySearch(30), 7) 17 | } 18 | 19 | static var allTests = [ 20 | ("testBinarySearch", testBinarySearch), 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /DataStructures/LinkedList/Sources/LinkedList/LinkedListNode.swift: -------------------------------------------------------------------------------- 1 | public class LinkedListNode: CustomStringConvertible, CustomDebugStringConvertible { 2 | public let value: T 3 | public var nextNode: LinkedListNode? 4 | public var previousNode: LinkedListNode? 5 | 6 | init(value: T) { 7 | self.value = value 8 | } 9 | 10 | // MARK: CustomStringConvertible 11 | 12 | public var description: String { 13 | if let nextNode = self.nextNode { 14 | return "\(self.value) -> \(nextNode.description)" 15 | } 16 | return "\(self.value)" 17 | } 18 | 19 | // MARK: CustomDebugStringConvertible 20 | 21 | public var debugDescription: String { 22 | if let nextNode = self.nextNode { 23 | return "\(self.value) -> \(nextNode.debugDescription)" 24 | } 25 | return "\(self.value)" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Problems/AnagramFinder/AnagramFinder/Utilities.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utilities.swift 3 | // AnagramFinder 4 | // 5 | // Created by Rogelio Gudino on 8/23/15. 6 | // Copyright © 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // TODO: Move this out to it’s own Utilities static library or framework. 12 | public func outputStringFromLaunchPath(_ launchPath: String, arguments: Array) -> String { 13 | let task = Process() 14 | 15 | task.launchPath = launchPath 16 | task.arguments = arguments 17 | 18 | let pipe = Pipe() 19 | task.standardOutput = pipe 20 | let fileHandle = pipe.fileHandleForReading 21 | 22 | task.launch() 23 | let outputData = fileHandle.readDataToEndOfFile() 24 | return NSString(data: outputData, encoding: String.Encoding.utf8.rawValue)! as String 25 | } 26 | -------------------------------------------------------------------------------- /Problems/Fractals/FractalsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Problems/AnagramFinder/AnagramFinderTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoiTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Problems/LargestSumSequence/LargestSumSequenceTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /DataStructures/Queue/Tests/QueueTests/QueueTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Queue 3 | 4 | class QueueTests: XCTestCase { 5 | func testCount() { 6 | let queue = Queue(elements: [1, 2, 3]) 7 | XCTAssert(queue.count() == 3, "Count should be 3.") 8 | } 9 | 10 | func testPeek() { 11 | let queue = Queue(elements: [1, 2, 3]) 12 | XCTAssert(queue.peek() == 1, "Peeked element should be 1.") 13 | } 14 | 15 | func testMutation() { 16 | var queue = Queue() 17 | queue.add(1) 18 | XCTAssert(queue.peek() == 1, "Peeked element should be 1.") 19 | queue.add(2) 20 | XCTAssert(queue.next() == 1, "Next element should be 1.") 21 | XCTAssert(queue.next() == 2, "Next element should be 2.") 22 | } 23 | 24 | static var allTests = [ 25 | ("testCount", testCount), 26 | ("testPeek", testPeek), 27 | ("testMutation", testMutation), 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /Problems/IntersectingSetsMerger/Sources/IntersectingSetsMerger/IntersectingSetsMerger.swift: -------------------------------------------------------------------------------- 1 | public func mergedIntersectingSets(sets: [Set]) -> [Set] { 2 | var mergedSets = sets 3 | if sets.count <= 1 { 4 | return mergedSets 5 | } 6 | 7 | var outerIndex = mergedSets.startIndex 8 | while outerIndex < (mergedSets.endIndex - 1) { 9 | var innerIndex = outerIndex.advanced(by: 1) 10 | while innerIndex < mergedSets.endIndex { 11 | let outerSet = mergedSets[outerIndex] 12 | let innerSet = mergedSets[innerIndex] 13 | if outerSet.isDisjoint(with: innerSet) == false { 14 | mergedSets[outerIndex].formUnion(innerSet) 15 | mergedSets.remove(at: innerIndex) 16 | } else { 17 | innerIndex = innerIndex.advanced(by: 1) 18 | } 19 | } 20 | 21 | outerIndex = outerIndex.advanced(by: 1) 22 | } 23 | 24 | return mergedSets 25 | } 26 | -------------------------------------------------------------------------------- /Problems/AckermannFunction/App/main.swift: -------------------------------------------------------------------------------- 1 | import Darwin 2 | import Problems_AckermannFunction_AckermannFunction 3 | 4 | let arguments = CommandLine.arguments 5 | let argumentsCount = arguments.count 6 | if argumentsCount != 3 { 7 | print("Need 2 arguments, not \(argumentsCount - 1)!!") 8 | exit(EXIT_FAILURE) 9 | } 10 | 11 | // Argument 0 is executable location. 12 | let firstArgument = arguments[1] 13 | let secondArgument = arguments[2] 14 | 15 | guard let firstValue = Int(firstArgument) else { 16 | print("First argument needs to be a valid integer.") 17 | exit(EXIT_FAILURE) 18 | } 19 | guard let secondValue = Int(secondArgument) else { 20 | print("Second argument needs to be a valid integer.") 21 | exit(EXIT_FAILURE) 22 | } 23 | 24 | print(">>> Starting to calculate...") 25 | let result = ackermann(firstValue, secondValue) 26 | print(">>> Ackerman Function result for (\(firstValue), \(secondValue)) is \(result)") 27 | -------------------------------------------------------------------------------- /DataStructures/Stack/Sources/Stack/Stack.swift: -------------------------------------------------------------------------------- 1 | import ArrayDeque 2 | 3 | public struct Stack { 4 | private var storage: ArrayDeque 5 | private var reversed = false 6 | 7 | public init() { 8 | storage = ArrayDeque() 9 | } 10 | 11 | public init(elements: [T]) { 12 | storage = ArrayDeque(array: elements) 13 | } 14 | 15 | public func count() -> Int { 16 | return storage.count() 17 | } 18 | 19 | public func peek() -> T? { 20 | if reversed { 21 | return storage[0] 22 | } 23 | return storage.last() 24 | } 25 | 26 | public mutating func push(_ object: T) { 27 | if reversed { 28 | storage.prepend(object) 29 | } else { 30 | storage.append(object) 31 | } 32 | } 33 | 34 | public mutating func pop() -> T { 35 | if reversed { 36 | return storage.removeFirst()! 37 | } 38 | return storage.removeLast()! 39 | } 40 | 41 | public mutating func reverse() { 42 | reversed = !reversed 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Problems/StringReverse/Tests/StringReverseTests/StringReverseTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import StringReverse 3 | 4 | class StringReverseTests: XCTestCase { 5 | func testReversedViaStackIteration() { 6 | XCTAssertEqual("".reversedViaStackIteration(), "") 7 | XCTAssertEqual("Rogelio".reversedViaStackIteration(), "oilegoR") 8 | } 9 | 10 | func testReversedViaArrayIteration() { 11 | XCTAssertEqual("".reversedViaArrayIteration(), "") 12 | XCTAssertEqual("Rogelio".reversedViaArrayIteration(), "oilegoR") 13 | } 14 | 15 | func testReversedViaArrayTwoSideBuildup() { 16 | XCTAssertEqual("".reversedViaArrayTwoSideBuildup(), "") 17 | XCTAssertEqual("Rogelio".reversedViaArrayTwoSideBuildup(), "oilegoR") 18 | } 19 | 20 | static var allTests = [ 21 | ("testReversedViaStackIteration", testReversedViaStackIteration), 22 | ("testReversedViaArrayIteration", testReversedViaArrayIteration), 23 | ("testReversedViaArrayTwoSideBuildup", testReversedViaArrayTwoSideBuildup), 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /Problems/BinarySearch/Sources/BinarySearch/Collection+BinarySearch.swift: -------------------------------------------------------------------------------- 1 | public extension Collection where Element: Comparable { 2 | func binarySearch(_ value: Element) -> Self.Index? { 3 | if self.count == 0 { 4 | return nil 5 | } 6 | return self.binarySearch(value, startIndex: self.startIndex, endIndex: self.index(self.endIndex, offsetBy: -1)) 7 | } 8 | 9 | private func binarySearch(_ value: Element, startIndex: Self.Index, endIndex: Self.Index) -> Self.Index? { 10 | let middleIndex = self.index(startIndex, offsetBy: self.distance(from: startIndex, to: endIndex) / 2) 11 | let element = self[middleIndex] 12 | 13 | if element == value { 14 | return middleIndex 15 | } 16 | 17 | if startIndex == endIndex { 18 | return nil 19 | } 20 | 21 | if element > value { 22 | return self.binarySearch(value, startIndex: startIndex, endIndex: middleIndex) 23 | } else { 24 | return self.binarySearch(value, startIndex: self.index(middleIndex, offsetBy: 1), endIndex: endIndex) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Problems/IntersectingSetsMerger/Tests/IntersectingSetsMergerTests/IntersectingSetsMergerTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import IntersectingSetsMerger 3 | 4 | class IntersectingSetsMergerTests: XCTestCase { 5 | func testMergedIntersectingSets() { 6 | var input: [Set] = [] 7 | var expected: [Set] = [] 8 | XCTAssertEqual(mergedIntersectingSets(sets: input), expected) 9 | 10 | input = [ Set(arrayLiteral: "a", "b", "c"), Set(arrayLiteral: "d", "e", "f") ] 11 | expected = input 12 | XCTAssertEqual(mergedIntersectingSets(sets: input), expected) 13 | 14 | input = [ 15 | Set(arrayLiteral: "a", "b", "c"), 16 | Set(arrayLiteral: "c", "d", "e"), 17 | Set(arrayLiteral: "f"), 18 | Set(arrayLiteral: "a", "z"), 19 | ] 20 | expected = [ 21 | Set(arrayLiteral: "a", "b", "c", "d", "e", "z"), 22 | Set(arrayLiteral: "f"), 23 | ] 24 | XCTAssertEqual(mergedIntersectingSets(sets: input), expected) 25 | } 26 | 27 | static var allTests = [ 28 | ("testMergedIntersectingSets", testMergedIntersectingSets), 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /Problems/Fractals/FractalsTests/FractalsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FractalsTests.swift 3 | // FractalsTests 4 | // 5 | // Created by Rogelio Gudino on 2/8/15. 6 | // Copyright (c) 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import XCTest 11 | 12 | class FractalsTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Problems/Fractals/Fractals/FractalView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FractalView.swift 3 | // SwiftFractals 4 | // 5 | // Created by Rogelio Gudino on 8/2/14. 6 | // Copyright (c) 2014 Cananito. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class FractalView: NSView { 12 | private let colorsArray = [ 13 | NSColor.greenColor(), 14 | NSColor.redColor(), 15 | NSColor.whiteColor(), 16 | NSColor.yellowColor(), 17 | NSColor.blueColor(), 18 | NSColor.brownColor(), 19 | NSColor.magentaColor(), 20 | NSColor.cyanColor(), 21 | NSColor.orangeColor(), 22 | NSColor.purpleColor() 23 | ] 24 | 25 | override func drawRect(dirtyRect: NSRect) { 26 | self.drawFractal(dirtyRect) 27 | } 28 | 29 | internal func drawFractal(rect: NSRect) { 30 | Swift.print("Subclasses must override!") 31 | } 32 | 33 | internal func randomColor() -> NSColor { 34 | let index = Int(arc4random_uniform(UInt32(self.colorsArray.count))) 35 | let color = self.colorsArray[index] 36 | return color 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Problems/StringPermutations/StringPermutations/StringPermutations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StringPermutations.swift 3 | // StringPermutations 4 | // 5 | // Created by Rogelio Gudino on 10/5/15. 6 | // Copyright © 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | extension String { 10 | func permutations() -> [String] { 11 | if self.characters.count == 0 { 12 | return [] 13 | } 14 | 15 | if self.characters.count == 1 { 16 | return [self] 17 | } 18 | 19 | var permutations = [String]() 20 | for (index, character) in self.characters.enumerate() { 21 | var string = self 22 | let characterIndex = string.startIndex.advancedBy(index) 23 | string.removeAtIndex(characterIndex) 24 | let subPermutations = string.permutations() 25 | for subPermutation in subPermutations { 26 | let permutation = "\(character)\(subPermutation)" 27 | permutations.append(permutation) 28 | } 29 | } 30 | 31 | return permutations 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Problems/AnagramFinder/AnagramFinder/AnagramClusterer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnagramClusterer.swift 3 | // AnagramFinder 4 | // 5 | // Created by Rogelio Gudino on 2/14/15. 6 | // Copyright (c) 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | public func clusterArrayOfWords(_ words: [String]) -> [String: [String]] { 10 | var wordsClusterDictionary = [String: [String]]() 11 | 12 | for word in words { 13 | let alphabetizedWord = alphabetizeWord(word) 14 | if var existingArray = wordsClusterDictionary[alphabetizedWord] { 15 | existingArray.append(word) 16 | wordsClusterDictionary[alphabetizedWord] = existingArray 17 | } else { 18 | wordsClusterDictionary[alphabetizedWord] = [word] 19 | } 20 | } 21 | 22 | return wordsClusterDictionary 23 | } 24 | 25 | private func alphabetizeWord(_ word: String) -> String { 26 | if (word.isEmpty == true) { 27 | return word 28 | } 29 | 30 | let charactersArray = word.lowercased().characters.sorted() 31 | let alphabetizedWord = charactersArray.reduce("") { $0 + String($1) } 32 | return alphabetizedWord 33 | } 34 | -------------------------------------------------------------------------------- /Problems/SetsOfNumbersThatAddUpTo/Tests/SetsOfNumbersThatAddUpToTests/SetsOfNumbersThatAddUpToTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SetsOfNumbersThatAddUpTo 3 | 4 | class SetsOfNumbersThatAddUpToTests : XCTestCase { 5 | func testSetsOfNumbersThatAddUpTo() { 6 | var result: [[Int]]? = nil 7 | // Time: 0.145 sec (10% STDEV) 8 | self.measure { 9 | for _ in 0...10000 { 10 | result = setsOfNumbersThatAddUpTo(sum: 16, numbers: [2, 4, 6, 10]) 11 | } 12 | } 13 | XCTAssertEqual(result, [[6, 10], [2, 4, 10]]) 14 | } 15 | func testMemoizedSetsOfNumbersThatAddUpTo() { 16 | var result: [[Int]]? = nil 17 | // Time: 0.019 sec (10% STDEV) 18 | self.measure { 19 | var memoization = [String : [[Int]]]() 20 | for _ in 0...10000 { 21 | result = memoizedSetsOfNumbersThatAddUpTo(sum: 16, numbers: [2, 4, 6, 10], memoization: &memoization) 22 | } 23 | } 24 | XCTAssertEqual(result, [[6, 10], [2, 4, 10]]) 25 | } 26 | 27 | static var allTests = [ 28 | ("testSetsOfNumbersThatAddUpTo", testSetsOfNumbersThatAddUpTo), 29 | ("testMemoizedSetsOfNumbersThatAddUpTo", testMemoizedSetsOfNumbersThatAddUpTo), 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /DataStructures/Polynomial/Tests/PolynomialTests/PolynomialTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Polynomial 3 | 4 | class PolynomialTests: XCTestCase { 5 | func testStringRepresentation() { 6 | let polynomial = Polynomial(terms: [ 7 | Term(constant: 5, coefficient: 2), 8 | Term(constant: 3, coefficient: 1), 9 | Term(constant: 1, coefficient: 0) 10 | ]) 11 | let derivedPolynomial = polynomial.derived() 12 | XCTAssert(polynomial.description == "5x^2, 3x, 1", "Polynomial's string representation.") 13 | XCTAssert(derivedPolynomial.description == "10x, 3", "Derived polynomial's string representation.") 14 | 15 | let negativeExponentPolynomial = Polynomial(terms: [ 16 | Term(constant: 10, coefficient: -3) 17 | ]) 18 | let derivedNegativeExponentPolynomial = negativeExponentPolynomial.derived() 19 | XCTAssert(negativeExponentPolynomial.description == "10x^-3", "Polynomial's string representation.") 20 | XCTAssert(derivedNegativeExponentPolynomial.description == "-30x^-4", "Derived polynomial's string representation.") 21 | } 22 | 23 | static var allTests = [ 24 | ("testStringRepresentation", testStringRepresentation), 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /Problems/Fibonacci/Sources/Fibonacci/Fibonacci.swift: -------------------------------------------------------------------------------- 1 | public func iterativeFibonacci(position: Int) -> Int { 2 | if position == 0 { 3 | return 0 4 | } 5 | if position == 1 || position == 2 { 6 | return 1 7 | } 8 | var twoBefore = 1 9 | var oneBefore = 1 10 | var result = 0 11 | for _ in 3 ... position { 12 | result = oneBefore + twoBefore 13 | twoBefore = oneBefore 14 | oneBefore = result 15 | } 16 | return result 17 | } 18 | 19 | public func recursiveFibonacci(position: Int) -> Int { 20 | if position < 2 { 21 | return position 22 | } else { 23 | return recursiveFibonacci(position: position - 1) + recursiveFibonacci(position: position - 2) 24 | } 25 | } 26 | 27 | public func memoizedRecursiveFibonacci(position: Int, memoization: inout [Int : Int]) -> Int { 28 | if let result = memoization[position] { 29 | return result 30 | } 31 | 32 | let result: Int 33 | if position < 2 { 34 | result = position 35 | } else { 36 | result = memoizedRecursiveFibonacci(position: position - 1, memoization: &memoization) + memoizedRecursiveFibonacci(position: position - 2, memoization: &memoization) 37 | } 38 | memoization[position] = result 39 | return result 40 | } 41 | -------------------------------------------------------------------------------- /Problems/Fractals/Fractals/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoi/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Problems/AnagramFinder/AnagramFinder/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /DataStructures/CountedSet/Sources/CountedSet/CountedSet.swift: -------------------------------------------------------------------------------- 1 | public struct CountedSet { 2 | private var dictionary = Dictionary() 3 | 4 | public init() { 5 | } 6 | 7 | public mutating func incrementCountForElement(element: T) -> Int { 8 | let updatedCount: Int 9 | if let currentCount = dictionary[element] { 10 | updatedCount = currentCount + 1 11 | } else { 12 | updatedCount = 1 13 | } 14 | dictionary[element] = updatedCount 15 | return updatedCount 16 | } 17 | 18 | public mutating func decrementCountForElement(element: T) -> Int { 19 | guard let currentCount = dictionary[element] else { 20 | return 0 21 | } 22 | let updatedCount = currentCount - 1 23 | if updatedCount == 0 { 24 | dictionary.removeValue(forKey: element) 25 | } else { 26 | dictionary[element] = updatedCount 27 | } 28 | return updatedCount 29 | } 30 | 31 | public func countForElement(element: T) -> Int { 32 | guard let currentCount = dictionary[element] else { 33 | return 0 34 | } 35 | return currentCount 36 | } 37 | 38 | public func elements() -> LazyCollection.Keys> { 39 | return dictionary.keys.lazy 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /DataStructures/Trie/Sources/Trie/TrieNode.swift: -------------------------------------------------------------------------------- 1 | public class TrieNode { 2 | public typealias Key = Character 3 | 4 | public let key: Key? 5 | public var value: T? 6 | private var parent: TrieNode? 7 | private var children = [TrieNode]() 8 | 9 | internal init(key: Key?, value: T?) { 10 | self.key = key 11 | self.value = value 12 | } 13 | 14 | internal func childNodeWithKey(_ key: Key) -> TrieNode? { 15 | for node in children { 16 | if let nodeKey = node.key, nodeKey == key { 17 | return node 18 | } 19 | } 20 | return nil 21 | } 22 | 23 | internal func addChildNodeWithKey(_ key: Key) -> TrieNode { 24 | if let existingNode = childNodeWithKey(key) { 25 | return existingNode 26 | } else { 27 | let node = TrieNode(key: key, value: nil) 28 | node.parent = self 29 | children.append(node) 30 | return node 31 | } 32 | } 33 | 34 | internal func trim() { 35 | if value != nil || children.count > 0 { 36 | return 37 | } 38 | if let index = parent?.children.firstIndex(where: { return $0 === self }) { 39 | parent?.children.remove(at: index) 40 | } 41 | parent?.trim() 42 | parent = nil 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Problems/LargestSumSequence/LargestSumSequence/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Problems/StringPermutations/StringPermutations/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Problems/Fractals/Fractals/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Rogelio Gudino. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Problems/AnagramFinder/AnagramFinder/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Rogelio Gudino. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoi/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Rogelio Gudino. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Problems/LargestSumSequence/LargestSumSequence/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Rogelio Gudino. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Problems/StringPermutations/StringPermutations/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Rogelio Gudino. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftComputerScience 2 | 3 | Collection of Swift projects for Computer Science concepts and topics. 4 | 5 | ## Usage 6 | 7 | TODO: Change this section with instructions on how to build anything, run binaries, test xctests, and debug binaries and xctests. 8 | 9 | * Standalone scripts need to be run with `swift `. 10 | * Directories with a `Package.swift` file can be built, run, and/or tested by `cd`ing into the directory and executing `swift build`, `swift run`, and/or `swift test` accordingly. 11 | * Directories with a `BUILD` file or `.xcodeproj` directory are being migrated to SwiftPM and likely don't compile. 12 | * To debug a test: 13 | 14 | ``` 15 | $ lldb .build/debug/ 16 | 17 | (lldb) r 18 | ``` 19 | 20 | ``` 21 | # Get xctest command to use in the next step. 22 | $ swift test -v 23 | 24 | $ lldb /Applications//Contents/Developer/usr/bin/xctest 25 | 26 | # Launches xctest, not the test itself. 27 | (lldb) process launch 28 | 29 | 30 | 31 | # Launches the test. 32 | (lldb) process launch 33 | ``` 34 | 35 | ## Sources 36 | 37 | * [Stanford's CS106](https://www.youtube.com/playlist?list=PLFE6E58F856038C69) 38 | * [Stanford CS Education Library](http://cslibrary.stanford.edu/) 39 | * [Khan Academy's Computer Science subject](https://www.khanacademy.org/) 40 | -------------------------------------------------------------------------------- /Problems/AckermannFunction/Tests/AckermannFunctionTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Problems_AckermannFunction_AckermannFunction 3 | 4 | class AckermannFunctionTests: XCTestCase { 5 | func testAckermannFunction() { 6 | XCTAssertEqual(ackermann(0, 0), 1) 7 | XCTAssertEqual(ackermann(0, 1), 2) 8 | XCTAssertEqual(ackermann(0, 2), 3) 9 | XCTAssertEqual(ackermann(0, 3), 4) 10 | XCTAssertEqual(ackermann(0, 4), 5) 11 | XCTAssertEqual(ackermann(0, 5), 6) 12 | 13 | XCTAssertEqual(ackermann(1, 0), 2) 14 | XCTAssertEqual(ackermann(1, 1), 3) 15 | XCTAssertEqual(ackermann(1, 2), 4) 16 | XCTAssertEqual(ackermann(1, 3), 5) 17 | XCTAssertEqual(ackermann(1, 4), 6) 18 | XCTAssertEqual(ackermann(1, 5), 7) 19 | 20 | XCTAssertEqual(ackermann(2, 0), 3) 21 | XCTAssertEqual(ackermann(2, 1), 5) 22 | XCTAssertEqual(ackermann(2, 2), 7) 23 | XCTAssertEqual(ackermann(2, 3), 9) 24 | XCTAssertEqual(ackermann(2, 4), 11) 25 | XCTAssertEqual(ackermann(2, 5), 13) 26 | 27 | XCTAssertEqual(ackermann(3, 0), 5) 28 | XCTAssertEqual(ackermann(3, 1), 13) 29 | XCTAssertEqual(ackermann(3, 2), 29) 30 | XCTAssertEqual(ackermann(3, 3), 61) 31 | XCTAssertEqual(ackermann(3, 4), 125) 32 | XCTAssertEqual(ackermann(3, 5), 253) 33 | 34 | XCTAssertEqual(ackermann(4, 0), 13) 35 | // ackermann(4, 1) segfaults! 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Problems/StringReverse/Sources/StringReverse/String+StringReverse.swift: -------------------------------------------------------------------------------- 1 | import Stack 2 | 3 | public extension String { 4 | func reversedViaStackIteration() -> String { 5 | if self.count == 0 { 6 | return self 7 | } 8 | 9 | var stack = Stack() 10 | for character in self { 11 | stack.push(character) 12 | } 13 | var result = [Character]() 14 | while stack.peek() != nil { 15 | result.append(stack.pop()) 16 | } 17 | return String(result) 18 | } 19 | 20 | func reversedViaArrayIteration() -> String { 21 | if self.count == 0 { 22 | return self 23 | } 24 | 25 | var result = [Character]() 26 | var characters = self 27 | while characters.last != nil { 28 | result.append(characters.removeLast()) 29 | } 30 | return String(result) 31 | } 32 | 33 | func reversedViaArrayTwoSideBuildup() -> String { 34 | if self.count == 0 { 35 | return self 36 | } 37 | 38 | var result = Array(self) 39 | var leftIndex = 0 40 | var rightIndex = result.count - 1 41 | 42 | while leftIndex < rightIndex { 43 | let leftCharacter = result[leftIndex] 44 | let rightCharacter = result[rightIndex] 45 | result[leftIndex] = rightCharacter 46 | result[rightIndex] = leftCharacter 47 | leftIndex += 1 48 | rightIndex -= 1 49 | } 50 | return String(result) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Problems/StableMarriageProblem/Tests/StableMarriageProblemTests/StableMarriageProblemTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import StableMarriageProblem 3 | 4 | class StableMarriageProblemTests: XCTestCase { 5 | func testStableMarriageProblem() { 6 | let charlotte = "Charlotte" 7 | let elizabeth = "Elizabeth" 8 | let jane = "Jane" 9 | let lydia = "Lydia" 10 | let bingley = "Bingley" 11 | let collins = "Collins" 12 | let darcy = "Darcy" 13 | let wickham = "Wickham" 14 | 15 | let proposersPreferences = [ 16 | charlotte: [bingley, darcy, collins, wickham], 17 | elizabeth: [wickham, darcy, bingley, collins], 18 | jane: [bingley, wickham, darcy, collins], 19 | lydia: [bingley, wickham, darcy, collins], 20 | ] 21 | let recipientsPreferences = [ 22 | bingley: [jane, elizabeth, lydia, charlotte], 23 | collins: [jane, elizabeth, lydia, charlotte], 24 | darcy: [elizabeth, jane, charlotte, lydia], 25 | wickham: [lydia, jane, elizabeth, charlotte], 26 | ] 27 | let expected = [ 28 | charlotte: collins, 29 | elizabeth: darcy, 30 | jane: bingley, 31 | lydia: wickham, 32 | ] 33 | 34 | let result = StableMarriageProblem.solve(proposersPreferences, recipientsPreferences) 35 | XCTAssertEqual(result!, expected) 36 | } 37 | 38 | static var allTests = [ 39 | ("testStableMarriageProblem", testStableMarriageProblem), 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /Problems/RecursiveReverseStack/Tests/RecursiveReverseStackTests/RecursiveReverseStackTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Stack 3 | import RecursiveReverseStack 4 | 5 | class RecursiveReverseStackTests: XCTestCase { 6 | func testRecursiveReverseStack() { 7 | var stack = Stack() 8 | Stack.reverseStack(&stack) 9 | XCTAssertEqual(stack.count(), 0) 10 | 11 | stack.push(1) 12 | Stack.reverseStack(&stack) 13 | XCTAssertEqual(stack.peek()!, 1) 14 | 15 | stack.push(2) 16 | stack.push(3) 17 | Stack.reverseStack(&stack) 18 | XCTAssertEqual(stack.pop(), 1) 19 | XCTAssertEqual(stack.pop(), 2) 20 | XCTAssertEqual(stack.pop(), 3) 21 | XCTAssertEqual(stack.count(), 0) 22 | } 23 | 24 | func testRecursiveReverseStackPerformance() { 25 | var stack = Stack() 26 | for i in 1...1000 { 27 | stack.push(i) 28 | } 29 | 30 | self.measure { 31 | Stack.reverseStack(&stack) 32 | } 33 | } 34 | 35 | func testFlagFlipReverseStackPerformance() { 36 | var stack = Stack() 37 | for i in 1...1000 { 38 | stack.push(i) 39 | } 40 | 41 | self.measure { 42 | stack.reverse() 43 | } 44 | } 45 | 46 | static var allTests = [ 47 | ("testRecursiveReverseStack", testRecursiveReverseStack), 48 | ("testRecursiveReverseStackPerformance", testRecursiveReverseStackPerformance), 49 | ("testFlagFlipReverseStackPerformance", testFlagFlipReverseStackPerformance), 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /Algorithms/RunLengthEncoding/Sources/RunLengthEncoding/RunLengthEncoding.swift: -------------------------------------------------------------------------------- 1 | // TODO: Make a full-fledged RLE struct: 2 | // 1. Support generic values. 3 | // 2. Make it a SequenceType. 4 | // 3. Take care of data validation. 5 | public typealias RLE = [Int] 6 | 7 | enum RLEError: Error { 8 | case invalidRLE(message: String) 9 | } 10 | 11 | public struct RLEGenerator: IteratorProtocol { 12 | public typealias Element = Int 13 | 14 | private let rle: RLE 15 | private var currentIndex = Int(-2) 16 | private var currentCount = Int(0) 17 | 18 | public init(rle: RLE) throws { 19 | if rle.count % 2 != 0 { 20 | throw RLEError.invalidRLE(message: "Contents of RLE must be even, given count: \(rle.count).") 21 | } 22 | self.rle = rle 23 | advanceToNextNonZeroIfNecessary() 24 | } 25 | 26 | public func isAtEnd() -> Bool { 27 | if (currentCount == 0) && (currentIndex == (rle.count - 2)) { 28 | return true 29 | } 30 | return false 31 | } 32 | 33 | public mutating func next() -> Element? { 34 | if isAtEnd() { 35 | return nil 36 | } 37 | let element = rle[currentIndex + 1] 38 | currentCount -= 1 39 | advanceToNextNonZeroIfNecessary() 40 | return element 41 | } 42 | 43 | private mutating func advanceToNextNonZeroIfNecessary() { 44 | while currentCount == 0 { 45 | if isAtEnd() { 46 | return 47 | } 48 | currentIndex = currentIndex + 2 49 | currentCount = rle[currentIndex] 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /DataStructures/Trie/Sources/Trie/Trie.swift: -------------------------------------------------------------------------------- 1 | public struct Trie { 2 | public typealias Key = String 3 | 4 | private var rootNode = TrieNode(key: nil, value: nil) 5 | 6 | public init() { 7 | } 8 | 9 | public func valueForKey(_ key: Key) -> T? { 10 | if key.isEmpty { 11 | return nil 12 | } 13 | 14 | var currentNode = rootNode 15 | for (_, character) in key.enumerated() { 16 | if let node = currentNode.childNodeWithKey(character) { 17 | currentNode = node 18 | } else { 19 | return nil 20 | } 21 | } 22 | 23 | return currentNode.value 24 | } 25 | 26 | public mutating func setValue(_ value: T, key: Key) { 27 | if key.isEmpty { 28 | return 29 | } 30 | 31 | var currentNode = rootNode 32 | for (_, character) in key.enumerated() { 33 | if let node = currentNode.childNodeWithKey(character) { 34 | currentNode = node 35 | } else { 36 | currentNode = currentNode.addChildNodeWithKey(character) 37 | } 38 | } 39 | 40 | currentNode.value = value 41 | } 42 | 43 | public mutating func removeValueForKey(_ key: Key) -> T? { 44 | if key.isEmpty { 45 | return nil 46 | } 47 | 48 | var currentNode = rootNode 49 | for (_, character) in key.enumerated() { 50 | if let node = currentNode.childNodeWithKey(character) { 51 | currentNode = node 52 | } else { 53 | return nil 54 | } 55 | } 56 | 57 | let value = currentNode.value 58 | currentNode.value = nil 59 | currentNode.trim() 60 | return value 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Problems/LargestSumSequence/LargestSumSequenceTests/LargestSumSequenceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LargestSumSequenceTests.swift 3 | // LargestSumSequenceTests 4 | // 5 | // Created by Rogelio Gudino on 9/7/15. 6 | // Copyright © 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | // TODO: Move algorithm to Algorithms folder and get rid of `@testable`. 11 | @testable import LargestSumSequence 12 | 13 | class LargestSumSequenceTests: XCTestCase { 14 | func testLargestSum() { 15 | XCTAssert(largestSum([2, 10, -5, 8, 2]) == 17) 16 | XCTAssert(largestSum([2, 10, -50, 8, 2]) == 12) 17 | XCTAssert(largestSum([0, 10, 0, -8, 2]) == 10) 18 | XCTAssert(largestSum([-2, -1, -10, -8, -1]) == -1) 19 | XCTAssert(largestSum([2, -1, 1, -8, -1]) == 2) 20 | XCTAssert(largestSum([12, -10, -1, 8, -1]) == 12) 21 | XCTAssert(largestSum([-1, -10, -3, -8, -7]) == -1) 22 | XCTAssert(largestSum([4, -9, 8, -6, 5]) == 8) 23 | XCTAssert(largestSum([10, -5, -3]) == 10) 24 | } 25 | 26 | func testLargestSumSequence() { 27 | XCTAssert(largestSumSequence([2, 10, -5, 8, 2]) == [2, 10, -5, 8, 2]) 28 | XCTAssert(largestSumSequence([2, 10, -50, 8, 2]) == [2, 10]) 29 | XCTAssert(largestSumSequence([0, 10, 0, -8, 2]) == [0, 10]) 30 | XCTAssert(largestSumSequence([-2, -1, -10, -8, -1]) == [-1]) 31 | XCTAssert(largestSumSequence([2, -1, 1, -8, -1]) == [2]) 32 | XCTAssert(largestSumSequence([12, -10, -1, 8, -1]) == [12]) 33 | XCTAssert(largestSumSequence([-1, -10, -3, -8, -7]) == [-1]) 34 | XCTAssert(largestSumSequence([4, -9, 8, -6, 5]) == [8]) 35 | XCTAssert(largestSumSequence([10, -5, -3]) == [10]) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Problems/SetsOfNumbersThatAddUpTo/Sources/SetsOfNumbersThatAddUpTo/SetsOfNumbersThatAddUpTo.swift: -------------------------------------------------------------------------------- 1 | public func setsOfNumbersThatAddUpTo(sum: Int, numbers: [Int]) -> [[Int]] { 2 | if sum == 0 || numbers.count == 0 { 3 | return [[]] 4 | } 5 | 6 | let lastNumber = numbers.last! 7 | let subsetNumbers = Array(numbers.prefix(numbers.count - 1)) 8 | if sum < lastNumber { 9 | return setsOfNumbersThatAddUpTo(sum: sum, numbers: subsetNumbers) 10 | } else if sum == lastNumber { 11 | return [[lastNumber]] + setsOfNumbersThatAddUpTo(sum: sum, numbers: subsetNumbers) 12 | } else { 13 | let remainder = sum - lastNumber 14 | return setsOfNumbersThatAddUpTo(sum: remainder, numbers: subsetNumbers).filter { $0.count > 0 }.map { (x) -> [Int] in 15 | var mx = x 16 | mx.append(lastNumber) 17 | return mx 18 | } 19 | } 20 | } 21 | 22 | public func memoizedSetsOfNumbersThatAddUpTo(sum: Int, numbers: [Int], memoization: inout [String : [[Int]]]) -> [[Int]] { 23 | let key = "\(sum):\(numbers.count)" 24 | if let existingResult = memoization[key] { 25 | return existingResult 26 | } 27 | 28 | if sum == 0 || numbers.count == 0 { 29 | return [[]] 30 | } 31 | 32 | let lastNumber = numbers.last! 33 | let subsetNumbers = Array(numbers.prefix(numbers.count - 1)) 34 | let result: [[Int]] 35 | if sum < lastNumber { 36 | result = setsOfNumbersThatAddUpTo(sum: sum, numbers: subsetNumbers) 37 | } else if sum == lastNumber { 38 | result = [[lastNumber]] + setsOfNumbersThatAddUpTo(sum: sum, numbers: subsetNumbers) 39 | } else { 40 | let remainder = sum - lastNumber 41 | result = setsOfNumbersThatAddUpTo(sum: remainder, numbers: subsetNumbers).filter { $0.count > 0 }.map { (x) -> [Int] in 42 | var mx = x 43 | mx.append(lastNumber) 44 | return mx 45 | } 46 | } 47 | memoization[key] = result 48 | return result 49 | } 50 | -------------------------------------------------------------------------------- /Problems/StringPermutations/StringPermutations/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // StringPermutations 4 | // 5 | // Created by Rogelio Gudino on 10/5/15. 6 | // Copyright © 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { 12 | @IBOutlet weak var stringTextField: NSTextField! 13 | @IBOutlet weak var permutationsTableView: NSTableView! 14 | @IBOutlet weak var permutationsCountLabel: NSTextField! 15 | @IBOutlet weak var generatePermutationsButton: NSButton! 16 | 17 | var permutations = [String]() 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | stringTextField.becomeFirstResponder() 22 | } 23 | 24 | // MARK: NSTableViewDataSource Methods 25 | func numberOfRowsInTableView(tableView: NSTableView) -> Int { 26 | return self.permutations.count 27 | } 28 | 29 | // MARK: NSTableViewDelegate Methods 30 | func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? { 31 | let permutation = self.permutations[row] 32 | 33 | let tableCellView = tableView.makeViewWithIdentifier("PermutationCell", owner: self) as? NSTableCellView 34 | tableCellView?.textField?.stringValue = permutation 35 | 36 | return tableCellView 37 | } 38 | 39 | func tableView(tableView: NSTableView, selectionIndexesForProposedSelection proposedSelectionIndexes: NSIndexSet) -> NSIndexSet { 40 | return NSIndexSet() 41 | } 42 | 43 | // MARK: Action Methods 44 | @IBAction func generatePermutations(sender: NSButton!) { 45 | permutations = stringTextField.stringValue.permutations() 46 | permutationsCountLabel.stringValue = "Permutations: \(permutations.count)" 47 | permutationsTableView.reloadData() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Problems/LargestSumSequence/LargestSumSequence/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // LargestSumSequence 4 | // 5 | // Created by Rogelio Gudino on 8/22/15. 6 | // Copyright © 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | @IBOutlet weak var currentArrayLabel: NSTextField! 13 | @IBOutlet weak var resultArrayLabel: NSTextField! 14 | @IBOutlet weak var resultSumLabel: NSTextField! 15 | @IBOutlet weak var numberTextField: NSTextField! 16 | @IBOutlet weak var appendButton: NSButton! 17 | @IBOutlet weak var calculateButton: NSButton! 18 | 19 | var currentArray = [Int]() 20 | var resultArray = [Int]() 21 | 22 | @IBAction func appendButtonWasClicked(sender: AnyObject!) { 23 | if let number = Int(numberTextField.stringValue) { 24 | currentArray.append(number) 25 | updateUI() 26 | } 27 | } 28 | 29 | @IBAction func calculateButtonWasClicked(sender: AnyObject!) { 30 | resultArray = largestSumSequence(currentArray) 31 | updateUI() 32 | } 33 | 34 | @IBAction func clearButtonWasClicked(sender: AnyObject!) { 35 | currentArray.removeAll() 36 | resultArray.removeAll() 37 | numberTextField.stringValue = "0" 38 | updateUI() 39 | } 40 | 41 | override func controlTextDidChange(obj: NSNotification) { 42 | if let _ = Int(numberTextField.stringValue) { 43 | appendButton.enabled = true 44 | calculateButton.enabled = true 45 | } else { 46 | appendButton.enabled = false 47 | calculateButton.enabled = false 48 | } 49 | } 50 | 51 | private func updateUI() { 52 | currentArrayLabel.stringValue = currentArray.description 53 | resultArrayLabel.stringValue = resultArray.description 54 | resultSumLabel.stringValue = String(resultArray.reduce(0) { $0 + $1 }) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Sources/StringSearching/NaiveStringSearch.swift: -------------------------------------------------------------------------------- 1 | public func naiveStringSearch(pattern: String, string: String) -> [Range] { 2 | if pattern.count < 1 || string.count < 1 { 3 | return [] 4 | } 5 | var results = [Range]() 6 | var currentStart = 0 7 | while let range = rangeOfFirstOccurrance(start: currentStart, pattern: pattern, string: string) { 8 | results.append(range) 9 | currentStart = range.endIndex 10 | } 11 | return results 12 | } 13 | 14 | private func rangeOfFirstOccurrance(start: Int, pattern: String, string: String) -> Range? { 15 | if pattern.count < 1 || string.count < 1 { 16 | return nil 17 | } 18 | 19 | if pattern.count > (string.count - start) { 20 | return nil 21 | } 22 | 23 | var possibleMatchingStartIndex: String.Index? 24 | 25 | var currentStringIndex = string.index(string.startIndex, offsetBy: start) 26 | var currentPatternIndex = pattern.startIndex 27 | 28 | while pattern.distance(from: currentPatternIndex, to: pattern.endIndex) > 0 && string.distance(from: currentStringIndex, to: string.endIndex) > 0 { 29 | let currentStringCharacter = string[currentStringIndex] 30 | let currentPatternCharacter = pattern[currentPatternIndex] 31 | 32 | if currentStringCharacter == currentPatternCharacter { 33 | if possibleMatchingStartIndex == nil { 34 | possibleMatchingStartIndex = currentStringIndex 35 | } 36 | currentPatternIndex = string.index(currentPatternIndex, offsetBy: 1) 37 | } else if possibleMatchingStartIndex != nil { 38 | possibleMatchingStartIndex = nil 39 | currentPatternIndex = pattern.startIndex 40 | } 41 | 42 | currentStringIndex = string.index(currentStringIndex, offsetBy: 1) 43 | } 44 | 45 | if let matchingStartIndex = possibleMatchingStartIndex { 46 | let matchingStart = string.distance(from: string.startIndex, to: matchingStartIndex) 47 | let matchingEnd = matchingStart + pattern.count 48 | return matchingStart.. { 2 | public typealias Preferences = [T: [T]] 3 | 4 | public static func solve(_ proposersPreferences: Preferences, _ recipientsPreferences: Preferences) -> [T: T]? { 5 | if proposersPreferences.count != recipientsPreferences.count { 6 | return nil 7 | } 8 | 9 | var result = [T: T]() 10 | var inverseResult = [T: T]() 11 | while result.count < proposersPreferences.count { 12 | for proposer in proposersPreferences.keys { 13 | // If the proposer is already matched, skip. 14 | if result[proposer] != nil { 15 | continue 16 | } 17 | 18 | // Go over their ranking to propose to the best one. 19 | for choice in proposersPreferences[proposer]! { 20 | if let competingProposer = inverseResult[choice] { 21 | // Their choice is taken, can they upgrade? 22 | let choicesRankings = recipientsPreferences[choice]! 23 | if self.isNewProposerBetter(newProposer: proposer, existingProposer: competingProposer, rankings: choicesRankings) { 24 | // Upgrade! 25 | result[proposer] = choice 26 | inverseResult[choice] = proposer 27 | // Remove competing proposer from result. 28 | result[competingProposer] = nil 29 | break 30 | } 31 | } else { 32 | // Their choice is free, marry for now. 33 | result[proposer] = choice 34 | inverseResult[choice] = proposer 35 | break 36 | } 37 | } 38 | } 39 | } 40 | 41 | return result 42 | } 43 | 44 | private static func isNewProposerBetter(newProposer: T, existingProposer: T, rankings: [T]) -> Bool { 45 | for choice in rankings { 46 | if choice == newProposer { 47 | return true 48 | } 49 | if choice == existingProposer { 50 | return false 51 | } 52 | } 53 | return false 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Tests/StringSearchingTests/NaiveStringSearchTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import StringSearching 3 | 4 | final class NaiveStringSearchTests: XCTestCase { 5 | func testReturnsEmptyArray() { 6 | let pattern = "World" 7 | let string = "Hello Universe!" 8 | 9 | let ranges = naiveStringSearch(pattern: pattern, string: string) 10 | XCTAssert(ranges.count == 0) 11 | } 12 | 13 | func testReturnsOneRange() { 14 | let pattern = "World" 15 | let string = "Hello Wor World!" 16 | 17 | let ranges = naiveStringSearch(pattern: pattern, string: string) 18 | XCTAssert(ranges.count == 1) 19 | 20 | let range = ranges[0] 21 | XCTAssert(range == 10..<15) 22 | } 23 | 24 | func testReturnsThreeRanges() { 25 | let pattern = "World" 26 | let string = "World, Hello Wor WorldWorld" 27 | 28 | let ranges = naiveStringSearch(pattern: pattern, string: string) 29 | XCTAssert(ranges.count == 3) 30 | 31 | let firstRange = ranges[0] 32 | XCTAssert(firstRange == 0..<5) 33 | 34 | let secondRange = ranges[1] 35 | XCTAssert(secondRange == 17..<22) 36 | 37 | let thirdRange = ranges[2] 38 | XCTAssert(thirdRange == 22..<27) 39 | } 40 | 41 | func testMiscCases() { 42 | var pattern = "needle" 43 | var string = "Find a needle in a haystack" 44 | var patternRanges = naiveStringSearch(pattern: pattern, string: string) 45 | XCTAssert(patternRanges.count == 1) 46 | XCTAssert(patternRanges[0] == 7..<13) 47 | 48 | pattern = "orl" 49 | string = "Hello World!" 50 | patternRanges = naiveStringSearch(pattern: pattern, string: string) 51 | XCTAssert(patternRanges.count == 1) 52 | XCTAssert(patternRanges[0] == 7..<10) 53 | 54 | pattern = "World" 55 | string = "Wo" 56 | patternRanges = naiveStringSearch(pattern: pattern, string: string) 57 | XCTAssert(patternRanges.count == 0) 58 | } 59 | 60 | func testSpeedPerformanceSmall() { 61 | let string = LoremIpsum.small 62 | let pattern = "Maecenas" 63 | self.measure { 64 | let patternRanges = naiveStringSearch(pattern: pattern, string: string) 65 | XCTAssert(patternRanges.count == 3) 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Misc/HelloBashCursor/HelloBashCursor.swift: -------------------------------------------------------------------------------- 1 | import Darwin 2 | 3 | /** 4 | Proof of concept script to illustrate how to print and move the bash cursor around. 5 | 6 | Prerequisite Knowledge: 7 | - `fflush(__stdoutp)`: Forces output lacking new-line. 8 | - `\r`: Puts the cursor at the beginning of the line (a.k.a. carriage return). 9 | - `\u{1B}`: Unicode escape character (`\033` in bash). 10 | - `7`: When it follows an escape character, it saves the current cursor position. 11 | - `8`: When it follows an escape character, it restores the cursor position. 12 | - `[3A`: When it follows an escape character, it moves the cursor UP 3 rows. 13 | - `[3B`: When it follows an escape character, it moves the cursor DOWN 3 rows. 14 | - `[3C`: When it follows an escape character, it moves the cursor FORWARD 3 columns. 15 | - `[3D`: When it follows an escape character, it moves the cursor BACKWARD 3 columns. 16 | - `[1;0H`: When it follows an escape character, it places the cursor in row 1, column 0. 17 | 18 | Resources: 19 | - http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html 20 | - http://ascii-table.com/ansi-escape-sequences.php 21 | - http://wiki.bash-hackers.org/scripting/terminalcodes 22 | - https://stackoverflow.com/questions/25483292/update-current-line-with-command-line-tool-in-swift 23 | */ 24 | 25 | func oneLineReplaceSimple() { 26 | for i in 9...13 { 27 | print("\rHello \(i)", terminator: "") 28 | fflush(__stdoutp) 29 | sleep(1) 30 | } 31 | print("") 32 | } 33 | //oneLineReplaceSimple() 34 | 35 | func oneLineReplace() { 36 | for i in 9...13 { 37 | if i != 9 { 38 | print("\u{1B}8", terminator: "") 39 | } 40 | print("\u{1B}7Hello \(i)", terminator: "") 41 | fflush(__stdoutp) 42 | sleep(1) 43 | } 44 | print("") 45 | } 46 | //oneLineReplace() 47 | 48 | func multipleLineReplaceSimple() { 49 | for i in 9...13 { 50 | if i != 9 { 51 | print("\u{1B}8", terminator: "") 52 | } 53 | print("\u{1B}7Hello \(i)\nHello \(i)\nHello \(i)") 54 | sleep(1) 55 | } 56 | } 57 | //multipleLineReplaceSimple() 58 | 59 | func multipleLineReplace() { 60 | for i in 9...13 { 61 | if i != 9 { 62 | print("\r\u{1B}[3A", terminator: "") 63 | } 64 | print("Hello \(i)\nHello \(i)\nHello \(i)") 65 | sleep(1) 66 | } 67 | } 68 | multipleLineReplace() 69 | -------------------------------------------------------------------------------- /Problems/Fractals/Fractals/TriangleFractalView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TriangleFractalView.swift 3 | // SwiftFractals 4 | // 5 | // Created by Rogelio Gudino on 8/2/14. 6 | // Copyright (c) 2014 Cananito. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class TriangleFractalView: FractalView { 12 | override func drawFractal(rect: NSRect) { 13 | self.drawTriangle(rect) 14 | 15 | let width = CGRectGetWidth(rect) 16 | let height = CGRectGetHeight(rect) 17 | 18 | if (width < 20.0 || height < 20.0) { 19 | return 20 | } 21 | 22 | let halfWidth = width / 2 23 | let halfHeight = height / 2 24 | 25 | let topY = rect.origin.y + halfHeight 26 | let bottomY = rect.origin.y 27 | let middleX = rect.origin.x + (halfWidth / 2) 28 | let rightX = rect.origin.x + halfWidth 29 | let leftX = rect.origin.x 30 | 31 | let topMiddleRect = NSRect(x: middleX, y: topY, width: halfWidth, height: halfHeight) 32 | let bottomRightRect = NSRect(x: rightX, y: bottomY, width: halfWidth, height: halfHeight) 33 | let bottomLeftRect = NSRect(x: leftX, y: bottomY, width: halfWidth, height: halfHeight) 34 | 35 | drawFractal(topMiddleRect) 36 | drawFractal(bottomRightRect) 37 | drawFractal(bottomLeftRect) 38 | } 39 | 40 | private func drawTriangle(rect: NSRect) { 41 | let topY = rect.origin.y + CGRectGetHeight(rect) 42 | let bottomY = rect.origin.y 43 | let middleX = rect.origin.x + (CGRectGetWidth(rect) / 2) 44 | let rightX = rect.origin.x + CGRectGetWidth(rect) 45 | let leftX = rect.origin.x 46 | 47 | let topMiddlePoint: NSPoint = NSPoint(x: middleX, y: topY) 48 | let bottomRightPoint: NSPoint = NSPoint(x: rightX, y: bottomY) 49 | let bottomLeftPoint: NSPoint = NSPoint(x: leftX, y: bottomY) 50 | 51 | self.randomColor().set() 52 | let trianglePath: NSBezierPath = NSBezierPath() 53 | trianglePath.moveToPoint(topMiddlePoint) 54 | trianglePath.lineToPoint(bottomRightPoint) 55 | trianglePath.lineToPoint(bottomLeftPoint) 56 | trianglePath.lineToPoint(topMiddlePoint) 57 | trianglePath.lineWidth = 2.0 58 | trianglePath.stroke() 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Problems/AnagramFinder/AnagramFinderTests/AnagramFinderTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnagramFinderTests.swift 3 | // AnagramFinderTests 4 | // 5 | // Created by Rogelio Gudino on 2/14/15. 6 | // Copyright (c) 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import XCTest 11 | import AnagramFinder 12 | 13 | class AnagramFinderTests: XCTestCase { 14 | func testAnagramClusterer() { 15 | // Empty. 16 | var words = [String]() 17 | var expected = [String: [String]]() 18 | var result = clusterArrayOfWords(words) 19 | XCTAssertTrue(self.wordClustersAreEqual(expected, result)) 20 | 21 | // Values not equal to sorted keys. 22 | words = ["cab", "cba", 23 | "bab"] 24 | expected = ["abc": ["cab", "cba"], 25 | "abb": ["bab"]] 26 | result = clusterArrayOfWords(words) 27 | XCTAssertTrue(self.wordClustersAreEqual(expected, result)) 28 | 29 | // Many values, including equal to sorted keys. 30 | words = ["abc", "acb", "bac", "bca", "cab", "cba", 31 | "abb", "bab", "bba"] 32 | expected = ["abc": ["abc", "acb", "bac", "bca", "cab", "cba"], 33 | "abb": ["abb", "bab", "bba"]] 34 | result = clusterArrayOfWords(words) 35 | XCTAssertTrue(self.wordClustersAreEqual(expected, result)) 36 | 37 | // Missing keys or values. 38 | expected = ["abc": ["abc"], 39 | "abb": ["abb"]] 40 | XCTAssertFalse(self.wordClustersAreEqual(expected, result)) 41 | expected = ["abc": ["abc"], 42 | "zzz": ["zzz"]] 43 | XCTAssertFalse(self.wordClustersAreEqual(expected, result)) 44 | expected = ["abc": ["abc"]] 45 | XCTAssertFalse(self.wordClustersAreEqual(expected, result)) 46 | } 47 | 48 | private func wordClustersAreEqual(_ lhs: [String: [String]], _ rhs: [String: [String]]) -> Bool { 49 | if lhs.keys.count != rhs.keys.count { 50 | return false 51 | } 52 | for (key, leftValue) in lhs { 53 | if let rightValue = rhs[key] { 54 | if leftValue != rightValue { 55 | return false 56 | } 57 | } else { 58 | return false 59 | } 60 | } 61 | return true 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /DataStructures/Stack/Tests/StackTests/StackTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Stack 3 | 4 | class StackTests: XCTestCase { 5 | func testCount() { 6 | let stack = Stack(elements: [1, 2, 3]) 7 | XCTAssert(stack.count() == 3, "Count should be 3.") 8 | } 9 | 10 | func testPeek() { 11 | let stack = Stack(elements: [1, 2, 3]) 12 | XCTAssert(stack.peek() == 3, "Peeked element should be 3.") 13 | } 14 | 15 | func testMutation() { 16 | var stack = Stack() 17 | stack.push(1) 18 | XCTAssert(stack.peek() == 1, "Peeked element should be 1.") 19 | stack.push(2) 20 | XCTAssert(stack.pop() == 2, "Next element should be 2.") 21 | XCTAssert(stack.pop() == 1, "Next element should be 1.") 22 | } 23 | 24 | func testReverse() { 25 | var stack = Stack() 26 | stack.reverse() 27 | XCTAssert(stack.count() == 0) 28 | XCTAssertNil(stack.peek()) 29 | 30 | stack.push(1) 31 | stack.reverse() 32 | XCTAssert(stack.peek() == 1) 33 | 34 | stack.push(2) 35 | stack.push(3) 36 | stack.push(4) 37 | stack.reverse() 38 | XCTAssert(stack.pop() == 1) 39 | XCTAssert(stack.pop() == 2) 40 | XCTAssert(stack.pop() == 3) 41 | XCTAssert(stack.pop() == 4) 42 | XCTAssert(stack.count() == 0) 43 | 44 | stack.push(1) 45 | stack.push(2) 46 | stack.push(3) 47 | stack.push(4) 48 | stack.reverse() 49 | XCTAssert(stack.pop() == 1) 50 | XCTAssert(stack.pop() == 2) 51 | XCTAssert(stack.pop() == 3) 52 | XCTAssert(stack.pop() == 4) 53 | XCTAssert(stack.count() == 0) 54 | 55 | stack.push(1) 56 | stack.push(2) 57 | stack.push(3) 58 | stack.push(4) 59 | stack.reverse() 60 | stack.reverse() 61 | XCTAssert(stack.pop() == 4) 62 | XCTAssert(stack.pop() == 3) 63 | XCTAssert(stack.pop() == 2) 64 | XCTAssert(stack.pop() == 1) 65 | XCTAssert(stack.count() == 0) 66 | 67 | stack.push(1) 68 | stack.push(2) 69 | stack.reverse() 70 | stack.push(3) 71 | stack.push(4) 72 | XCTAssert(stack.pop() == 4) 73 | XCTAssert(stack.pop() == 3) 74 | XCTAssert(stack.pop() == 1) 75 | XCTAssert(stack.pop() == 2) 76 | XCTAssert(stack.count() == 0) 77 | } 78 | 79 | static var allTests = [ 80 | ("testCount", testCount), 81 | ("testPeek", testPeek), 82 | ("testMutation", testMutation), 83 | ("testReverse", testReverse), 84 | ] 85 | } 86 | -------------------------------------------------------------------------------- /Problems/LargestSumSequence/LargestSumSequence/LargestSumSequenceCalculator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LargestSumSequenceCalculator.swift 3 | // LargestSumSequence 4 | // 5 | // Created by Rogelio Gudino on 8/22/15. 6 | // Copyright © 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | func largestSumSequence(array: [Int]) -> [Int] { 10 | var result = [Int]() 11 | var largest = Int.min 12 | var current = 0 13 | var start = 0 14 | var end = array.count - 1 15 | 16 | for i in 0 ..< array.count { 17 | if current < 0 { 18 | current = 0 19 | start = i 20 | } 21 | current += array[i] 22 | if current > largest { 23 | largest = current 24 | end = i 25 | result = Array(array[start...end]) 26 | } 27 | } 28 | return result 29 | } 30 | 31 | func largestSum(array: [Int]) -> Int { 32 | var largest = Int.min 33 | var current = 0 34 | 35 | for number in array { 36 | if current < 0 { 37 | current = 0 38 | } 39 | current += number 40 | if current > largest { 41 | largest = current 42 | } 43 | } 44 | 45 | return largest 46 | } 47 | 48 | func largestSumSequenceSlow(array: [Int]) -> [Int] { 49 | var result = [Int]() 50 | var start = 0 51 | var end = array.count 52 | var sum = Int.min 53 | 54 | while start < array.count { 55 | end = array.count 56 | while end > start { 57 | let range = start ..< end 58 | let subArray = Array(array[range]) 59 | let tempSum = subArray.reduce(0) { $0 + $1 } 60 | if tempSum > sum { 61 | sum = tempSum 62 | result = subArray 63 | } 64 | end -= 1 65 | } 66 | start += 1 67 | } 68 | 69 | return result 70 | } 71 | 72 | func largestSumSlow(array: [Int]) -> Int { 73 | var result = Int.min 74 | var start = 0 75 | var end = array.count 76 | 77 | while start < array.count { 78 | end = array.count 79 | while end > start { 80 | let range = start ..< end 81 | let subArray = Array(array[range]) 82 | let sum = subArray.reduce(0) { $0 + $1 } 83 | if sum > result { 84 | result = sum 85 | } 86 | end -= 1 87 | } 88 | start += 1 89 | } 90 | 91 | return result 92 | } 93 | -------------------------------------------------------------------------------- /Problems/Fractals/Fractals/MondrianFractalView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MondrianFractalView.swift 3 | // SwiftFractals 4 | // 5 | // Created by Rogelio Gudino on 8/2/14. 6 | // Copyright (c) 2014 Cananito. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | enum MondrianSquareSequence: Int { 12 | case SplitHorizontal, SplitVertical, Nothing 13 | } 14 | 15 | class MondrianFractalView: FractalView { 16 | override func drawFractal(rect: NSRect) { 17 | let width = CGRectGetWidth(rect) 18 | let height = CGRectGetHeight(rect) 19 | 20 | if (width < 20.0 || height < 20.0) { 21 | return 22 | } 23 | 24 | self.drawSquare(rect) 25 | 26 | let sequence = MondrianSquareSequence(rawValue: Int(arc4random_uniform(UInt32(3)))) 27 | if let mondrianSequence = sequence { 28 | switch mondrianSequence { 29 | case .SplitHorizontal: 30 | self.splitHorizontal(rect) 31 | case .SplitVertical: 32 | self.splitVertical(rect) 33 | case .Nothing: 34 | break 35 | } 36 | } 37 | } 38 | 39 | private func splitHorizontal(rect: NSRect) { 40 | let newY = self.newValueForRectLength(rect.size.height) 41 | let topRect = NSRect(x: rect.origin.x, y: rect.origin.y, width: rect.size.width, height: newY) 42 | let bottomRect = NSRect(x: rect.origin.x, y: rect.origin.y + newY, width: rect.size.width, height: rect.size.height - newY) 43 | self.drawFractal(topRect) 44 | self.drawFractal(bottomRect) 45 | } 46 | 47 | private func splitVertical(rect: NSRect) { 48 | let newX = self.newValueForRectLength(rect.size.width) 49 | let leftRect = NSRect(x: rect.origin.x, y: rect.origin.y, width: newX, height: rect.size.height) 50 | let rightRect = NSRect(x: rect.origin.x + newX, y: rect.origin.y, width: rect.size.width - newX, height: rect.size.height) 51 | self.drawFractal(leftRect) 52 | self.drawFractal(rightRect) 53 | } 54 | 55 | private func newValueForRectLength(length: CGFloat) -> CGFloat { 56 | let value = Float(arc4random_uniform(UInt32(length))) 57 | return CGFloat(value) 58 | } 59 | 60 | private func drawSquare(rect: NSRect) { 61 | let squarePath: NSBezierPath = NSBezierPath(rect: rect) 62 | self.randomColor().set() 63 | squarePath.fill() 64 | NSColor.blackColor().set() 65 | squarePath.stroke() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /DataStructures/Heap/Tests/HeapTests/HeapTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Heap 3 | 4 | class HeapTests: XCTestCase { 5 | func testHeap() { 6 | var heap = Heap(leftIsHigherPriority: >) 7 | XCTAssertEqual(heap.count(), 0) 8 | XCTAssertTrue(heap.isEmpty()) 9 | 10 | heap.insert(element: 5) 11 | XCTAssertEqual(heap.count(), 1) 12 | XCTAssertEqual(heap.peek(), 5) 13 | XCTAssertFalse(heap.isEmpty()) 14 | 15 | heap.insert(element: 24) 16 | XCTAssertEqual(heap.count(), 2) 17 | XCTAssertEqual(heap.peek(), 24) 18 | XCTAssertFalse(heap.isEmpty()) 19 | 20 | heap.insert(element: 1) 21 | XCTAssertEqual(heap.count(), 3) 22 | XCTAssertEqual(heap.peek(), 24) 23 | XCTAssertFalse(heap.isEmpty()) 24 | 25 | heap.insert(element: 26) 26 | XCTAssertEqual(heap.count(), 4) 27 | XCTAssertEqual(heap.peek(), 26) 28 | XCTAssertFalse(heap.isEmpty()) 29 | 30 | heap.insert(element: 7) 31 | XCTAssertEqual(heap.count(), 5) 32 | XCTAssertEqual(heap.peek(), 26) 33 | XCTAssertFalse(heap.isEmpty()) 34 | 35 | heap.insert(element: 50) 36 | XCTAssertEqual(heap.count(), 6) 37 | XCTAssertEqual(heap.peek(), 50) 38 | XCTAssertFalse(heap.isEmpty()) 39 | 40 | heap.insert(element: 48) 41 | XCTAssertEqual(heap.count(), 7) 42 | XCTAssertEqual(heap.peek(), 50) 43 | XCTAssertFalse(heap.isEmpty()) 44 | 45 | heap.insert(element: 2) 46 | XCTAssertEqual(heap.count(), 8) 47 | XCTAssertEqual(heap.peek(), 50) 48 | XCTAssertFalse(heap.isEmpty()) 49 | 50 | XCTAssertEqual(heap.remove(), 50) 51 | XCTAssertEqual(heap.count(), 7) 52 | XCTAssertFalse(heap.isEmpty()) 53 | 54 | XCTAssertEqual(heap.remove(), 48) 55 | XCTAssertEqual(heap.count(), 6) 56 | XCTAssertFalse(heap.isEmpty()) 57 | 58 | XCTAssertEqual(heap.remove(), 26) 59 | XCTAssertEqual(heap.count(), 5) 60 | XCTAssertFalse(heap.isEmpty()) 61 | 62 | XCTAssertEqual(heap.remove(), 24) 63 | XCTAssertEqual(heap.count(), 4) 64 | XCTAssertFalse(heap.isEmpty()) 65 | 66 | XCTAssertEqual(heap.remove(), 7) 67 | XCTAssertEqual(heap.count(), 3) 68 | XCTAssertFalse(heap.isEmpty()) 69 | 70 | XCTAssertEqual(heap.remove(), 5) 71 | XCTAssertEqual(heap.count(), 2) 72 | XCTAssertFalse(heap.isEmpty()) 73 | 74 | XCTAssertEqual(heap.remove(), 2) 75 | XCTAssertEqual(heap.count(), 1) 76 | XCTAssertFalse(heap.isEmpty()) 77 | 78 | XCTAssertEqual(heap.remove(), 1) 79 | XCTAssertEqual(heap.count(), 0) 80 | XCTAssertTrue(heap.isEmpty()) 81 | } 82 | 83 | static var allTests = [ 84 | ("testHeap", testHeap), 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /DataStructures/BinaryTree/Sources/BinaryTree/BinaryTree.swift: -------------------------------------------------------------------------------- 1 | public class BinaryTreeNode: CustomStringConvertible, CustomDebugStringConvertible { 2 | public let value: T 3 | public var leftNode: BinaryTreeNode? 4 | public var rightNode: BinaryTreeNode? 5 | public weak var parentNode: BinaryTreeNode? 6 | 7 | public init(value: T) { 8 | self.value = value 9 | } 10 | 11 | public func enumerate(_ body: (BinaryTreeNode) -> ()) { 12 | enumerateInOrder(body) 13 | } 14 | 15 | public func enumerateInOrder(_ body: (BinaryTreeNode) -> ()) { 16 | if let leftNode = self.leftNode { 17 | leftNode.enumerateInOrder(body) 18 | } 19 | body(self) 20 | if let rightNode = self.rightNode { 21 | rightNode.enumerateInOrder(body) 22 | } 23 | } 24 | 25 | public func enumeratePreOrder(_ body: (BinaryTreeNode) -> ()) { 26 | body(self) 27 | if let leftNode = self.leftNode { 28 | leftNode.enumeratePreOrder(body) 29 | } 30 | if let rightNode = self.rightNode { 31 | rightNode.enumeratePreOrder(body) 32 | } 33 | } 34 | 35 | public func enumeratePostOrder(_ body: (BinaryTreeNode) -> ()) { 36 | if let leftNode = self.leftNode { 37 | leftNode.enumeratePostOrder(body) 38 | } 39 | if let rightNode = self.rightNode { 40 | rightNode.enumeratePostOrder(body) 41 | } 42 | body(self) 43 | } 44 | 45 | public func enumerateBreadthFirst(_ body: (BinaryTreeNode) -> ()) { 46 | var queue = [BinaryTreeNode]() 47 | queue.append(self) 48 | 49 | while queue.isEmpty == false { 50 | let current = queue.first! 51 | if let left = current.leftNode { 52 | queue.append(left) 53 | } 54 | if let right = current.rightNode { 55 | queue.append(right) 56 | } 57 | body(current) 58 | queue.removeFirst() 59 | } 60 | } 61 | 62 | public func next() -> BinaryTreeNode? { 63 | var nextLeft = self.rightNode 64 | while nextLeft != nil { 65 | if let n = nextLeft?.leftNode { 66 | nextLeft = n 67 | } else { 68 | return nextLeft 69 | } 70 | } 71 | 72 | var currentNode = self 73 | while currentNode.parentNode != nil { 74 | let parent = currentNode.parentNode! 75 | if let left = parent.leftNode, left === currentNode { 76 | return parent 77 | } 78 | currentNode = parent 79 | } 80 | 81 | return nil 82 | } 83 | 84 | // MARK: CustomStringConvertible 85 | 86 | public var description: String { 87 | return "\(self.value)" 88 | } 89 | 90 | // MARK: CustomDebugStringConvertible 91 | 92 | public var debugDescription: String { 93 | return "\(self.value)" 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /DataStructures/ExpiringDictionary/Tests/ExpiringDictionaryTests/ExpiringDictionaryTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import ExpiringDictionary 3 | 4 | class ExpiringDictionaryTests: XCTestCase { 5 | func testExpiringDictionary() { 6 | var expiringDictionary = ExpiringDictionary() 7 | 8 | // No values. 9 | XCTAssertEqual(expiringDictionary.count(), 0) 10 | XCTAssertNil(expiringDictionary.value(forKey: "A")) 11 | 12 | // With an expired value. 13 | expiringDictionary.insert(key: "A", value: "value a", expirationTimeInterval: nowByAddingTimeInterval(-500)) 14 | XCTAssertEqual(expiringDictionary.count(), 0) 15 | XCTAssertNil(expiringDictionary.value(forKey: "A")) 16 | 17 | // With a valid value. 18 | expiringDictionary.insert(key: "B", value: "value b", expirationTimeInterval: nowByAddingTimeInterval(500)) 19 | XCTAssertEqual(expiringDictionary.count(), 1) 20 | XCTAssertEqual(expiringDictionary.value(forKey: "B"), "value b") 21 | XCTAssertEqual(expiringDictionary.count(), 1) 22 | 23 | // Updating a valid value to an invalid one. 24 | expiringDictionary.insert(key: "B", value: "value b", expirationTimeInterval: nowByAddingTimeInterval(-500)) 25 | XCTAssertEqual(expiringDictionary.count(), 0) 26 | XCTAssertNil(expiringDictionary.value(forKey: "B")) 27 | XCTAssertEqual(expiringDictionary.count(), 0) 28 | 29 | // With an always valid value, updating a valid value to another valid one, and then to an invalid one. 30 | expiringDictionary.insert(key: "Z", value: "value z", expirationTimeInterval: nowByAddingTimeInterval(999)) 31 | XCTAssertEqual(expiringDictionary.count(), 1) 32 | XCTAssertEqual(expiringDictionary.value(forKey: "Z"), "value z") 33 | XCTAssertEqual(expiringDictionary.count(), 1) 34 | expiringDictionary.insert(key: "B", value: "value b", expirationTimeInterval: nowByAddingTimeInterval(600)) 35 | XCTAssertEqual(expiringDictionary.count(), 2) 36 | XCTAssertEqual(expiringDictionary.value(forKey: "B"), "value b") 37 | XCTAssertEqual(expiringDictionary.count(), 2) 38 | expiringDictionary.insert(key: "B", value: "value b", expirationTimeInterval: nowByAddingTimeInterval(700)) 39 | XCTAssertEqual(expiringDictionary.count(), 2) 40 | XCTAssertEqual(expiringDictionary.value(forKey: "B"), "value b") 41 | XCTAssertEqual(expiringDictionary.count(), 2) 42 | expiringDictionary.insert(key: "B", value: "value b", expirationTimeInterval: nowByAddingTimeInterval(-500)) 43 | XCTAssertEqual(expiringDictionary.count(), 1) 44 | XCTAssertNil(expiringDictionary.value(forKey: "B")) 45 | XCTAssertEqual(expiringDictionary.count(), 1) 46 | } 47 | 48 | private func nowByAddingTimeInterval(_ timeInterval: TimeInterval) -> TimeInterval { 49 | return Date().timeIntervalSince1970 + timeInterval 50 | } 51 | 52 | static var allTests = [ 53 | ("testExpiringDictionary", testExpiringDictionary), 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Sources/StringSearching/BoyerMooreHorspool.swift: -------------------------------------------------------------------------------- 1 | private func badCharacterRuleTableForPattern(pattern: String) -> [Character: Int] { 2 | var table = [Character: Int]() 3 | let lastCharacterIndex = pattern.count - 1 4 | for (index, character) in pattern.enumerated() { 5 | table[character] = lastCharacterIndex - index 6 | } 7 | return table 8 | } 9 | 10 | public struct BoyerMooreHorspoolPattern { 11 | public let string: String 12 | internal let characterCount: Int 13 | private let badCharacterRuleTable: [Character: Int] 14 | 15 | public init(string: String) { 16 | self.string = string 17 | self.characterCount = string.count 18 | self.badCharacterRuleTable = badCharacterRuleTableForPattern(pattern: string) 19 | } 20 | 21 | internal func badCharacterRuleShift(character: Character) -> Int { 22 | if let index = self.badCharacterRuleTable[character] { 23 | return index 24 | } 25 | return self.characterCount 26 | } 27 | } 28 | 29 | public func boyerMooreHorspoolStringSearch(pattern: BoyerMooreHorspoolPattern, document: String) -> [Range] { 30 | if pattern.string.count < 1 || document.count < 1 { 31 | return [] 32 | } 33 | 34 | if pattern.string.count > document.count { 35 | return [] 36 | } 37 | 38 | var ranges = [Range]() 39 | var currentDocumentIndex = document.startIndex 40 | let patternCharacterCount = pattern.characterCount 41 | let endIndex = document.index(document.endIndex, offsetBy: -patternCharacterCount) 42 | 43 | while true { 44 | var shift = 1 45 | var match = true 46 | 47 | // TODO: All this `index(_:,offsetBy:)` and `distance(from:to:)` is super inefficient, tune. 48 | for index in stride(from: patternCharacterCount - 1, to: 0, by: -1) { 49 | let documentIndex = document.index(currentDocumentIndex, offsetBy: index) 50 | let patternIndex = pattern.string.index(pattern.string.startIndex, offsetBy: index) 51 | 52 | let documentCharacter = document[documentIndex] 53 | let patternCharacter = pattern.string[patternIndex] 54 | 55 | if documentCharacter != patternCharacter { 56 | let badCharacterShift = pattern.badCharacterRuleShift(character: documentCharacter) 57 | shift = max(badCharacterShift, shift) 58 | match = false 59 | break 60 | } 61 | } 62 | 63 | if match == true { 64 | let start = document.distance(from: document.startIndex, to: currentDocumentIndex) 65 | let end = document.distance(from: document.startIndex, to: document.index(currentDocumentIndex, offsetBy: patternCharacterCount)) 66 | let range = start.. Term? { 39 | for term in terms { 40 | if term.coefficient == coefficient { 41 | return term 42 | } 43 | } 44 | return nil 45 | } 46 | 47 | public func derived() -> Polynomial { 48 | let terms = self.simplified().terms.sorted { $0.coefficient > $1.coefficient } 49 | 50 | var derivedTerms = [Term]() 51 | for term in terms { 52 | if term.coefficient == 0 { 53 | continue 54 | } 55 | 56 | let newConstant = term.constant * term.coefficient 57 | let newCoefficient = term.coefficient - 1 58 | let newTerm = Term(constant: newConstant, coefficient: newCoefficient) 59 | derivedTerms.append(newTerm) 60 | } 61 | 62 | return Polynomial(terms: derivedTerms) 63 | } 64 | 65 | public func simplified() -> Polynomial { 66 | var simplifiedTerms = [Term]() 67 | for (_, value) in coefficientGroupedTerms(terms) { 68 | let term = Term(constant: value.constant, coefficient: value.coefficient) 69 | simplifiedTerms.append(term) 70 | } 71 | return Polynomial(terms: simplifiedTerms) 72 | } 73 | 74 | // MARK: CustomStringConvertible 75 | 76 | public var description: String { 77 | return terms.map { $0.description }.joined(separator: ", ") 78 | } 79 | 80 | // MARK: CustomDebugStringConvertible 81 | 82 | public var debugDescription: String { 83 | return description 84 | } 85 | } 86 | 87 | private func coefficientGroupedTerms(_ terms: [Term]) -> CoefficientGroupedTerms { 88 | var coefficientGroupedTerms = CoefficientGroupedTerms() 89 | for term in terms { 90 | if let existingTerm = coefficientGroupedTerms[term.coefficient] { 91 | let newConstant = existingTerm.constant + term.constant 92 | coefficientGroupedTerms[term.coefficient] = Term(constant: newConstant, coefficient: term.coefficient) 93 | } else { 94 | coefficientGroupedTerms[term.coefficient] = term 95 | } 96 | } 97 | return coefficientGroupedTerms 98 | } 99 | -------------------------------------------------------------------------------- /DataStructures/Trie/Tests/TrieTests/TrieTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Trie 3 | 4 | class TrieTests: XCTestCase { 5 | func testTrie() { 6 | var trie = Trie() 7 | trie.setValue(1, key: "R") 8 | trie.setValue(2, key: "Ro") 9 | trie.setValue(3, key: "Rog") 10 | trie.setValue(4, key: "Roge") 11 | trie.setValue(5, key: "Rogel") 12 | trie.setValue(6, key: "Rogeli") 13 | trie.setValue(7, key: "Rogelio") 14 | trie.setValue(11, key: "G") 15 | trie.setValue(12, key: "Gu") 16 | trie.setValue(13, key: "Gud") 17 | trie.setValue(14, key: "Gudi") 18 | trie.setValue(15, key: "Gudin") 19 | trie.setValue(16, key: "Gudino") 20 | 21 | XCTAssert(trie.valueForKey("R")! == 1) 22 | XCTAssert(trie.valueForKey("Ro")! == 2) 23 | XCTAssert(trie.valueForKey("Rog")! == 3) 24 | XCTAssert(trie.valueForKey("Roge")! == 4) 25 | XCTAssert(trie.valueForKey("Rogel")! == 5) 26 | XCTAssert(trie.valueForKey("Rogeli")! == 6) 27 | XCTAssert(trie.valueForKey("Rogelio")! == 7) 28 | XCTAssert(trie.valueForKey("G")! == 11) 29 | XCTAssert(trie.valueForKey("Gu")! == 12) 30 | XCTAssert(trie.valueForKey("Gud")! == 13) 31 | XCTAssert(trie.valueForKey("Gudi")! == 14) 32 | XCTAssert(trie.valueForKey("Gudin")! == 15) 33 | XCTAssert(trie.valueForKey("Gudino")! == 16) 34 | 35 | XCTAssert(trie.removeValueForKey("R")! == 1) 36 | XCTAssert(trie.valueForKey("R") == nil) 37 | XCTAssert(trie.valueForKey("Ro")! == 2) 38 | 39 | XCTAssert(trie.removeValueForKey("Ro")! == 2) 40 | XCTAssert(trie.valueForKey("Ro") == nil) 41 | XCTAssert(trie.valueForKey("Rog")! == 3) 42 | 43 | XCTAssert(trie.removeValueForKey("Rog")! == 3) 44 | XCTAssert(trie.valueForKey("Rog") == nil) 45 | XCTAssert(trie.valueForKey("Roge")! == 4) 46 | 47 | XCTAssert(trie.removeValueForKey("Roge")! == 4) 48 | XCTAssert(trie.valueForKey("Roge") == nil) 49 | XCTAssert(trie.valueForKey("Rogel")! == 5) 50 | 51 | XCTAssert(trie.removeValueForKey("Rogel")! == 5) 52 | XCTAssert(trie.valueForKey("Rogel") == nil) 53 | XCTAssert(trie.valueForKey("Rogeli")! == 6) 54 | 55 | XCTAssert(trie.removeValueForKey("Rogeli")! == 6) 56 | XCTAssert(trie.valueForKey("Rogeli") == nil) 57 | XCTAssert(trie.valueForKey("Rogelio")! == 7) 58 | 59 | XCTAssert(trie.removeValueForKey("Rogelio")! == 7) 60 | XCTAssert(trie.valueForKey("Rogelio") == nil) 61 | 62 | XCTAssert(trie.removeValueForKey("Gudino")! == 16) 63 | XCTAssert(trie.valueForKey("Gudino") == nil) 64 | 65 | XCTAssert(trie.removeValueForKey("Gudin")! == 15) 66 | XCTAssert(trie.valueForKey("Gudin") == nil) 67 | 68 | XCTAssert(trie.removeValueForKey("Gudi")! == 14) 69 | XCTAssert(trie.valueForKey("Gudi") == nil) 70 | 71 | XCTAssert(trie.removeValueForKey("Gud")! == 13) 72 | XCTAssert(trie.valueForKey("Gud") == nil) 73 | 74 | XCTAssert(trie.removeValueForKey("Gu")! == 12) 75 | XCTAssert(trie.valueForKey("Gu") == nil) 76 | 77 | XCTAssert(trie.removeValueForKey("G")! == 11) 78 | XCTAssert(trie.valueForKey("G") == nil) 79 | } 80 | 81 | static var allTests = [ 82 | ("testTrie", testTrie), 83 | ] 84 | } 85 | -------------------------------------------------------------------------------- /DataStructures/ExpiringDictionary/Sources/ExpiringDictionary/ExpiringDictionary.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Heap 3 | 4 | public struct ExpiringDictionary { 5 | private struct ValueTimeInterval { 6 | let value: Value 7 | let expirationTimeInterval: TimeInterval 8 | } 9 | 10 | private struct KeyTimeInterval : Comparable { 11 | static func <(lhs: KeyTimeInterval, rhs: KeyTimeInterval) -> Bool { 12 | return lhs.expirationTimeInterval < rhs.expirationTimeInterval 13 | } 14 | static func ==(lhs: KeyTimeInterval, rhs: KeyTimeInterval) -> Bool { 15 | return lhs.expirationTimeInterval == rhs.expirationTimeInterval 16 | } 17 | let key: Key 18 | let expirationTimeInterval: TimeInterval 19 | } 20 | 21 | private var valueTimeIntervals = Dictionary(); 22 | private var keyTimeIntervalHeap = Heap(leftIsHigherPriority: <) 23 | 24 | public init() { 25 | } 26 | 27 | public func count() -> Int { 28 | return valueTimeIntervals.count 29 | } 30 | 31 | public mutating func insert(key: Key, value: Value, expirationTimeInterval: TimeInterval) { 32 | // Always updating and inserting to get proper clean-up via `cleanUp()`. Otherwise if invalid time intervals are skipped, the heap will become stale with outdated entries. 33 | 34 | valueTimeIntervals[key] = ValueTimeInterval(value: value, expirationTimeInterval: expirationTimeInterval) 35 | // Heap will have possible duplicate keys. `cleanUp()` accounts for this. 36 | keyTimeIntervalHeap.insert(element: KeyTimeInterval(key: key, expirationTimeInterval: expirationTimeInterval)) 37 | cleanUp() 38 | } 39 | 40 | public mutating func value(forKey key: Key) -> Value? { 41 | // return valueWithoutCleanUp(forKey: key) 42 | return valueWithCleanUp(forKey: key) 43 | } 44 | 45 | private mutating func valueWithCleanUp(forKey key: Key) -> Value? { 46 | cleanUp() 47 | return valueTimeIntervals[key]?.value 48 | } 49 | 50 | private mutating func valueWithoutCleanUp(forKey key: Key) -> Value? { 51 | guard let entry = valueTimeIntervals[key] else { 52 | return nil 53 | } 54 | if entry.expirationTimeInterval < Date().timeIntervalSince1970 { 55 | valueTimeIntervals.removeValue(forKey: key) 56 | return nil 57 | } 58 | return entry.value 59 | } 60 | 61 | private mutating func cleanUp() { 62 | let currentTimeInterval = Date().timeIntervalSince1970 63 | while let keyTimeInterval = keyTimeIntervalHeap.peek() { 64 | if keyTimeInterval.expirationTimeInterval >= currentTimeInterval { 65 | // Earliest entry hasn’t expired, rest are also still be valid. 66 | return 67 | } 68 | 69 | // Clean-up otherwise. 70 | _ = keyTimeIntervalHeap.remove() 71 | let key = keyTimeInterval.key 72 | if let valueTimeInterval = valueTimeIntervals[key], valueTimeInterval.expirationTimeInterval == keyTimeInterval.expirationTimeInterval { 73 | valueTimeIntervals.removeValue(forKey: key) 74 | } // Otherwise the entry got updated in the `valueTimeIntervals` dictionary during insert and thus the heap ended with duplicates. 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Tests/StringSearchingTests/BoyerMooreHorspoolTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import StringSearching 3 | 4 | final class BoyerMooreHorspoolTests: XCTestCase { 5 | func testReturnsEmptyArray() { 6 | let pattern = BoyerMooreHorspoolPattern(string: "World") 7 | let document = "Hello Universe!" 8 | 9 | let ranges = boyerMooreHorspoolStringSearch(pattern: pattern, document: document) 10 | XCTAssert(ranges.count == 0) 11 | } 12 | 13 | func testReturnsOneRange() { 14 | let pattern = BoyerMooreHorspoolPattern(string: "World") 15 | let document = "Hello Wor World!" 16 | 17 | let ranges = boyerMooreHorspoolStringSearch(pattern: pattern, document: document) 18 | XCTAssert(ranges.count == 1) 19 | 20 | let range = ranges[0] 21 | XCTAssert(range == 10..<15) 22 | } 23 | 24 | func testReturnsThreeRanges() { 25 | let pattern = BoyerMooreHorspoolPattern(string: "World") 26 | let document = "World, Hello Wor WorldWorld" 27 | 28 | let ranges = boyerMooreHorspoolStringSearch(pattern: pattern, document: document) 29 | XCTAssert(ranges.count == 3) 30 | 31 | let firstRange = ranges[0] 32 | XCTAssert(firstRange == 0..<5) 33 | 34 | let secondRange = ranges[1] 35 | XCTAssert(secondRange == 17..<22) 36 | 37 | let thirdRange = ranges[2] 38 | XCTAssert(thirdRange == 22..<27) 39 | } 40 | 41 | func testMiscCases() { 42 | var pattern = BoyerMooreHorspoolPattern(string: "needle") 43 | var document = "Find a needle in a haystack" 44 | var patternRanges = boyerMooreHorspoolStringSearch(pattern: pattern, document: document) 45 | XCTAssert(patternRanges.count == 1) 46 | XCTAssert(patternRanges[0] == 7..<13) 47 | 48 | pattern = BoyerMooreHorspoolPattern(string: "orl") 49 | document = "Hello World!" 50 | patternRanges = boyerMooreHorspoolStringSearch(pattern: pattern, document: document) 51 | XCTAssert(patternRanges.count == 1) 52 | XCTAssert(patternRanges[0] == 7..<10) 53 | 54 | pattern = BoyerMooreHorspoolPattern(string: "World") 55 | document = "Wo" 56 | patternRanges = boyerMooreHorspoolStringSearch(pattern: pattern, document: document) 57 | XCTAssert(patternRanges.count == 0) 58 | } 59 | 60 | func testSpeedPerformanceSmall() { 61 | let document = LoremIpsum.small 62 | let pattern = BoyerMooreHorspoolPattern(string: "Maecenas") 63 | self.measure { 64 | let patternRanges = boyerMooreHorspoolStringSearch(pattern: pattern, document: document) 65 | XCTAssert(patternRanges.count == 3) 66 | } 67 | } 68 | 69 | func testSpeedPerformanceBig() { 70 | let document = LoremIpsum.big 71 | let pattern = BoyerMooreHorspoolPattern(string: "inceptos himenaeos.") 72 | self.measure { 73 | let patternRanges = boyerMooreHorspoolStringSearch(pattern: pattern, document: document) 74 | XCTAssert(patternRanges.count == 5) 75 | } 76 | } 77 | 78 | static var allTests = [ 79 | ("testReturnsEmptyArray", testReturnsEmptyArray), 80 | ("testReturnsOneRange", testReturnsOneRange), 81 | ("testReturnsThreeRanges", testReturnsThreeRanges), 82 | ("testMiscCases", testMiscCases), 83 | ("testSpeedPerformanceSmall", testSpeedPerformanceSmall), 84 | ("testSpeedPerformanceBig", testSpeedPerformanceBig), 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /Problems/Fractals/Fractals/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Fractals 4 | // 5 | // Created by Rogelio Gudino on 2/8/15. 6 | // Copyright (c) 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | @IBOutlet weak var window: NSWindow! 14 | @IBOutlet weak var fractalContainerView: NSView! 15 | @IBOutlet weak var fractalPickerRadioMatrix: NSMatrix! 16 | private var currentFractalView: FractalView? 17 | private let triangleFractalView: TriangleFractalView 18 | private let mondrianFractalView: MondrianFractalView 19 | 20 | override init() { 21 | self.triangleFractalView = TriangleFractalView() 22 | self.triangleFractalView.translatesAutoresizingMaskIntoConstraints = false 23 | self.mondrianFractalView = MondrianFractalView() 24 | self.mondrianFractalView.translatesAutoresizingMaskIntoConstraints = false 25 | self.currentFractalView = self.triangleFractalView 26 | } 27 | 28 | func applicationDidFinishLaunching(aNotification: NSNotification) { 29 | self.changeToFractalView(fractalView: self.currentFractalView!) 30 | } 31 | 32 | @IBAction func changeFractal(sender: NSMatrix!) { 33 | guard let cell = sender.selectedCell() else { return } 34 | if cell.title == "Triangle" { 35 | changeToFractalView(fractalView: self.triangleFractalView) 36 | } else if cell.title == "Mondrian" { 37 | changeToFractalView(fractalView: self.mondrianFractalView) 38 | } else { 39 | let alert = NSAlert() 40 | alert.messageText = "That fractal is not supported yet." 41 | alert.alertStyle = NSAlertStyle.InformationalAlertStyle 42 | alert.beginSheetModalForWindow(self.window, completionHandler: Optional.None) 43 | } 44 | } 45 | 46 | func changeToFractalView(fractalView fractalView: FractalView) { 47 | self.currentFractalView?.removeFromSuperview() 48 | self.currentFractalView = fractalView 49 | self.fractalContainerView.addSubview(self.currentFractalView!) 50 | 51 | self.fractalContainerView.addConstraint(NSLayoutConstraint(item: self.currentFractalView!, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: self.fractalContainerView, attribute: NSLayoutAttribute.Width, multiplier: 1.0, constant: 0.0)) 52 | self.fractalContainerView.addConstraint(NSLayoutConstraint(item: self.currentFractalView!, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: self.fractalContainerView, attribute: NSLayoutAttribute.Height, multiplier: 1.0, constant: 0.0)) 53 | self.fractalContainerView.addConstraint(NSLayoutConstraint(item: self.currentFractalView!, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.fractalContainerView, attribute: NSLayoutAttribute.Left, multiplier: 1.0, constant: 0.0)) 54 | self.fractalContainerView.addConstraint(NSLayoutConstraint(item: self.currentFractalView!, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.fractalContainerView, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0.0)) 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Problems/PalindromeDetector/Tests/PalindromeDetectorTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Problems_PalindromeDetector_PalindromeDetector 3 | 4 | class PalindromeDetectorTests: XCTestCase { 5 | let first = "" 6 | let second = "a" 7 | let third = "aa" 8 | let fourth = "aba" 9 | let fifth = "abaa" 10 | let sixth = "aaba" 11 | let seventh = "anita lava la tina" 12 | 13 | func testIsPalindromUsingIteration() { 14 | XCTAssertTrue(first.withoutWhiteSpaces().isPalindromeUsingIteration()) 15 | XCTAssertTrue(second.withoutWhiteSpaces().isPalindromeUsingIteration()) 16 | XCTAssertTrue(third.withoutWhiteSpaces().isPalindromeUsingIteration()) 17 | XCTAssertTrue(fourth.withoutWhiteSpaces().isPalindromeUsingIteration()) 18 | XCTAssertFalse(fifth.withoutWhiteSpaces().isPalindromeUsingIteration()) 19 | XCTAssertFalse(sixth.withoutWhiteSpaces().isPalindromeUsingIteration()) 20 | XCTAssertTrue(seventh.withoutWhiteSpaces().isPalindromeUsingIteration()) 21 | } 22 | 23 | func testIsPalindromeUsingRecursion() { 24 | XCTAssertTrue(first.withoutWhiteSpaces().isPalindromeUsingRecursion()) 25 | XCTAssertTrue(second.withoutWhiteSpaces().isPalindromeUsingRecursion()) 26 | XCTAssertTrue(third.withoutWhiteSpaces().isPalindromeUsingRecursion()) 27 | XCTAssertTrue(fourth.withoutWhiteSpaces().isPalindromeUsingRecursion()) 28 | XCTAssertFalse(fifth.withoutWhiteSpaces().isPalindromeUsingRecursion()) 29 | XCTAssertFalse(sixth.withoutWhiteSpaces().isPalindromeUsingRecursion()) 30 | XCTAssertTrue(seventh.withoutWhiteSpaces().isPalindromeUsingRecursion()) 31 | } 32 | 33 | func testIsPalindromeUsingStack() { 34 | XCTAssertTrue(first.withoutWhiteSpaces().isPalindromeUsingStack()) 35 | XCTAssertTrue(second.withoutWhiteSpaces().isPalindromeUsingStack()) 36 | XCTAssertTrue(third.withoutWhiteSpaces().isPalindromeUsingStack()) 37 | XCTAssertTrue(fourth.withoutWhiteSpaces().isPalindromeUsingStack()) 38 | XCTAssertFalse(fifth.withoutWhiteSpaces().isPalindromeUsingStack()) 39 | XCTAssertFalse(sixth.withoutWhiteSpaces().isPalindromeUsingStack()) 40 | XCTAssertTrue(seventh.withoutWhiteSpaces().isPalindromeUsingStack()) 41 | } 42 | 43 | func testIsPalindromeUsingLinkedList() { 44 | XCTAssertTrue(first.withoutWhiteSpaces().isPalindromeUsingLinkedList()) 45 | XCTAssertTrue(second.withoutWhiteSpaces().isPalindromeUsingLinkedList()) 46 | XCTAssertTrue(third.withoutWhiteSpaces().isPalindromeUsingLinkedList()) 47 | XCTAssertTrue(fourth.withoutWhiteSpaces().isPalindromeUsingLinkedList()) 48 | XCTAssertFalse(fifth.withoutWhiteSpaces().isPalindromeUsingLinkedList()) 49 | XCTAssertFalse(sixth.withoutWhiteSpaces().isPalindromeUsingLinkedList()) 50 | XCTAssertTrue(seventh.withoutWhiteSpaces().isPalindromeUsingLinkedList()) 51 | } 52 | 53 | func testIsPalindromeUsingArrayDeque() { 54 | XCTAssertFalse(first.withoutWhiteSpaces().isPalindromeUsingArrayDeque()) 55 | XCTAssertFalse(second.withoutWhiteSpaces().isPalindromeUsingArrayDeque()) 56 | XCTAssertFalse(third.withoutWhiteSpaces().isPalindromeUsingArrayDeque()) 57 | XCTAssertFalse(fourth.withoutWhiteSpaces().isPalindromeUsingArrayDeque()) 58 | XCTAssertFalse(fifth.withoutWhiteSpaces().isPalindromeUsingArrayDeque()) 59 | XCTAssertFalse(sixth.withoutWhiteSpaces().isPalindromeUsingArrayDeque()) 60 | XCTAssertFalse(seventh.withoutWhiteSpaces().isPalindromeUsingArrayDeque()) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Algorithms/StringSearching/Sources/StringSearching/BoyerMoore.swift: -------------------------------------------------------------------------------- 1 | private func badCharacterRuleTableForPattern(pattern: String) -> [Character: Int] { 2 | var table = [Character: Int]() 3 | let lastCharacterIndex = pattern.count - 1 4 | for (index, character) in pattern.enumerated() { 5 | table[character] = lastCharacterIndex - index 6 | } 7 | return table 8 | } 9 | 10 | private func goodSuffixRuleTableForPattern(pattern: String) -> [Character: Int] { 11 | // TODO: Implement 12 | return [Character: Int]() 13 | } 14 | 15 | public struct BoyerMoorePattern { 16 | public let string: String 17 | internal let characterCount: Int 18 | private let badCharacterRuleTable: [Character: Int] 19 | private let goodSuffixRuleTable: [Character: Int] 20 | 21 | public init(string: String) { 22 | self.string = string 23 | self.characterCount = string.count 24 | self.badCharacterRuleTable = badCharacterRuleTableForPattern(pattern: string) 25 | self.goodSuffixRuleTable = goodSuffixRuleTableForPattern(pattern: string) 26 | } 27 | 28 | internal func badCharacterRuleShift(character: Character) -> Int { 29 | if let index = self.badCharacterRuleTable[character] { 30 | return index 31 | } 32 | return self.characterCount 33 | } 34 | 35 | internal func goodSuffixRuleShift(character: Character) -> Int { 36 | // TODO: Implement 37 | return 0 38 | } 39 | } 40 | 41 | public func boyerMooreStringSearch(pattern: BoyerMoorePattern, document: String) -> [Range] { 42 | if pattern.string.count < 1 || document.count < 1 { 43 | return [] 44 | } 45 | 46 | if pattern.string.count > document.count { 47 | return [] 48 | } 49 | 50 | var ranges = [Range]() 51 | var currentDocumentIndex = document.startIndex 52 | let patternCharacterCount = pattern.characterCount 53 | let endIndex = document.index(document.endIndex, offsetBy: -patternCharacterCount) 54 | 55 | while true { 56 | var shift = 1 57 | var match = true 58 | 59 | // TODO: All this `index(_:,offsetBy:)` and `distance(from:to:)` is super inefficient, tune. 60 | for index in stride(from: patternCharacterCount - 1, to: 0, by: -1) { 61 | let documentIndex = document.index(currentDocumentIndex, offsetBy: index) 62 | let patternIndex = pattern.string.index(pattern.string.startIndex, offsetBy: index) 63 | 64 | let documentCharacter = document[documentIndex] 65 | let patternCharacter = pattern.string[patternIndex] 66 | 67 | if documentCharacter != patternCharacter { 68 | let badCharacterShift = pattern.badCharacterRuleShift(character: documentCharacter) 69 | shift = max(badCharacterShift, shift) 70 | match = false 71 | break 72 | } 73 | } 74 | 75 | if match == true { 76 | let start = document.distance(from: document.startIndex, to: currentDocumentIndex) 77 | let end = document.distance(from: document.startIndex, to: document.index(currentDocumentIndex, offsetBy: patternCharacterCount)) 78 | let range = start.. String { 6 | return self.lazy.filter { $0 != " " }.reduce("") { $0 + String($1) } 7 | } 8 | 9 | public func isPalindrome() -> Bool { 10 | return isPalindromeUsingIteration() 11 | } 12 | 13 | public func isPalindromeUsingIteration() -> Bool { 14 | if isEmptyOrSingleCharacter() { 15 | return true 16 | } 17 | 18 | let characters = Array(self) 19 | var leftIndex = 0 20 | var rightIndex = characters.count - 1 21 | while leftIndex < rightIndex { 22 | if characters[leftIndex] != characters[rightIndex] { 23 | return false 24 | } 25 | leftIndex += 1 26 | rightIndex -= 1 27 | } 28 | return true 29 | } 30 | 31 | public func isPalindromeUsingRecursion() -> Bool { 32 | if isEmptyOrSingleCharacter() { 33 | return true 34 | } 35 | 36 | let length = self.count 37 | let firstCharacter = self[self.index(self.startIndex, offsetBy: 0)] 38 | let lastCharacter = self[self.index(self.startIndex, offsetBy: length - 1)] 39 | let matchingEnds = firstCharacter == lastCharacter 40 | if matchingEnds && length == 2 { 41 | return true 42 | } else if matchingEnds { 43 | let secondCharacterStringIndex = self.index(self.startIndex, offsetBy: 1) 44 | let secondToLastCharacterStringIndex = self.index(self.startIndex, offsetBy: length - 2) 45 | let range = secondCharacterStringIndex...secondToLastCharacterStringIndex 46 | let newString = String(self[range]) 47 | 48 | return newString.isPalindromeUsingRecursion() 49 | } 50 | 51 | return false 52 | } 53 | 54 | public func isPalindromeUsingStack() -> Bool { 55 | if isEmptyOrSingleCharacter() { 56 | return true 57 | } 58 | 59 | let characters = Array(self) 60 | var stack = Stack(elements: characters) 61 | 62 | let middleIndex: Int 63 | if characters.count % 2 == 0 { 64 | middleIndex = (characters.count / 2) - 1 65 | } else { 66 | middleIndex = characters.count / 2 67 | } 68 | 69 | var index = 0 70 | while index < characters.count { 71 | if stack.pop() != characters[index] { 72 | return false 73 | } 74 | if index == middleIndex { 75 | return true 76 | } 77 | index += 1 78 | } 79 | 80 | return true 81 | } 82 | 83 | public func isPalindromeUsingLinkedList() -> Bool { 84 | if isEmptyOrSingleCharacter() { 85 | return true 86 | } 87 | 88 | let characters = Array(self) 89 | let linkedList = LinkedList() 90 | 91 | for character in characters { 92 | linkedList.appendValue(character) 93 | } 94 | 95 | while (linkedList.lastNode != nil) { 96 | if linkedList.firstNode?.value != linkedList.lastNode?.value { 97 | return false 98 | } 99 | _ = linkedList.detachFirstValue() 100 | _ = linkedList.detachLastValue() 101 | } 102 | 103 | return true 104 | } 105 | 106 | public func isPalindromeUsingArrayDeque() -> Bool { 107 | // TODO: Implement. 108 | // 1. Fill up the deque. 109 | // 2. Grab (remove) and compare first and last values. 110 | return false 111 | } 112 | 113 | // MARK: Private 114 | 115 | private func isEmptyOrSingleCharacter() -> Bool { 116 | return self.isEmpty || self.count == 1 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /DataStructures/LinkedList/Sources/LinkedList/LinkedList.swift: -------------------------------------------------------------------------------- 1 | public class LinkedList: CustomStringConvertible, CustomDebugStringConvertible { 2 | public var firstNode: LinkedListNode? 3 | public var lastNode: LinkedListNode? 4 | 5 | public init() { 6 | } 7 | 8 | // MARK: Public Methods 9 | 10 | public func appendValue(_ value: T) { 11 | let newNode = LinkedListNode(value: value) 12 | newNode.previousNode = self.lastNode 13 | self.lastNode?.nextNode = newNode 14 | self.lastNode = newNode 15 | if self.firstNode == nil { 16 | self.firstNode = newNode 17 | } 18 | } 19 | 20 | public func prependValue(_ value: T) { 21 | let newNode = LinkedListNode(value: value) 22 | newNode.nextNode = self.firstNode 23 | self.firstNode?.previousNode = newNode 24 | self.firstNode = newNode 25 | if self.lastNode == nil { 26 | self.lastNode = newNode 27 | } 28 | } 29 | 30 | public func detachFirstValue() -> T? { 31 | let oldFirstNode = self.firstNode 32 | 33 | if let newFirstNode = oldFirstNode?.nextNode { 34 | self.firstNode = newFirstNode 35 | self.firstNode?.previousNode = nil 36 | } else { 37 | self.firstNode = nil 38 | self.lastNode = nil 39 | } 40 | 41 | oldFirstNode?.nextNode = nil 42 | return oldFirstNode?.value 43 | } 44 | 45 | public func detachLastValue() -> T? { 46 | let oldLastNode = self.lastNode 47 | 48 | if let newLastNode = oldLastNode?.previousNode { 49 | self.lastNode = newLastNode 50 | self.lastNode?.nextNode = nil 51 | } else { 52 | self.firstNode = nil 53 | self.lastNode = nil 54 | } 55 | 56 | oldLastNode?.previousNode = nil 57 | return oldLastNode?.value 58 | } 59 | 60 | public func deleteDuplicates() { 61 | deleteDuplicatesWithLinearTime() 62 | } 63 | 64 | public func deleteDuplicatesWithConstantMemory() { 65 | var current: LinkedListNode? = self.firstNode 66 | while current != nil { 67 | var temp: LinkedListNode? = current?.nextNode 68 | while temp != nil { 69 | if (current?.value == temp?.value) { 70 | if temp === self.lastNode { 71 | self.lastNode = temp?.previousNode 72 | self.lastNode?.previousNode = temp?.previousNode?.previousNode 73 | } 74 | temp?.previousNode?.nextNode = temp?.nextNode 75 | temp?.nextNode?.previousNode = temp?.previousNode 76 | temp?.nextNode = nil 77 | temp?.previousNode = nil 78 | temp = temp?.previousNode?.nextNode 79 | } else { 80 | temp = temp?.nextNode 81 | } 82 | } 83 | current = current?.nextNode 84 | } 85 | } 86 | 87 | public func deleteDuplicatesWithLinearTime() { 88 | var current: LinkedListNode? = self.firstNode 89 | var previous: LinkedListNode? 90 | var set = Set() 91 | while current != nil { 92 | if set.contains(current!.value) { 93 | if current === self.lastNode { 94 | self.lastNode = current?.previousNode 95 | self.lastNode?.previousNode = current?.previousNode?.previousNode 96 | } 97 | previous?.nextNode = current?.nextNode 98 | previous?.nextNode?.previousNode = previous 99 | } else { 100 | set.insert(current!.value) 101 | previous = current 102 | } 103 | current = current?.nextNode 104 | } 105 | } 106 | 107 | // MARK: CustomStringConvertible 108 | 109 | public var description: String { 110 | if let firstNode = self.firstNode { 111 | return firstNode.description 112 | } 113 | return "" 114 | } 115 | 116 | // MARK: CustomDebugStringConvertible 117 | 118 | public var debugDescription: String { 119 | if let firstNode = self.firstNode { 120 | return firstNode.debugDescription 121 | } 122 | return "" 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /DataStructures/Heap/Sources/Heap/Heap.swift: -------------------------------------------------------------------------------- 1 | import PriorityQueue 2 | 3 | public struct Heap: PriorityQueue { 4 | public typealias Element = T 5 | private let leftIsHigherPriority: (T, T) -> Bool 6 | private var storage = [T]() 7 | 8 | public init(leftIsHigherPriority: @escaping (T, T) -> Bool) { 9 | self.leftIsHigherPriority = leftIsHigherPriority 10 | } 11 | 12 | public func isEmpty() -> Bool { 13 | return storage.isEmpty 14 | } 15 | 16 | public func count() -> Int { 17 | return storage.count 18 | } 19 | 20 | public func peek() -> T? { 21 | return storage.first 22 | } 23 | 24 | public mutating func insert(element: T) { 25 | storage.append(element) 26 | updateStorageTreeViaInsert() 27 | } 28 | 29 | private mutating func updateStorageTreeViaInsert() { 30 | // Take the rightmost leaf (last element). 31 | let rightmostLeaf = storage.last! 32 | var currentIndex = storage.count - 1 33 | 34 | // Navigate up the tree and swap it with elements of lower priority. 35 | while currentIndex > 0 { 36 | // Obtain index of parent. 37 | let parentIndex: Int 38 | if currentIndex == 1 { 39 | parentIndex = 0 40 | } else { 41 | parentIndex = ((currentIndex + 1) / 2) - 1 42 | } 43 | 44 | // Compare with parent. 45 | let parent = storage[parentIndex] 46 | if leftIsHigherPriority(rightmostLeaf, parent) { 47 | storage[currentIndex] = parent 48 | storage[parentIndex] = rightmostLeaf 49 | currentIndex = parentIndex 50 | continue 51 | } 52 | 53 | // Lower priority than parent. We’re done. 54 | break 55 | } 56 | } 57 | 58 | public mutating func remove() -> T? { 59 | if storage.isEmpty { 60 | return nil 61 | } 62 | let root = storage[0] 63 | updateStorageTreeViaRemove() 64 | return root 65 | } 66 | 67 | private mutating func updateStorageTreeViaRemove() { 68 | // Take the rightmost leaf (last element) and set it as the new root. 69 | let rightmostLeaf = storage.last! 70 | var currentIndex = 0 71 | storage[currentIndex] = rightmostLeaf 72 | storage.removeLast() 73 | 74 | // Navigate down the tree and swap it with elements of higher priority. 75 | while true { 76 | let rightChildIndex = (currentIndex + 1) * 2 77 | let leftChildIndex = rightChildIndex - 1 78 | 79 | if rightChildIndex < storage.count && leftChildIndex < storage.count { 80 | // Have both children, obtain the one with higher priority. 81 | let rightChild = storage[rightChildIndex] 82 | let leftChild = storage[leftChildIndex] 83 | let child: T 84 | let childIndex: Int 85 | if leftIsHigherPriority(leftChild, rightChild) { 86 | child = leftChild 87 | childIndex = leftChildIndex 88 | } else { 89 | child = rightChild 90 | childIndex = rightChildIndex 91 | } 92 | 93 | // Compare original rightmost leaf with higher priority child. 94 | if !leftIsHigherPriority(rightmostLeaf, child) { 95 | storage[currentIndex] = child 96 | storage[childIndex] = rightmostLeaf 97 | currentIndex = childIndex 98 | continue 99 | } 100 | } else if rightChildIndex < storage.count { 101 | // Compare original rightmost leaf with right child. 102 | let rightChild = storage[rightChildIndex] 103 | if !leftIsHigherPriority(rightmostLeaf, rightChild) { 104 | storage[currentIndex] = rightChild 105 | storage[rightChildIndex] = rightmostLeaf 106 | currentIndex = rightChildIndex 107 | continue 108 | } 109 | } else if leftChildIndex < storage.count { 110 | // Compare original rightmost leaf with left child. 111 | let leftChild = storage[leftChildIndex] 112 | if !leftIsHigherPriority(rightmostLeaf, leftChild) { 113 | storage[currentIndex] = leftChild 114 | storage[leftChildIndex] = rightmostLeaf 115 | currentIndex = leftChildIndex 116 | continue 117 | } 118 | } 119 | 120 | // Higher priority than both, or no children. We’re done. 121 | break 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Problems/AnagramFinder/AnagramFinder/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AnagramFinder 4 | // 5 | // Created by Rogelio Gudino on 2/14/15. 6 | // Copyright (c) 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate, NSTableViewDataSource, NSTableViewDelegate { 13 | @IBOutlet weak var window: NSWindow! 14 | @IBOutlet weak var progressIndicator: NSProgressIndicator! 15 | @IBOutlet weak var populateWithEnglishDictionaryButton: NSButton! 16 | @IBOutlet weak var textScrollView: NSScrollView! 17 | @IBOutlet weak var findAnagramsButton: NSButton! 18 | @IBOutlet weak var anagramsTableViewScrollContainer: NSScrollView! 19 | @IBOutlet weak var anagramsTableView: NSTableView! 20 | private var textView: NSTextView! { 21 | get { 22 | return self.textScrollView.contentView.documentView as! NSTextView 23 | } 24 | } 25 | 26 | private var anagramCluster = [String: [String]]() 27 | private var sortedAnagramClusterKeys = [String]() 28 | private let privateQueue = DispatchQueue(label: "com.cananito.private-queue") 29 | 30 | // MARK: NSApplicationDelegate 31 | func applicationDidFinishLaunching(_ aNotification: Notification) { 32 | } 33 | 34 | // MARK: NSWindowDelegate 35 | func windowDidBecomeKey(_ notification: Notification) { 36 | } 37 | 38 | // MARK: NSTableViewDataSource Methods 39 | func numberOfRows(in tableView: NSTableView) -> Int { 40 | return self.sortedAnagramClusterKeys.count 41 | } 42 | 43 | // MARK: NSTableViewDelegate Methods 44 | func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { 45 | let key = self.sortedAnagramClusterKeys[row] 46 | 47 | var numberOfOccurrences = 0 48 | if let words = self.anagramCluster[key] { 49 | numberOfOccurrences = words.count 50 | } 51 | 52 | let tableCellView = tableView.make(withIdentifier: "AnagramCell", owner: self) as? NSTableCellView 53 | tableCellView?.textField?.stringValue = "\(key): \(numberOfOccurrences)" 54 | 55 | return tableCellView 56 | } 57 | 58 | func tableView(_ tableView: NSTableView, selectionIndexesForProposedSelection proposedSelectionIndexes: IndexSet) -> IndexSet { 59 | return IndexSet() 60 | } 61 | 62 | // MARK: Action Methods 63 | @IBAction func findAnagrams(_ sender: AnyObject!) { 64 | if let string = self.textView.string as String? { 65 | self.showLoadingUI() 66 | 67 | self.privateQueue.async { 68 | let words = string.characters.split(whereSeparator: { $0 == "\n" }).map { String($0) } 69 | self.anagramCluster = clusterArrayOfWords(words) 70 | self.sortedAnagramClusterKeys = self.anagramCluster.keys.sorted() 71 | 72 | DispatchQueue.main.async { 73 | self.hideLoadingUI() 74 | self.anagramsTableView.reloadData() 75 | } 76 | } 77 | } 78 | } 79 | 80 | @IBAction func populateWithEnglishDictionary(_ sender: AnyObject!) { 81 | self.showLoadingUI() 82 | self.privateQueue.async { 83 | let wordsPath = "/bin/cat" 84 | let wordsString = outputStringFromLaunchPath(wordsPath, arguments: ["/usr/share/dict/words"]) 85 | DispatchQueue.main.async { 86 | self.hideLoadingUI() 87 | self.textView.string = wordsString 88 | } 89 | } 90 | } 91 | 92 | // MARK: Private Methods 93 | private func showLoadingUI() { 94 | self.populateWithEnglishDictionaryButton.isEnabled = false 95 | self.findAnagramsButton.isEnabled = false 96 | 97 | self.textView.isSelectable = false 98 | self.textView.isEditable = false 99 | self.textView.alphaValue = 0.25 100 | 101 | self.anagramsTableView.isEnabled = false 102 | self.anagramsTableView.alphaValue = 0.25 103 | 104 | self.progressIndicator.startAnimation(self) 105 | } 106 | 107 | private func hideLoadingUI() { 108 | self.populateWithEnglishDictionaryButton.isEnabled = true 109 | self.findAnagramsButton.isEnabled = true 110 | 111 | self.textView.isSelectable = true 112 | self.textView.isEditable = true 113 | self.textView.alphaValue = 1.0 114 | 115 | self.anagramsTableView.isEnabled = true 116 | self.anagramsTableView.alphaValue = 1.0 117 | 118 | self.progressIndicator.stopAnimation(self) 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoi/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // TowerOfHanoi 4 | // 5 | // Created by Rogelio Gudino on 2/8/15. 6 | // Copyright (c) 2015 Rogelio Gudino. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | @IBOutlet weak var window: NSWindow! 14 | @IBOutlet weak var drawingView: DrawingView! 15 | @IBOutlet weak var actionButton: NSButton! 16 | private let originalDisksArray: [Disk] 17 | private let backgroundOperationQueue: OperationQueue 18 | 19 | override init() { 20 | var disks = [Disk]() 21 | for i in 1 ..< 6 { 22 | let disk = Disk(identifier: i) 23 | disks.append(disk) 24 | } 25 | self.originalDisksArray = disks.reversed() 26 | self.backgroundOperationQueue = OperationQueue() 27 | } 28 | 29 | func applicationDidFinishLaunching(_ aNotification: Notification) { 30 | self.resetTower() 31 | } 32 | 33 | @IBAction func buttonWasClicked(_ sender: AnyObject!) { 34 | guard let cell: NSCell = sender.selectedCell() else { return } 35 | if cell.title == "Solve" { 36 | cell.title = "Finish" 37 | self.resetTower() 38 | self.solveTower(animated: true) 39 | } else if cell.title == "Finish" { 40 | self.backgroundOperationQueue.cancelAllOperations() 41 | self.resetTower() 42 | self.solveTower(animated: false) 43 | } 44 | } 45 | 46 | private func resetTower() { 47 | var towerOfHanoi = TowerOfHanoi() 48 | towerOfHanoi.sourcePole = self.originalDisksArray 49 | self.drawingView.towerOfHanoi = towerOfHanoi 50 | } 51 | 52 | private func solveTower(animated: Bool) { 53 | var newTowerOfHanoi = self.drawingView.towerOfHanoi 54 | 55 | if animated { 56 | self.backgroundOperationQueue.addOperation({ 57 | Thread.sleep(forTimeInterval: 0.4) 58 | self.moveAnimatedTower(tower: &newTowerOfHanoi, numberOfDisks: newTowerOfHanoi.sourcePole.count, sourcePole: &newTowerOfHanoi.sourcePole, destinationPole: &newTowerOfHanoi.destinationPole, temporaryPole: &newTowerOfHanoi.temporaryPole) 59 | self.actionButton.title = "Solve" 60 | }) 61 | } else { 62 | self.moveTower(tower: &newTowerOfHanoi, numberOfDisks: newTowerOfHanoi.sourcePole.count, sourcePole: &newTowerOfHanoi.sourcePole, destinationPole: &newTowerOfHanoi.destinationPole, temporaryPole: &newTowerOfHanoi.temporaryPole) 63 | self.drawingView.towerOfHanoi = newTowerOfHanoi 64 | self.actionButton.title = "Solve" 65 | } 66 | } 67 | 68 | private func moveSingleDisk(sourcePole: inout [Disk], destinationPole: inout [Disk]) { 69 | let disk = sourcePole.remove(at: 0) 70 | destinationPole.insert(disk, at: 0) 71 | } 72 | 73 | private func moveAnimatedTower(tower: inout TowerOfHanoi, numberOfDisks: Int, sourcePole: inout [Disk], destinationPole: inout [Disk], temporaryPole: inout [Disk]) { 74 | if (numberOfDisks > 0) { 75 | self.moveAnimatedTower(tower: &tower, numberOfDisks: numberOfDisks - 1, sourcePole: &sourcePole, destinationPole: &temporaryPole, temporaryPole: &destinationPole) 76 | self.moveSingleDisk(sourcePole: &sourcePole, destinationPole: &destinationPole) 77 | 78 | if self.isCurrentOperationCancelled() { 79 | return 80 | } 81 | self.drawingView.towerOfHanoi = tower 82 | Thread.sleep(forTimeInterval: 0.5) 83 | 84 | self.moveAnimatedTower(tower: &tower, numberOfDisks: numberOfDisks - 1, sourcePole: &temporaryPole, destinationPole: &destinationPole, temporaryPole: &sourcePole) 85 | } 86 | } 87 | 88 | private func moveTower(tower: inout TowerOfHanoi, numberOfDisks: Int, sourcePole: inout [Disk], destinationPole: inout [Disk], temporaryPole: inout [Disk]) { 89 | if (numberOfDisks > 0) { 90 | self.moveTower(tower: &tower, numberOfDisks: numberOfDisks - 1, sourcePole: &sourcePole, destinationPole: &temporaryPole, temporaryPole: &destinationPole) 91 | self.moveSingleDisk(sourcePole: &sourcePole, destinationPole: &destinationPole) 92 | self.moveTower(tower: &tower, numberOfDisks: numberOfDisks - 1, sourcePole: &temporaryPole, destinationPole: &destinationPole, temporaryPole: &sourcePole) 93 | } 94 | } 95 | 96 | private func isCurrentOperationCancelled() -> Bool { 97 | if let currentQueue = OperationQueue.current { 98 | if currentQueue.operationCount > 0 { 99 | let operation: Operation = currentQueue.operations[0] as Operation 100 | return operation.isCancelled 101 | } 102 | } 103 | 104 | return false 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /DataStructures/LinkedList/Tests/LinkedListTests/LinkedListTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import LinkedList 3 | 4 | class LinkedListTests: XCTestCase { 5 | func testEmptyLinkedListDescription() { 6 | let emptyLinkedList = LinkedList() 7 | XCTAssert(emptyLinkedList.firstNode == nil, "An empty list’s firstNode should nil") 8 | XCTAssert(emptyLinkedList.lastNode == nil, "An empty list’s lastNode should nil") 9 | } 10 | 11 | func testPrependingValues() { 12 | let linkedList = LinkedList() 13 | linkedList.prependValue(3) 14 | linkedList.prependValue(2) 15 | linkedList.prependValue(1) 16 | XCTAssert(linkedList.description == "1 -> 2 -> 3", "List with 3 prepended values should print them in reverse order") 17 | 18 | var node = linkedList.firstNode 19 | XCTAssert(node?.value == 1, "firstNode should be 1") 20 | 21 | node = node?.nextNode 22 | XCTAssert(node?.value == 2, "firstNode should be 2") 23 | 24 | node = node?.nextNode 25 | XCTAssert(node?.value == 3, "firstNode should be 3") 26 | 27 | XCTAssert(linkedList.lastNode?.value == 3, "lastNode should be 3") 28 | } 29 | 30 | func testAppendingValues() { 31 | let linkedList = LinkedList() 32 | linkedList.appendValue(3) 33 | linkedList.appendValue(2) 34 | linkedList.appendValue(1) 35 | XCTAssert(linkedList.description == "3 -> 2 -> 1", "List with 3 appended values should print them in order") 36 | 37 | var node = linkedList.firstNode 38 | XCTAssert(node?.value == 3, "firstNode should be 3") 39 | 40 | node = node?.nextNode 41 | XCTAssert(node?.value == 2, "firstNode should be 2") 42 | 43 | node = node?.nextNode 44 | XCTAssert(node?.value == 1, "firstNode should be 1") 45 | 46 | XCTAssert(linkedList.lastNode?.value == 1, "lastNode should be 1") 47 | } 48 | 49 | func testDetachingFirstValues() { 50 | let linkedList = LinkedList() 51 | linkedList.prependValue(3) 52 | linkedList.prependValue(2) 53 | linkedList.prependValue(1) 54 | 55 | XCTAssert(linkedList.detachFirstValue() == 1, "First detached value should be 1") 56 | XCTAssert(linkedList.detachFirstValue() == 2, "Second detached value should be 2") 57 | XCTAssert(linkedList.detachFirstValue() == 3, "Third detached value should be 3") 58 | XCTAssert(linkedList.detachFirstValue() == nil, "Fourth detached value should be nil") 59 | } 60 | 61 | func testDetachingLastValues() { 62 | let linkedList = LinkedList() 63 | linkedList.appendValue(3) 64 | linkedList.appendValue(2) 65 | linkedList.appendValue(1) 66 | 67 | XCTAssert(linkedList.detachLastValue() == 1, "First detached value should be 1") 68 | XCTAssert(linkedList.detachLastValue() == 2, "Second detached value should be 2") 69 | XCTAssert(linkedList.detachLastValue() == 3, "Third detached value should be 3") 70 | XCTAssert(linkedList.detachLastValue() == nil, "Fourth detached value should be nil") 71 | } 72 | 73 | func testDeleteDuplicatesWithConstantMemory() { 74 | let linkedList = LinkedList() 75 | linkedList.appendValue(3) 76 | linkedList.appendValue(4) 77 | linkedList.appendValue(3) 78 | linkedList.appendValue(1) 79 | linkedList.appendValue(4) 80 | linkedList.appendValue(2) 81 | linkedList.appendValue(2) 82 | linkedList.deleteDuplicatesWithConstantMemory() 83 | 84 | XCTAssert(linkedList.detachLastValue() == 2, "First detached value should be 2") 85 | XCTAssert(linkedList.detachLastValue() == 1, "Second detached value should be 1") 86 | XCTAssert(linkedList.detachLastValue() == 4, "Third detached value should be 4") 87 | XCTAssert(linkedList.detachLastValue() == 3, "Fourth detached value should be 3") 88 | XCTAssert(linkedList.detachLastValue() == nil, "Fifth detached value should be nil") 89 | } 90 | 91 | func testDeleteDuplicatesWithLinearTime() { 92 | let linkedList = LinkedList() 93 | linkedList.appendValue(3) 94 | linkedList.appendValue(4) 95 | linkedList.appendValue(3) 96 | linkedList.appendValue(1) 97 | linkedList.appendValue(4) 98 | linkedList.appendValue(2) 99 | linkedList.appendValue(2) 100 | linkedList.deleteDuplicatesWithLinearTime() 101 | 102 | XCTAssert(linkedList.detachLastValue() == 2, "First detached value should be 2") 103 | XCTAssert(linkedList.detachLastValue() == 1, "Second detached value should be 1") 104 | XCTAssert(linkedList.detachLastValue() == 4, "Third detached value should be 4") 105 | XCTAssert(linkedList.detachLastValue() == 3, "Fourth detached value should be 3") 106 | XCTAssert(linkedList.detachLastValue() == nil, "Fifth detached value should be nil") 107 | } 108 | 109 | static var allTests = [ 110 | ("testEmptyLinkedListDescription", testEmptyLinkedListDescription), 111 | ("testPrependingValues", testPrependingValues), 112 | ("testAppendingValues", testAppendingValues), 113 | ("testDetachingFirstValues", testDetachingFirstValues), 114 | ("testDetachingLastValues", testDetachingLastValues), 115 | ("testDeleteDuplicatesWithConstantMemory", testDeleteDuplicatesWithConstantMemory), 116 | ("testDeleteDuplicatesWithLinearTime", testDeleteDuplicatesWithLinearTime), 117 | ] 118 | } 119 | -------------------------------------------------------------------------------- /Problems/TowerOfHanoi/TowerOfHanoi/DrawingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DrawingView.swift 3 | // SwiftTowerOfHanoi 4 | // 5 | // Created by Rogelio Gudino on 8/3/14. 6 | // Copyright (c) 2014 Cananito. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class DrawingView: NSView { 12 | private var firstPoleRect: NSRect 13 | private var secondPoleRect: NSRect 14 | private var thirdPoleRect: NSRect 15 | private var diskWidths: [CGFloat] 16 | var towerOfHanoi: TowerOfHanoi = TowerOfHanoi() { 17 | didSet { 18 | self.display() 19 | } 20 | } 21 | 22 | override init(frame frameRect: NSRect) { 23 | self.firstPoleRect = NSRect() 24 | self.secondPoleRect = NSRect() 25 | self.thirdPoleRect = NSRect() 26 | self.diskWidths = [CGFloat]() 27 | super.init(frame: frameRect) 28 | } 29 | 30 | required init?(coder: NSCoder) { 31 | self.firstPoleRect = NSRect() 32 | self.secondPoleRect = NSRect() 33 | self.thirdPoleRect = NSRect() 34 | self.diskWidths = [CGFloat]() 35 | super.init(coder: coder) 36 | } 37 | 38 | override func draw(_ dirtyRect: NSRect) { 39 | self.drawPoles(dirtyRect) 40 | self.drawDisks() 41 | } 42 | 43 | private func drawPoles(_ rect: NSRect) { 44 | let combinedPolesWidth = rect.size.width / 2 45 | let poleWidth = combinedPolesWidth / 3 46 | var poleRect = NSRect(x: 0, y: rect.origin.y, width: poleWidth, height: rect.size.height) 47 | 48 | poleRect.origin.x = poleWidth / 2.0 49 | self.firstPoleRect = poleRect 50 | poleRect.origin.x = self.firstPoleRect.maxX + poleWidth 51 | self.secondPoleRect = poleRect 52 | poleRect.origin.x = self.secondPoleRect.maxX + poleWidth; 53 | self.thirdPoleRect = poleRect 54 | 55 | self.populateDiskWidths() 56 | 57 | self.drawPole(self.firstPoleRect) 58 | self.drawPole(self.secondPoleRect) 59 | self.drawPole(self.thirdPoleRect) 60 | } 61 | 62 | private func populateDiskWidths() { 63 | self.diskWidths.removeAll(keepingCapacity: true) 64 | 65 | if self.towerOfHanoi.totalDiskCount() == 0 { 66 | return 67 | } 68 | 69 | let smallestDiskWidth = self.firstPoleRect.size.width * 0.10 70 | let diskWidthDecrements = (self.firstPoleRect.size.width - smallestDiskWidth) / CGFloat(self.towerOfHanoi.totalDiskCount()) 71 | var currentWidth = self.firstPoleRect.size.width 72 | 73 | for _ in 0 ..< self.towerOfHanoi.totalDiskCount() { 74 | self.diskWidths.append(currentWidth) 75 | currentWidth -= diskWidthDecrements 76 | } 77 | } 78 | 79 | private func drawPole(_ rect: NSRect) { 80 | let poleBaseHeight = rect.size.height * 0.05 81 | let poleBaseRect = NSRect(x: rect.origin.x, y: rect.origin.y, width: rect.size.width, height: poleBaseHeight) 82 | self.drawSquare(poleBaseRect, withFillColor: NSColor.black, andStrokeColor: NSColor.clear) 83 | 84 | let polePoleWidth = rect.size.width * 0.10 85 | let polePoleHieght = rect.size.height - poleBaseHeight 86 | let polePoleX = rect.origin.x + (rect.size.width / 2) - (polePoleWidth / 2) 87 | let polePoleRect = NSRect(x: polePoleX, y: rect.origin.y, width: polePoleWidth, height: polePoleHieght) 88 | self.drawSquare(polePoleRect, withFillColor: NSColor.black, andStrokeColor: NSColor.clear) 89 | } 90 | 91 | private func drawDisks() { 92 | if self.towerOfHanoi.totalDiskCount() == 0 { 93 | return 94 | } 95 | 96 | let reverseFirstPoleDisks = self.towerOfHanoi.sourcePole.reversed() 97 | let reverseSecondPoleDisks = self.towerOfHanoi.destinationPole.reversed() 98 | let reverseThirdPoleDisks = self.towerOfHanoi.temporaryPole.reversed() 99 | 100 | self.drawPoleDisks(disks: reverseFirstPoleDisks, forPoleRect: self.firstPoleRect) 101 | self.drawPoleDisks(disks: reverseSecondPoleDisks, forPoleRect: self.secondPoleRect) 102 | self.drawPoleDisks(disks: reverseThirdPoleDisks, forPoleRect: self.thirdPoleRect) 103 | } 104 | 105 | private func drawPoleDisks(disks: S, forPoleRect poleRect: NSRect) where S.Iterator.Element == Disk { 106 | let diskHeight = poleRect.size.height * 0.05 107 | let diskVerticalPadding: CGFloat = 2.0 108 | var currentY = poleRect.origin.y + diskHeight + diskVerticalPadding 109 | 110 | for disk in disks { 111 | let currentWidth = self.diskWidths[disk.identifier - 1] 112 | let diskX = poleRect.origin.x + (poleRect.size.width / 2) - (currentWidth / 2) 113 | let diskRect = NSRect(x: diskX, y: currentY, width: currentWidth, height: diskHeight) 114 | self.drawSquare(diskRect, withFillColor: NSColor.red, andStrokeColor: NSColor.black) 115 | currentY += diskHeight + diskVerticalPadding 116 | 117 | } 118 | } 119 | 120 | private func drawSquare(_ rect: NSRect, withFillColor fillColor: NSColor, andStrokeColor strokeColor: NSColor) { 121 | let squarePath: NSBezierPath = NSBezierPath(rect: rect) 122 | squarePath.lineWidth = 1.0 123 | fillColor.set() 124 | squarePath.fill() 125 | strokeColor.set() 126 | squarePath.stroke() 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /DataStructures/BinaryTree/Tests/BinaryTreeTests/BinaryTreeTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import BinaryTree 3 | 4 | class BinaryTreeTests: XCTestCase { 5 | let node2 = BinaryTreeNode(value: 2) 6 | let node1 = BinaryTreeNode(value: 1) 7 | let node3 = BinaryTreeNode(value: 3) 8 | let node4 = BinaryTreeNode(value: 4) 9 | let node5 = BinaryTreeNode(value: 5) 10 | let node6 = BinaryTreeNode(value: 6) 11 | let node7 = BinaryTreeNode(value: 7) 12 | let node8 = BinaryTreeNode(value: 8) 13 | let node9 = BinaryTreeNode(value: 9) 14 | let node10 = BinaryTreeNode(value: 10) 15 | let node11 = BinaryTreeNode(value: 11) 16 | let node12 = BinaryTreeNode(value: 12) 17 | let node13 = BinaryTreeNode(value: 13) 18 | let node14 = BinaryTreeNode(value: 14) 19 | let node15 = BinaryTreeNode(value: 15) 20 | let node16 = BinaryTreeNode(value: 16) // Root node 21 | let node17 = BinaryTreeNode(value: 17) 22 | let node18 = BinaryTreeNode(value: 18) 23 | let node19 = BinaryTreeNode(value: 19) 24 | let node20 = BinaryTreeNode(value: 20) 25 | let node21 = BinaryTreeNode(value: 21) 26 | 27 | override func setUp() { 28 | self.node2.leftNode = self.node1 29 | self.node1.parentNode = self.node2 30 | 31 | self.node3.leftNode = self.node2 32 | self.node2.parentNode = self.node3 33 | 34 | self.node16.leftNode = self.node3 35 | self.node3.parentNode = self.node16 36 | 37 | self.node5.leftNode = self.node4 38 | self.node4.parentNode = self.node5 39 | 40 | self.node7.leftNode = self.node5 41 | self.node5.parentNode = self.node7 42 | 43 | self.node5.rightNode = self.node6 44 | self.node6.parentNode = self.node5 45 | 46 | self.node12.leftNode = self.node7 47 | self.node7.parentNode = self.node12 48 | 49 | self.node7.rightNode = self.node8 50 | self.node8.parentNode = self.node7 51 | 52 | self.node10.leftNode = self.node9 53 | self.node9.parentNode = self.node10 54 | 55 | self.node8.rightNode = self.node10 56 | self.node10.parentNode = self.node8 57 | 58 | self.node10.rightNode = self.node11 59 | self.node11.parentNode = self.node10 60 | 61 | self.node3.rightNode = self.node12 62 | self.node12.parentNode = self.node3 63 | 64 | self.node14.leftNode = self.node13 65 | self.node13.parentNode = self.node14 66 | 67 | self.node12.rightNode = self.node14 68 | self.node14.parentNode = self.node12 69 | 70 | self.node14.rightNode = self.node15 71 | self.node15.parentNode = self.node14 72 | 73 | self.node16.rightNode = self.node17 74 | self.node17.parentNode = self.node16 75 | 76 | self.node19.leftNode = self.node18 77 | self.node18.parentNode = self.node19 78 | 79 | self.node17.rightNode = self.node19 80 | self.node19.parentNode = self.node17 81 | 82 | self.node19.rightNode = self.node20 83 | self.node20.parentNode = self.node19 84 | 85 | self.node20.rightNode = self.node21 86 | self.node21.parentNode = self.node20 87 | } 88 | 89 | func testEnumerateInOrder() { 90 | var array = [BinaryTreeNode]() 91 | self.node16.enumerateInOrder { (node) -> () in 92 | array.append(node) 93 | } 94 | XCTAssert(array.description == "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]") 95 | } 96 | 97 | func testEnumeratePreOrder() { 98 | var array = [BinaryTreeNode]() 99 | self.node16.enumeratePreOrder { (node) -> () in 100 | array.append(node) 101 | } 102 | XCTAssert(array.description == "[16, 3, 2, 1, 12, 7, 5, 4, 6, 8, 10, 9, 11, 14, 13, 15, 17, 19, 18, 20, 21]") 103 | } 104 | 105 | func testEnumeratePostOrder() { 106 | var array = [BinaryTreeNode]() 107 | self.node16.enumeratePostOrder { (node) -> () in 108 | array.append(node) 109 | } 110 | XCTAssert(array.description == "[1, 2, 4, 6, 5, 9, 11, 10, 8, 7, 13, 15, 14, 12, 3, 18, 21, 20, 19, 17, 16]") 111 | } 112 | 113 | func testEnumerateBreadthFirst() { 114 | var array = [BinaryTreeNode]() 115 | self.node16.enumerateBreadthFirst { (node) -> () in 116 | array.append(node) 117 | } 118 | XCTAssert(array.description == "[16, 3, 17, 2, 12, 19, 1, 7, 14, 18, 20, 5, 8, 13, 15, 21, 4, 6, 10, 9, 11]") 119 | } 120 | 121 | func testNextNode() { 122 | XCTAssert(node1.next() === node2) 123 | XCTAssert(node2.next() === node3) 124 | XCTAssert(node3.next() === node4) 125 | XCTAssert(node4.next() === node5) 126 | XCTAssert(node5.next() === node6) 127 | XCTAssert(node6.next() === node7) 128 | XCTAssert(node7.next() === node8) 129 | XCTAssert(node8.next() === node9) 130 | XCTAssert(node9.next() === node10) 131 | XCTAssert(node10.next() === node11) 132 | XCTAssert(node11.next() === node12) 133 | XCTAssert(node12.next() === node13) 134 | XCTAssert(node13.next() === node14) 135 | XCTAssert(node14.next() === node15) 136 | XCTAssert(node15.next() === node16) 137 | XCTAssert(node16.next() === node17) 138 | XCTAssert(node17.next() === node18) 139 | XCTAssert(node18.next() === node19) 140 | XCTAssert(node19.next() === node20) 141 | XCTAssert(node20.next() === node21) 142 | } 143 | 144 | static var allTests = [ 145 | ("testEnumerateInOrder", testEnumerateInOrder), 146 | ("testEnumeratePreOrder", testEnumeratePreOrder), 147 | ("testEnumeratePostOrder", testEnumeratePostOrder), 148 | ("testEnumerateBreadthFirst", testEnumerateBreadthFirst), 149 | ] 150 | } 151 | -------------------------------------------------------------------------------- /Problems/Fibonacci/Tests/FibonacciTests/FibonacciTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import Fibonacci 3 | 4 | // 92 is the max position that doesn’t crash on 64-bit. 5 | let meassurePosition = 92 6 | 7 | class FibonacciTests: XCTestCase { 8 | func testIterativeFibonacci() { 9 | XCTAssertEqual(iterativeFibonacci(position: 0), 0) 10 | XCTAssertEqual(iterativeFibonacci(position: 1), 1) 11 | XCTAssertEqual(iterativeFibonacci(position: 2), 1) 12 | XCTAssertEqual(iterativeFibonacci(position: 3), 2) 13 | XCTAssertEqual(iterativeFibonacci(position: 4), 3) 14 | XCTAssertEqual(iterativeFibonacci(position: 5), 5) 15 | XCTAssertEqual(iterativeFibonacci(position: 6), 8) 16 | XCTAssertEqual(iterativeFibonacci(position: 7), 13) 17 | XCTAssertEqual(iterativeFibonacci(position: 8), 21) 18 | XCTAssertEqual(iterativeFibonacci(position: 9), 34) 19 | } 20 | 21 | func testRecursiveFibonacci() { 22 | XCTAssertEqual(recursiveFibonacci(position: 0), 0) 23 | XCTAssertEqual(recursiveFibonacci(position: 1), 1) 24 | XCTAssertEqual(recursiveFibonacci(position: 2), 1) 25 | XCTAssertEqual(recursiveFibonacci(position: 3), 2) 26 | XCTAssertEqual(recursiveFibonacci(position: 4), 3) 27 | XCTAssertEqual(recursiveFibonacci(position: 5), 5) 28 | XCTAssertEqual(recursiveFibonacci(position: 6), 8) 29 | XCTAssertEqual(recursiveFibonacci(position: 7), 13) 30 | XCTAssertEqual(recursiveFibonacci(position: 8), 21) 31 | XCTAssertEqual(recursiveFibonacci(position: 9), 34) 32 | } 33 | 34 | func testMemoizedRecursiveFibonacci() { 35 | var memoization = [Int : Int]() 36 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 0, memoization: &memoization), 0) 37 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 1, memoization: &memoization), 1) 38 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 2, memoization: &memoization), 1) 39 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 3, memoization: &memoization), 2) 40 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 4, memoization: &memoization), 3) 41 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 5, memoization: &memoization), 5) 42 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 6, memoization: &memoization), 8) 43 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 7, memoization: &memoization), 13) 44 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 8, memoization: &memoization), 21) 45 | XCTAssertEqual(memoizedRecursiveFibonacci(position: 9, memoization: &memoization), 34) 46 | } 47 | 48 | func testIterativeFibonacciPerformance() { 49 | // Time: 0.000 sec (25% STDEV) 50 | self.measure { 51 | let _ = iterativeFibonacci(position: meassurePosition) 52 | let _ = iterativeFibonacci(position: meassurePosition) 53 | let _ = iterativeFibonacci(position: meassurePosition) 54 | let _ = iterativeFibonacci(position: meassurePosition) 55 | let _ = iterativeFibonacci(position: meassurePosition) 56 | } 57 | } 58 | 59 | func testRecursiveFibonacciPerformance() { 60 | // Time: 0.011 sec (5% STDEV) (with `position: 30`) 61 | // Time: 0.119 sec (2% STDEV) (with `position: 35`) 62 | self.measure { 63 | // Takes extremely long if meassured with `meassurePosition`. 64 | let _ = recursiveFibonacci(position: 30) 65 | } 66 | } 67 | 68 | func testPopulatedMemoizedRecursiveFibonacciPerformance() { 69 | var memoization = [Int : Int]() 70 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &memoization) 71 | // Time: 0.000 sec (88% STDEV) 72 | self.measure { 73 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &memoization) 74 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &memoization) 75 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &memoization) 76 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &memoization) 77 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &memoization) 78 | } 79 | } 80 | 81 | func testEmptyMemoizedRecursiveFibonacciPerformance() { 82 | var firstMemoization = [Int : Int]() 83 | var secondMemoization = [Int : Int]() 84 | var thirdMemoization = [Int : Int]() 85 | var fourthMemoization = [Int : Int]() 86 | var fifthMemoization = [Int : Int]() 87 | // Time: 0.000 sec (299% STDEV) 88 | self.measure { 89 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &firstMemoization) 90 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &secondMemoization) 91 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &thirdMemoization) 92 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &fourthMemoization) 93 | let _ = memoizedRecursiveFibonacci(position: meassurePosition, memoization: &fifthMemoization) 94 | } 95 | } 96 | 97 | static var allTests = [ 98 | ("testIterativeFibonacci", testIterativeFibonacci), 99 | ("testRecursiveFibonacci", testRecursiveFibonacci), 100 | ("testMemoizedRecursiveFibonacci", testMemoizedRecursiveFibonacci), 101 | ("testIterativeFibonacciPerformance", testIterativeFibonacciPerformance), 102 | ("testRecursiveFibonacciPerformance", testRecursiveFibonacciPerformance), 103 | ("testPopulatedMemoizedRecursiveFibonacciPerformance", testPopulatedMemoizedRecursiveFibonacciPerformance), 104 | ("testEmptyMemoizedRecursiveFibonacciPerformance", testEmptyMemoizedRecursiveFibonacciPerformance), 105 | ] 106 | } 107 | -------------------------------------------------------------------------------- /DataStructures/CountedSet/Tests/CountedSetTests/CountedSetTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import CountedSet 3 | 4 | class CountedSetTests: XCTestCase { 5 | func testIncrementAndDecrementElements() { 6 | let firstElement = "First" 7 | let secondElement = "Second" 8 | let thirdElement = "Third" 9 | 10 | var countedSet = CountedSet() 11 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 0) 12 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 0) 13 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 0) 14 | 15 | XCTAssertEqual(countedSet.incrementCountForElement(element: firstElement), 1) 16 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 1) 17 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 0) 18 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 0) 19 | 20 | XCTAssertEqual(countedSet.incrementCountForElement(element: firstElement), 2) 21 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 2) 22 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 0) 23 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 0) 24 | 25 | XCTAssertEqual(countedSet.incrementCountForElement(element: secondElement), 1) 26 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 2) 27 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 1) 28 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 0) 29 | 30 | XCTAssertEqual(countedSet.incrementCountForElement(element: secondElement), 2) 31 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 2) 32 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 2) 33 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 0) 34 | 35 | XCTAssertEqual(countedSet.incrementCountForElement(element: thirdElement), 1) 36 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 2) 37 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 2) 38 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 1) 39 | 40 | XCTAssertEqual(countedSet.incrementCountForElement(element: thirdElement), 2) 41 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 2) 42 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 2) 43 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 2) 44 | 45 | XCTAssertEqual(countedSet.decrementCountForElement(element: firstElement), 1) 46 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 1) 47 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 2) 48 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 2) 49 | 50 | XCTAssertEqual(countedSet.decrementCountForElement(element: secondElement), 1) 51 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 1) 52 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 1) 53 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 2) 54 | 55 | XCTAssertEqual(countedSet.decrementCountForElement(element: thirdElement), 1) 56 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 1) 57 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 1) 58 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 1) 59 | 60 | XCTAssertEqual(countedSet.decrementCountForElement(element: firstElement), 0) 61 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 0) 62 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 1) 63 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 1) 64 | 65 | XCTAssertEqual(countedSet.decrementCountForElement(element: secondElement), 0) 66 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 0) 67 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 0) 68 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 1) 69 | 70 | XCTAssertEqual(countedSet.decrementCountForElement(element: thirdElement), 0) 71 | XCTAssertEqual(countedSet.countForElement(element: firstElement), 0) 72 | XCTAssertEqual(countedSet.countForElement(element: secondElement), 0) 73 | XCTAssertEqual(countedSet.countForElement(element: thirdElement), 0) 74 | } 75 | 76 | func testElements() { 77 | let firstElement = "1First" 78 | let secondElement = "2Second" 79 | let thirdElement = "3Third" 80 | 81 | var countedSet = CountedSet() 82 | XCTAssertTrue(countedSet.elements().isEmpty) 83 | 84 | _ = countedSet.incrementCountForElement(element: firstElement) 85 | XCTAssertEqual(Array(countedSet.elements()), [firstElement]) 86 | 87 | _ = countedSet.incrementCountForElement(element: secondElement) 88 | XCTAssertEqual(countedSet.elements().sorted(), [firstElement, secondElement]) 89 | 90 | _ = countedSet.incrementCountForElement(element: thirdElement) 91 | XCTAssertEqual(countedSet.elements().sorted(), [firstElement, secondElement, thirdElement]) 92 | 93 | _ = countedSet.decrementCountForElement(element: firstElement) 94 | XCTAssertEqual(countedSet.elements().sorted(), [secondElement, thirdElement]) 95 | 96 | _ = countedSet.decrementCountForElement(element: secondElement) 97 | XCTAssertEqual(Array(countedSet.elements()), [thirdElement]) 98 | 99 | _ = countedSet.decrementCountForElement(element: thirdElement) 100 | XCTAssertTrue(countedSet.elements().isEmpty) 101 | } 102 | 103 | static var allTests = [ 104 | ("testIncrementAndDecrementElements", testIncrementAndDecrementElements), 105 | ("testElements", testElements), 106 | ] 107 | } 108 | --------------------------------------------------------------------------------