├── DataStructures ├── DataStructures.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── alexusbergo.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── DataStructures.xcscheme │ └── xcuserdata │ │ └── alexusbergo.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── DataStructures │ ├── AVLTree.swift │ ├── Bag.swift │ ├── Bimap.swift │ ├── BinaryHeap.swift │ ├── BinarySearchTree.swift │ ├── BitArray.swift │ ├── BloomFilter.swift │ ├── DataStructures.h │ ├── EditDistance.swift │ ├── Graph.swift │ ├── Info.plist │ ├── LinkedList.swift │ ├── Matrix.swift │ ├── Multimap.swift │ ├── PriorityQueue.swift │ ├── QueueExtensions.swift │ ├── RedBlackTree.swift │ ├── StackExtensions.swift │ └── Trie.swift ├── DataStructuresTests │ ├── Info.plist │ └── Tests.swift └── test_output │ ├── report.html │ └── report.junit └── README.md /DataStructures/DataStructures.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 160C1D571C32E19100CF2916 /* BinaryHeap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160C1D561C32E19100CF2916 /* BinaryHeap.swift */; }; 11 | 160C1D591C32E2A400CF2916 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160C1D581C32E2A400CF2916 /* PriorityQueue.swift */; }; 12 | 160C1D5B1C32EA9C00CF2916 /* BloomFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160C1D5A1C32EA9C00CF2916 /* BloomFilter.swift */; }; 13 | 160C1D5D1C32EAD800CF2916 /* BitArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160C1D5C1C32EAD800CF2916 /* BitArray.swift */; }; 14 | 160C1D5F1C353D4000CF2916 /* RedBlackTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160C1D5E1C353D4000CF2916 /* RedBlackTree.swift */; }; 15 | 160C1D621C3563B400CF2916 /* Trie.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160C1D611C3563B400CF2916 /* Trie.swift */; }; 16 | 16257F331C564D1A009DBD20 /* BinarySearchTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16257F321C564D1A009DBD20 /* BinarySearchTree.swift */; }; 17 | 1640AA891C403DFC004F7205 /* Multimap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1640AA881C403DFC004F7205 /* Multimap.swift */; }; 18 | 1640AA8B1C403FE0004F7205 /* Bimap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1640AA8A1C403FE0004F7205 /* Bimap.swift */; }; 19 | 1640AA8D1C40408E004F7205 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1640AA8C1C40408E004F7205 /* Bag.swift */; }; 20 | 1640AA8F1C40FF54004F7205 /* AVLTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1640AA8E1C40FF54004F7205 /* AVLTree.swift */; }; 21 | 1644D68E1C32A5F1000B5F7B /* DataStructures.h in Headers */ = {isa = PBXBuildFile; fileRef = 1644D68D1C32A5F1000B5F7B /* DataStructures.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | 1644D6951C32A5F1000B5F7B /* DataStructures.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1644D68A1C32A5F1000B5F7B /* DataStructures.framework */; }; 23 | 1644D69A1C32A5F1000B5F7B /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1644D6991C32A5F1000B5F7B /* Tests.swift */; }; 24 | 1644D6A71C32A614000B5F7B /* StackExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1644D6A41C32A614000B5F7B /* StackExtensions.swift */; }; 25 | 1644D6A91C32A614000B5F7B /* Graph.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1644D6A51C32A614000B5F7B /* Graph.swift */; }; 26 | 1644D6AB1C32A614000B5F7B /* LinkedList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1644D6A61C32A614000B5F7B /* LinkedList.swift */; }; 27 | 1644D6AE1C32A633000B5F7B /* QueueExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1644D6AD1C32A633000B5F7B /* QueueExtensions.swift */; }; 28 | 16485F2A1C4281920070C913 /* EditDistance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16485F291C4281920070C913 /* EditDistance.swift */; }; 29 | 166852C81C3A790600DD4B30 /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 166852C71C3A790600DD4B30 /* Matrix.swift */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | 1644D6961C32A5F1000B5F7B /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 1644D6811C32A5F1000B5F7B /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 1644D6891C32A5F1000B5F7B; 38 | remoteInfo = DataStructures; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 160C1D561C32E19100CF2916 /* BinaryHeap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BinaryHeap.swift; sourceTree = ""; }; 44 | 160C1D581C32E2A400CF2916 /* PriorityQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PriorityQueue.swift; sourceTree = ""; }; 45 | 160C1D5A1C32EA9C00CF2916 /* BloomFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BloomFilter.swift; sourceTree = ""; }; 46 | 160C1D5C1C32EAD800CF2916 /* BitArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BitArray.swift; sourceTree = ""; }; 47 | 160C1D5E1C353D4000CF2916 /* RedBlackTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RedBlackTree.swift; sourceTree = ""; }; 48 | 160C1D611C3563B400CF2916 /* Trie.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Trie.swift; sourceTree = ""; }; 49 | 16257F321C564D1A009DBD20 /* BinarySearchTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BinarySearchTree.swift; sourceTree = ""; }; 50 | 1640AA881C403DFC004F7205 /* Multimap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Multimap.swift; sourceTree = ""; }; 51 | 1640AA8A1C403FE0004F7205 /* Bimap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bimap.swift; sourceTree = ""; }; 52 | 1640AA8C1C40408E004F7205 /* Bag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bag.swift; sourceTree = ""; }; 53 | 1640AA8E1C40FF54004F7205 /* AVLTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AVLTree.swift; sourceTree = ""; }; 54 | 1644D68A1C32A5F1000B5F7B /* DataStructures.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataStructures.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 1644D68D1C32A5F1000B5F7B /* DataStructures.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataStructures.h; sourceTree = ""; }; 56 | 1644D68F1C32A5F1000B5F7B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 1644D6941C32A5F1000B5F7B /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 1644D6991C32A5F1000B5F7B /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 59 | 1644D69B1C32A5F1000B5F7B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | 1644D6A41C32A614000B5F7B /* StackExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StackExtensions.swift; sourceTree = ""; }; 61 | 1644D6A51C32A614000B5F7B /* Graph.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Graph.swift; sourceTree = ""; }; 62 | 1644D6A61C32A614000B5F7B /* LinkedList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinkedList.swift; sourceTree = ""; }; 63 | 1644D6AD1C32A633000B5F7B /* QueueExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueueExtensions.swift; sourceTree = ""; }; 64 | 16485F291C4281920070C913 /* EditDistance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditDistance.swift; sourceTree = ""; }; 65 | 166852C71C3A790600DD4B30 /* Matrix.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Matrix.swift; sourceTree = ""; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | 1644D6861C32A5F1000B5F7B /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | 1644D6911C32A5F1000B5F7B /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | 1644D6951C32A5F1000B5F7B /* DataStructures.framework in Frameworks */, 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 1644D6801C32A5F1000B5F7B = { 88 | isa = PBXGroup; 89 | children = ( 90 | 1644D68C1C32A5F1000B5F7B /* DataStructures */, 91 | 1644D6981C32A5F1000B5F7B /* Tests */, 92 | 1644D68B1C32A5F1000B5F7B /* Products */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | 1644D68B1C32A5F1000B5F7B /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 1644D68A1C32A5F1000B5F7B /* DataStructures.framework */, 100 | 1644D6941C32A5F1000B5F7B /* Tests.xctest */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | 1644D68C1C32A5F1000B5F7B /* DataStructures */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 1644D68D1C32A5F1000B5F7B /* DataStructures.h */, 109 | 1644D6A61C32A614000B5F7B /* LinkedList.swift */, 110 | 1644D6A51C32A614000B5F7B /* Graph.swift */, 111 | 160C1D581C32E2A400CF2916 /* PriorityQueue.swift */, 112 | 160C1D561C32E19100CF2916 /* BinaryHeap.swift */, 113 | 160C1D5A1C32EA9C00CF2916 /* BloomFilter.swift */, 114 | 160C1D5C1C32EAD800CF2916 /* BitArray.swift */, 115 | 166852C71C3A790600DD4B30 /* Matrix.swift */, 116 | 1640AA881C403DFC004F7205 /* Multimap.swift */, 117 | 1640AA8A1C403FE0004F7205 /* Bimap.swift */, 118 | 1640AA8C1C40408E004F7205 /* Bag.swift */, 119 | 160C1D611C3563B400CF2916 /* Trie.swift */, 120 | 160C1D5E1C353D4000CF2916 /* RedBlackTree.swift */, 121 | 16257F321C564D1A009DBD20 /* BinarySearchTree.swift */, 122 | 1640AA8E1C40FF54004F7205 /* AVLTree.swift */, 123 | 1644D6AD1C32A633000B5F7B /* QueueExtensions.swift */, 124 | 1644D6A41C32A614000B5F7B /* StackExtensions.swift */, 125 | 16485F291C4281920070C913 /* EditDistance.swift */, 126 | 1644D68F1C32A5F1000B5F7B /* Info.plist */, 127 | ); 128 | path = DataStructures; 129 | sourceTree = ""; 130 | }; 131 | 1644D6981C32A5F1000B5F7B /* Tests */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 1644D6991C32A5F1000B5F7B /* Tests.swift */, 135 | 1644D69B1C32A5F1000B5F7B /* Info.plist */, 136 | ); 137 | name = Tests; 138 | path = DataStructuresTests; 139 | sourceTree = ""; 140 | }; 141 | /* End PBXGroup section */ 142 | 143 | /* Begin PBXHeadersBuildPhase section */ 144 | 1644D6871C32A5F1000B5F7B /* Headers */ = { 145 | isa = PBXHeadersBuildPhase; 146 | buildActionMask = 2147483647; 147 | files = ( 148 | 1644D68E1C32A5F1000B5F7B /* DataStructures.h in Headers */, 149 | ); 150 | runOnlyForDeploymentPostprocessing = 0; 151 | }; 152 | /* End PBXHeadersBuildPhase section */ 153 | 154 | /* Begin PBXNativeTarget section */ 155 | 1644D6891C32A5F1000B5F7B /* DataStructures */ = { 156 | isa = PBXNativeTarget; 157 | buildConfigurationList = 1644D69E1C32A5F1000B5F7B /* Build configuration list for PBXNativeTarget "DataStructures" */; 158 | buildPhases = ( 159 | 1644D6851C32A5F1000B5F7B /* Sources */, 160 | 1644D6861C32A5F1000B5F7B /* Frameworks */, 161 | 1644D6871C32A5F1000B5F7B /* Headers */, 162 | 1644D6881C32A5F1000B5F7B /* Resources */, 163 | ); 164 | buildRules = ( 165 | ); 166 | dependencies = ( 167 | ); 168 | name = DataStructures; 169 | productName = DataStructures; 170 | productReference = 1644D68A1C32A5F1000B5F7B /* DataStructures.framework */; 171 | productType = "com.apple.product-type.framework"; 172 | }; 173 | 1644D6931C32A5F1000B5F7B /* Tests */ = { 174 | isa = PBXNativeTarget; 175 | buildConfigurationList = 1644D6A11C32A5F1000B5F7B /* Build configuration list for PBXNativeTarget "Tests" */; 176 | buildPhases = ( 177 | 1644D6901C32A5F1000B5F7B /* Sources */, 178 | 1644D6911C32A5F1000B5F7B /* Frameworks */, 179 | 1644D6921C32A5F1000B5F7B /* Resources */, 180 | ); 181 | buildRules = ( 182 | ); 183 | dependencies = ( 184 | 1644D6971C32A5F1000B5F7B /* PBXTargetDependency */, 185 | ); 186 | name = Tests; 187 | productName = DataStructuresTests; 188 | productReference = 1644D6941C32A5F1000B5F7B /* Tests.xctest */; 189 | productType = "com.apple.product-type.bundle.unit-test"; 190 | }; 191 | /* End PBXNativeTarget section */ 192 | 193 | /* Begin PBXProject section */ 194 | 1644D6811C32A5F1000B5F7B /* Project object */ = { 195 | isa = PBXProject; 196 | attributes = { 197 | LastSwiftUpdateCheck = 0720; 198 | LastUpgradeCheck = 0720; 199 | ORGANIZATIONNAME = "Alex Usbergo"; 200 | TargetAttributes = { 201 | 1644D6891C32A5F1000B5F7B = { 202 | CreatedOnToolsVersion = 7.2; 203 | LastSwiftMigration = 0800; 204 | }; 205 | 1644D6931C32A5F1000B5F7B = { 206 | CreatedOnToolsVersion = 7.2; 207 | LastSwiftMigration = 0800; 208 | }; 209 | }; 210 | }; 211 | buildConfigurationList = 1644D6841C32A5F1000B5F7B /* Build configuration list for PBXProject "DataStructures" */; 212 | compatibilityVersion = "Xcode 3.2"; 213 | developmentRegion = English; 214 | hasScannedForEncodings = 0; 215 | knownRegions = ( 216 | en, 217 | ); 218 | mainGroup = 1644D6801C32A5F1000B5F7B; 219 | productRefGroup = 1644D68B1C32A5F1000B5F7B /* Products */; 220 | projectDirPath = ""; 221 | projectRoot = ""; 222 | targets = ( 223 | 1644D6891C32A5F1000B5F7B /* DataStructures */, 224 | 1644D6931C32A5F1000B5F7B /* Tests */, 225 | ); 226 | }; 227 | /* End PBXProject section */ 228 | 229 | /* Begin PBXResourcesBuildPhase section */ 230 | 1644D6881C32A5F1000B5F7B /* Resources */ = { 231 | isa = PBXResourcesBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | 1644D6921C32A5F1000B5F7B /* Resources */ = { 238 | isa = PBXResourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | ); 242 | runOnlyForDeploymentPostprocessing = 0; 243 | }; 244 | /* End PBXResourcesBuildPhase section */ 245 | 246 | /* Begin PBXSourcesBuildPhase section */ 247 | 1644D6851C32A5F1000B5F7B /* Sources */ = { 248 | isa = PBXSourcesBuildPhase; 249 | buildActionMask = 2147483647; 250 | files = ( 251 | 16257F331C564D1A009DBD20 /* BinarySearchTree.swift in Sources */, 252 | 1644D6AB1C32A614000B5F7B /* LinkedList.swift in Sources */, 253 | 1644D6A91C32A614000B5F7B /* Graph.swift in Sources */, 254 | 1640AA8D1C40408E004F7205 /* Bag.swift in Sources */, 255 | 1644D6A71C32A614000B5F7B /* StackExtensions.swift in Sources */, 256 | 1644D6AE1C32A633000B5F7B /* QueueExtensions.swift in Sources */, 257 | 1640AA8B1C403FE0004F7205 /* Bimap.swift in Sources */, 258 | 160C1D5B1C32EA9C00CF2916 /* BloomFilter.swift in Sources */, 259 | 166852C81C3A790600DD4B30 /* Matrix.swift in Sources */, 260 | 160C1D621C3563B400CF2916 /* Trie.swift in Sources */, 261 | 1640AA8F1C40FF54004F7205 /* AVLTree.swift in Sources */, 262 | 160C1D5F1C353D4000CF2916 /* RedBlackTree.swift in Sources */, 263 | 160C1D571C32E19100CF2916 /* BinaryHeap.swift in Sources */, 264 | 160C1D591C32E2A400CF2916 /* PriorityQueue.swift in Sources */, 265 | 1640AA891C403DFC004F7205 /* Multimap.swift in Sources */, 266 | 160C1D5D1C32EAD800CF2916 /* BitArray.swift in Sources */, 267 | 16485F2A1C4281920070C913 /* EditDistance.swift in Sources */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | 1644D6901C32A5F1000B5F7B /* Sources */ = { 272 | isa = PBXSourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 1644D69A1C32A5F1000B5F7B /* Tests.swift in Sources */, 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | /* End PBXSourcesBuildPhase section */ 280 | 281 | /* Begin PBXTargetDependency section */ 282 | 1644D6971C32A5F1000B5F7B /* PBXTargetDependency */ = { 283 | isa = PBXTargetDependency; 284 | target = 1644D6891C32A5F1000B5F7B /* DataStructures */; 285 | targetProxy = 1644D6961C32A5F1000B5F7B /* PBXContainerItemProxy */; 286 | }; 287 | /* End PBXTargetDependency section */ 288 | 289 | /* Begin XCBuildConfiguration section */ 290 | 1644D69C1C32A5F1000B5F7B /* Debug */ = { 291 | isa = XCBuildConfiguration; 292 | buildSettings = { 293 | ALWAYS_SEARCH_USER_PATHS = NO; 294 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 295 | CLANG_CXX_LIBRARY = "libc++"; 296 | CLANG_ENABLE_MODULES = YES; 297 | CLANG_ENABLE_OBJC_ARC = YES; 298 | CLANG_WARN_BOOL_CONVERSION = YES; 299 | CLANG_WARN_CONSTANT_CONVERSION = YES; 300 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 301 | CLANG_WARN_EMPTY_BODY = YES; 302 | CLANG_WARN_ENUM_CONVERSION = YES; 303 | CLANG_WARN_INT_CONVERSION = YES; 304 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 305 | CLANG_WARN_UNREACHABLE_CODE = YES; 306 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 307 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 308 | COPY_PHASE_STRIP = NO; 309 | CURRENT_PROJECT_VERSION = 1; 310 | DEBUG_INFORMATION_FORMAT = dwarf; 311 | ENABLE_STRICT_OBJC_MSGSEND = YES; 312 | ENABLE_TESTABILITY = YES; 313 | GCC_C_LANGUAGE_STANDARD = gnu99; 314 | GCC_DYNAMIC_NO_PIC = NO; 315 | GCC_NO_COMMON_BLOCKS = YES; 316 | GCC_OPTIMIZATION_LEVEL = 0; 317 | GCC_PREPROCESSOR_DEFINITIONS = ( 318 | "DEBUG=1", 319 | "$(inherited)", 320 | ); 321 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 322 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 323 | GCC_WARN_UNDECLARED_SELECTOR = YES; 324 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 325 | GCC_WARN_UNUSED_FUNCTION = YES; 326 | GCC_WARN_UNUSED_VARIABLE = YES; 327 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 328 | MTL_ENABLE_DEBUG_INFO = YES; 329 | ONLY_ACTIVE_ARCH = YES; 330 | SDKROOT = iphoneos; 331 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 332 | TARGETED_DEVICE_FAMILY = "1,2"; 333 | VERSIONING_SYSTEM = "apple-generic"; 334 | VERSION_INFO_PREFIX = ""; 335 | }; 336 | name = Debug; 337 | }; 338 | 1644D69D1C32A5F1000B5F7B /* Release */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ALWAYS_SEARCH_USER_PATHS = NO; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_MODULES = YES; 345 | CLANG_ENABLE_OBJC_ARC = YES; 346 | CLANG_WARN_BOOL_CONVERSION = YES; 347 | CLANG_WARN_CONSTANT_CONVERSION = YES; 348 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 349 | CLANG_WARN_EMPTY_BODY = YES; 350 | CLANG_WARN_ENUM_CONVERSION = YES; 351 | CLANG_WARN_INT_CONVERSION = YES; 352 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 353 | CLANG_WARN_UNREACHABLE_CODE = YES; 354 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 355 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 356 | COPY_PHASE_STRIP = NO; 357 | CURRENT_PROJECT_VERSION = 1; 358 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 359 | ENABLE_NS_ASSERTIONS = NO; 360 | ENABLE_STRICT_OBJC_MSGSEND = YES; 361 | GCC_C_LANGUAGE_STANDARD = gnu99; 362 | GCC_NO_COMMON_BLOCKS = YES; 363 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 364 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 365 | GCC_WARN_UNDECLARED_SELECTOR = YES; 366 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 367 | GCC_WARN_UNUSED_FUNCTION = YES; 368 | GCC_WARN_UNUSED_VARIABLE = YES; 369 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 370 | MTL_ENABLE_DEBUG_INFO = NO; 371 | SDKROOT = iphoneos; 372 | TARGETED_DEVICE_FAMILY = "1,2"; 373 | VALIDATE_PRODUCT = YES; 374 | VERSIONING_SYSTEM = "apple-generic"; 375 | VERSION_INFO_PREFIX = ""; 376 | }; 377 | name = Release; 378 | }; 379 | 1644D69F1C32A5F1000B5F7B /* Debug */ = { 380 | isa = XCBuildConfiguration; 381 | buildSettings = { 382 | CLANG_ENABLE_MODULES = YES; 383 | DEFINES_MODULE = YES; 384 | DYLIB_COMPATIBILITY_VERSION = 1; 385 | DYLIB_CURRENT_VERSION = 1; 386 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 387 | INFOPLIST_FILE = DataStructures/Info.plist; 388 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 389 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 390 | PRODUCT_BUNDLE_IDENTIFIER = com.au.DataStructures; 391 | PRODUCT_NAME = "$(TARGET_NAME)"; 392 | SKIP_INSTALL = YES; 393 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 394 | SWIFT_VERSION = 3.0; 395 | }; 396 | name = Debug; 397 | }; 398 | 1644D6A01C32A5F1000B5F7B /* Release */ = { 399 | isa = XCBuildConfiguration; 400 | buildSettings = { 401 | CLANG_ENABLE_MODULES = YES; 402 | DEFINES_MODULE = YES; 403 | DYLIB_COMPATIBILITY_VERSION = 1; 404 | DYLIB_CURRENT_VERSION = 1; 405 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 406 | INFOPLIST_FILE = DataStructures/Info.plist; 407 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 408 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 409 | PRODUCT_BUNDLE_IDENTIFIER = com.au.DataStructures; 410 | PRODUCT_NAME = "$(TARGET_NAME)"; 411 | SKIP_INSTALL = YES; 412 | SWIFT_VERSION = 3.0; 413 | }; 414 | name = Release; 415 | }; 416 | 1644D6A21C32A5F1000B5F7B /* Debug */ = { 417 | isa = XCBuildConfiguration; 418 | buildSettings = { 419 | INFOPLIST_FILE = DataStructuresTests/Info.plist; 420 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 421 | PRODUCT_BUNDLE_IDENTIFIER = com.au.DataStructuresTests; 422 | PRODUCT_NAME = "$(TARGET_NAME)"; 423 | SWIFT_VERSION = 3.0; 424 | }; 425 | name = Debug; 426 | }; 427 | 1644D6A31C32A5F1000B5F7B /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | buildSettings = { 430 | INFOPLIST_FILE = DataStructuresTests/Info.plist; 431 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 432 | PRODUCT_BUNDLE_IDENTIFIER = com.au.DataStructuresTests; 433 | PRODUCT_NAME = "$(TARGET_NAME)"; 434 | SWIFT_VERSION = 3.0; 435 | }; 436 | name = Release; 437 | }; 438 | /* End XCBuildConfiguration section */ 439 | 440 | /* Begin XCConfigurationList section */ 441 | 1644D6841C32A5F1000B5F7B /* Build configuration list for PBXProject "DataStructures" */ = { 442 | isa = XCConfigurationList; 443 | buildConfigurations = ( 444 | 1644D69C1C32A5F1000B5F7B /* Debug */, 445 | 1644D69D1C32A5F1000B5F7B /* Release */, 446 | ); 447 | defaultConfigurationIsVisible = 0; 448 | defaultConfigurationName = Release; 449 | }; 450 | 1644D69E1C32A5F1000B5F7B /* Build configuration list for PBXNativeTarget "DataStructures" */ = { 451 | isa = XCConfigurationList; 452 | buildConfigurations = ( 453 | 1644D69F1C32A5F1000B5F7B /* Debug */, 454 | 1644D6A01C32A5F1000B5F7B /* Release */, 455 | ); 456 | defaultConfigurationIsVisible = 0; 457 | defaultConfigurationName = Release; 458 | }; 459 | 1644D6A11C32A5F1000B5F7B /* Build configuration list for PBXNativeTarget "Tests" */ = { 460 | isa = XCConfigurationList; 461 | buildConfigurations = ( 462 | 1644D6A21C32A5F1000B5F7B /* Debug */, 463 | 1644D6A31C32A5F1000B5F7B /* Release */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 1644D6811C32A5F1000B5F7B /* Project object */; 471 | } 472 | -------------------------------------------------------------------------------- /DataStructures/DataStructures.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DataStructures/DataStructures.xcodeproj/project.xcworkspace/xcuserdata/alexusbergo.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/DataStructures/1dc32189122dfd164de2873c51eeb7a6ee525f59/DataStructures/DataStructures.xcodeproj/project.xcworkspace/xcuserdata/alexusbergo.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DataStructures/DataStructures.xcodeproj/xcshareddata/xcschemes/DataStructures.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /DataStructures/DataStructures.xcodeproj/xcuserdata/alexusbergo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 51 | 52 | 66 | 67 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /DataStructures/DataStructures.xcodeproj/xcuserdata/alexusbergo.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DataStructures.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 1644D6891C32A5F1000B5F7B 16 | 17 | primary 18 | 19 | 20 | 1644D6931C32A5F1000B5F7B 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/AVLTree.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Original ObjC implementation: https://github.com/StephanPartzsch/AVLTree 24 | // 25 | 26 | import Foundation 27 | 28 | fileprivate func < (lhs: T?, rhs: T?) -> Bool { 29 | switch (lhs, rhs) { 30 | case let (l?, r?): 31 | return l < r 32 | case (nil, _?): 33 | return true 34 | default: 35 | return false 36 | } 37 | } 38 | 39 | fileprivate func > (lhs: T?, rhs: T?) -> Bool { 40 | switch (lhs, rhs) { 41 | case let (l?, r?): 42 | return l > r 43 | default: 44 | return rhs < lhs 45 | } 46 | } 47 | 48 | 49 | func ||(optional : Optional, defaultValue : T) -> T { 50 | if let value = optional { 51 | return value 52 | } 53 | return defaultValue 54 | } 55 | 56 | public func +(node : AVLTree, newValue : T) -> AVLTree { 57 | var newLeft : AVLTree? = node.left 58 | var newRight : AVLTree? = node.right 59 | 60 | if (newValue < node.value) { 61 | if let left = node.left { 62 | newLeft = left + newValue 63 | } else { 64 | newLeft = AVLTree(newValue) 65 | } 66 | 67 | } else if(newValue > node.value) { 68 | if let right = node.right { 69 | newRight = right + newValue 70 | } else { 71 | newRight = AVLTree(newValue) 72 | } 73 | 74 | } else { 75 | return node 76 | } 77 | 78 | let newRoot = AVLTree(value: node.value, left: newLeft, right: newRight) 79 | return newRoot.fixBalance() 80 | } 81 | 82 | public func-(node: AVLTree?, value : T) -> AVLTree? { 83 | return node?.remove(value).result 84 | } 85 | 86 | ///AVL tree is a self balanced binary tree. 87 | ///It doesn’t consume much memory, all standard operations (add, remove, find) are log(n) and 88 | ///you can iterate through the elements in ascending or descending manner. In comparison to an Array, 89 | ///an AVL tree is slower for addition but much faster for remove and find. The values are also always ordered. 90 | open class AVLTree { 91 | public typealias Element = T 92 | 93 | open let left : AVLTree? 94 | open let right : AVLTree? 95 | 96 | open let count : UInt 97 | open let depth : UInt 98 | open let balance : Int 99 | 100 | open let value : Element! 101 | 102 | public convenience init(_ value : Element){ 103 | self.init(value: value, left: nil, right: nil) 104 | } 105 | 106 | open func contains(_ value : Element) -> Bool{ 107 | if self.value == value { return true } 108 | if left?.contains(value) == true { return true } 109 | if right?.contains(value) == true { return true } 110 | return false 111 | } 112 | 113 | init(value : Element, left: AVLTree?, right: AVLTree?){ 114 | self.value = value 115 | self.left = left 116 | self.right = right 117 | self.count = 1 + (left?.count || 0) + (right?.count || 0) 118 | 119 | let ld = left?.depth || 0 120 | let rd = right?.depth || 0 121 | self.depth = 1 + (ld > rd ? ld : rd) 122 | 123 | let l: Int = Int((left?.depth) || 0) 124 | let r: Int = Int((right?.depth) || 0) 125 | self.balance = l - r 126 | } 127 | 128 | fileprivate func fixBalance() -> AVLTree { 129 | if abs(balance) < 2 { 130 | return self 131 | } 132 | 133 | if (balance == 2) { 134 | let leftBalance = self.left?.balance || 0 135 | 136 | if (leftBalance == 1 || leftBalance == 0) { 137 | //Easy case: 138 | return rotateToRight() 139 | } 140 | 141 | if (leftBalance == -1) { 142 | //Rotate Left to left 143 | let newLeft = left!.rotateToLeft() 144 | let newRoot = AVLTree(value: value, left: newLeft, right: right) 145 | 146 | return newRoot.rotateToRight() 147 | } 148 | 149 | fatalError("LeftNode too unbalanced") 150 | } 151 | 152 | if (balance == -2) { 153 | let rightBalance = right?.balance || 0 154 | 155 | if (rightBalance == -1 || rightBalance == 0) { 156 | //Easy case: 157 | return rotateToLeft() 158 | } 159 | 160 | if (rightBalance == 1) { 161 | //Rotate right to right 162 | let newRight = right!.rotateToRight() 163 | let newRoot = AVLTree(value: value, left: left, right: newRight) 164 | 165 | return newRoot.rotateToLeft() 166 | } 167 | 168 | fatalError("RightNode too unbalanced") 169 | } 170 | 171 | fatalError("Tree too unbalanced") 172 | } 173 | 174 | open func remove(_ value : Element) -> (result: AVLTree?, foundFlag :Bool) { 175 | 176 | if value < self.value { 177 | 178 | let removeResult = left?.remove(value) 179 | if removeResult == nil || removeResult!.foundFlag == false { 180 | // Not found, so nothing changed 181 | return (self, false) 182 | } 183 | 184 | let newRoot = AVLTree(value: self.value, left: removeResult!.result, right: right).fixBalance() 185 | return (newRoot, true) 186 | } 187 | 188 | if value > self.value { 189 | 190 | let removeResult = right?.remove(value) 191 | if removeResult == nil || removeResult!.foundFlag == false { 192 | // Not found, so nothing changed 193 | return (self, false) 194 | } 195 | 196 | let newRoot = AVLTree(value: self.value, left: left, right: removeResult!.result) 197 | return (newRoot, true) 198 | } 199 | 200 | //found it 201 | return (removeRoot(), true) 202 | } 203 | 204 | open func removeMin()-> (min : AVLTree, result : AVLTree?) { 205 | 206 | if left == nil { 207 | //We are the minimum: 208 | return (self, right) 209 | 210 | } else { 211 | //Go down: 212 | let (min, newLeft) = left!.removeMin() 213 | let newRoot = AVLTree(value: value, left: newLeft, right: right) 214 | 215 | return (min, newRoot.fixBalance()) 216 | } 217 | } 218 | 219 | open func removeMax()-> (max : AVLTree, result : AVLTree?) { 220 | 221 | if right == nil { 222 | //We are the max: 223 | return (self, left) 224 | } else { 225 | //Go down: 226 | let (max, newRight) = right!.removeMax() 227 | let newRoot = AVLTree(value: value, left: left, right: newRight) 228 | 229 | return (max, newRoot.fixBalance()) 230 | } 231 | } 232 | 233 | open func removeRoot() -> AVLTree? { 234 | 235 | if left == nil { 236 | return right 237 | } 238 | 239 | if right == nil { 240 | return left 241 | } 242 | 243 | //Neither are empty: 244 | if left!.count < right!.count { 245 | // LeftNode has fewer, so promote from RightNode to minimize depth 246 | let (min, newRight) = right!.removeMin() 247 | let newRoot = AVLTree(value: min.value, left: left, right: newRight) 248 | 249 | return newRoot.fixBalance() 250 | } else { 251 | let (max, newLeft) = left!.removeMax() 252 | let newRoot = AVLTree(value: max.value, left: newLeft, right: right) 253 | 254 | return newRoot.fixBalance() 255 | } 256 | } 257 | 258 | fileprivate func rotateToRight() -> AVLTree { 259 | let newRight = AVLTree(value: value, left: left!.right, right: right) 260 | return AVLTree(value: left!.value, left: left!.left, right: newRight) 261 | } 262 | 263 | fileprivate func rotateToLeft() -> AVLTree { 264 | let newLeft = AVLTree(value: value, left: left, right: right!.left) 265 | return AVLTree(value: right!.value, left: newLeft, right: right!.right) 266 | } 267 | } 268 | 269 | extension AVLTree : CustomStringConvertible { 270 | 271 | public var description : String { 272 | let empty = "_" 273 | return "(\(value) \(left?.description || empty) \(right?.description || empty))" 274 | } 275 | } 276 | 277 | extension AVLTree : Sequence { 278 | 279 | ///Runs a `RedBlackTreeGenerator` over the elements of `self`. (The elements are presented in 280 | ///order, from smallest to largest) 281 | public func makeIterator() -> AVLTreeGenerator { 282 | return AVLTreeGenerator(stack: [], curr: self) 283 | } 284 | } 285 | 286 | ///A `Generator` for a AVLTree 287 | public struct AVLTreeGenerator : IteratorProtocol { 288 | 289 | fileprivate var (stack, curr): ([AVLTree], AVLTree) 290 | 291 | ///Advance to the next element and return it, or return `nil` if no next element exists. 292 | public mutating func next() -> Element? { 293 | 294 | if curr.left == nil { 295 | if let right = curr.right { 296 | let value = curr.value 297 | curr = right 298 | return value 299 | } 300 | } else { 301 | stack.append(curr) 302 | if let left = curr.left { 303 | curr = left 304 | } 305 | } 306 | 307 | guard let node = stack.popLast() else { 308 | return nil 309 | } 310 | 311 | if let right = node.right { 312 | let value = node.value 313 | curr = right 314 | return value 315 | } 316 | 317 | return nil 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/Bag.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | 24 | import Foundation 25 | 26 | /// A Multiset (sometimes called a bag) is a special kind of set in which 27 | /// members are allowed to appear more than once. It's possible to convert a multiset 28 | /// to a set: `let set = Set(multiset)` 29 | /// 30 | /// Conforms to `Sequence`, `ExpressibleByArrayLiteral` and 31 | /// `Hashable`. 32 | public struct Bag { 33 | 34 | // MARK: Creating a Multiset 35 | 36 | /// Constructs an empty multiset. 37 | public init() {} 38 | 39 | /// Constructs a multiset from a sequence, such as an array. 40 | public init(_ elements: S) where S.Iterator.Element == T{ 41 | for e in elements { 42 | insert(e) 43 | } 44 | } 45 | 46 | // MARK: Querying a Multiset 47 | 48 | /// Number of elements stored in the multiset, including multiple copies. 49 | public fileprivate(set) var count = 0 50 | 51 | /// Returns `true` if and only if `count == 0`. 52 | public var isEmpty: Bool { 53 | return count == 0 54 | } 55 | 56 | /// Number of distinct elements stored in the multiset. 57 | public var distinctCount: Int { 58 | return members.count 59 | } 60 | 61 | /// A sequence containing the multiset's distinct elements. 62 | public var distinctElements: AnySequence { 63 | return AnySequence(members.keys) 64 | } 65 | 66 | /// Returns `true` if the multiset contains the given element. 67 | public func contains(_ element: T) -> Bool { 68 | return members[element] != nil 69 | } 70 | 71 | /// Returns the number of occurrences of an element in the multiset. 72 | public func count(_ element: T) -> Int { 73 | return members[element] ?? 0 74 | } 75 | 76 | // MARK: Adding and Removing Elements 77 | 78 | /// Inserts a single occurrence of an element into the multiset. 79 | public mutating func insert(_ element: T) { 80 | insert(element, occurrences: 1) 81 | } 82 | 83 | /// Inserts a number of occurrences of an element into the multiset. 84 | public mutating func insert(_ element: T, occurrences: Int) { 85 | precondition(occurrences >= 1, "Invalid number of occurrences") 86 | let previousNumber = members[element] ?? 0 87 | members[element] = previousNumber + occurrences 88 | count += occurrences 89 | } 90 | 91 | /// Removes a single occurrence of an element from the multiset, if present. 92 | public mutating func remove(_ element: T) { 93 | return remove(element, occurrences: 1) 94 | } 95 | 96 | /// Removes a number of occurrences of an element from the multiset. 97 | /// If the multiset contains fewer than this number of occurrences to begin with, 98 | /// all occurrences will be removed. 99 | public mutating func remove(_ element: T, occurrences: Int) { 100 | precondition(occurrences >= 1, "Invalid number of occurrences") 101 | if let currentOccurrences = members[element] { 102 | let nRemoved = [currentOccurrences, occurrences].min()! 103 | count -= nRemoved 104 | let newOcurrencies = currentOccurrences - nRemoved 105 | if newOcurrencies == 0 { 106 | members.removeValue(forKey: element) 107 | } else { 108 | members[element] = newOcurrencies 109 | } 110 | } 111 | } 112 | 113 | /// Removes all occurrences of an element from the multiset, if present. 114 | public mutating func removeAllOf(_ element: T) { 115 | let ocurrences = count(element) 116 | return remove(element, occurrences: ocurrences) 117 | } 118 | 119 | /// Removes all the elements from the multiset, and by default 120 | /// clears the underlying storage buffer. 121 | public mutating func removeAll(keepingCapacity keep: Bool = false) { 122 | members.removeAll(keepingCapacity: keep) 123 | count = 0 124 | } 125 | 126 | // MARK: Private Properties and Helper Methods 127 | 128 | /// Internal dictionary holding the elements. 129 | fileprivate var members = [T: Int]() 130 | } 131 | 132 | // MARK: - 133 | 134 | extension Bag: Sequence { 135 | 136 | // MARK: Sequence Protocol Conformance 137 | 138 | /// Provides for-in loop functionality. Generates multiple occurrences per element. 139 | /// 140 | /// - returns: A generator over the elements. 141 | public func makeIterator() -> AnyIterator { 142 | var keyValueGenerator = members.makeIterator() 143 | var elementCount = 0 144 | var element : T? = nil 145 | return AnyIterator { 146 | if elementCount > 0 { 147 | elementCount -= 1 148 | return element 149 | } 150 | let nextTuple = keyValueGenerator.next() 151 | element = nextTuple?.0 152 | elementCount = nextTuple?.1 ?? 1 153 | elementCount -= 1 154 | return element 155 | } 156 | } 157 | } 158 | 159 | extension Bag: CustomStringConvertible { 160 | 161 | // MARK: CustomStringConvertible Protocol Conformance 162 | 163 | /// A string containing a suitable textual 164 | /// representation of the multiset. 165 | public var description: String { 166 | return "[" + map{"\($0)"}.joined(separator: ", ") + "]" 167 | } 168 | } 169 | 170 | extension Bag: ExpressibleByArrayLiteral { 171 | 172 | // MARK: ExpressibleByArrayLiteral Protocol Conformance 173 | 174 | /// Constructs a multiset using an array literal. 175 | /// Unlike a set, multiple copies of an element are inserted. 176 | public init(arrayLiteral elements: T...) { 177 | self.init(elements) 178 | } 179 | } 180 | 181 | extension Bag: Hashable { 182 | 183 | // MARK: Hashable Protocol Conformance 184 | 185 | /// The hash value. 186 | /// `x == y` implies `x.hashValue == y.hashValue` 187 | public var hashValue: Int { 188 | var result = 3 189 | result = (31 ^ result) ^ distinctCount 190 | result = (31 ^ result) ^ count 191 | for element in self { 192 | result = (31 ^ result) ^ element.hashValue 193 | } 194 | return result 195 | } 196 | } 197 | 198 | // MARK: Multiset Equatable Conformance 199 | 200 | /// Returns `true` if and only if the multisets contain the same number of occurrences per element. 201 | public func ==(lhs: Bag, rhs: Bag) -> Bool { 202 | if lhs.count != rhs.count || lhs.distinctCount != rhs.distinctCount { 203 | return false 204 | } 205 | for element in lhs { 206 | if lhs.count(element) != rhs.count(element) { 207 | return false 208 | } 209 | } 210 | return true 211 | } 212 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/Bimap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Forked from mauriciosantos/Buckets-Swift/ 24 | 25 | import Foundation 26 | 27 | /// A Bimap is a special kind of dictionary that allows bidirectional lookup between 28 | /// keys and values. 29 | /// All keys and values must be unique. 30 | /// It allows to get, set, or delete a key-value pairs using 31 | /// subscript notation: `bimap[value: aValue] = aKey` or `bimap[key: aKey] = aValue` 32 | /// 33 | /// Conforms to `Sequence`, `Collection`, `ExpressibleByDictionaryLiteral`, 34 | /// `Equatable`, `Hashable` and `CustomStringConvertible`. 35 | public struct Bimap { 36 | 37 | // MARK: Creating a Bimap 38 | 39 | /// Constructs an empty bimap. 40 | public init() {} 41 | 42 | /// Constructs a bimap with at least the given number of 43 | /// elements worth of storage. The actual capacity will be the 44 | /// smallest power of 2 that's >= `minimumCapacity`. 45 | public init(minimumCapacity: Int) { 46 | keysToValues = [Key: Value](minimumCapacity: minimumCapacity) 47 | valuesToKeys = [Value: Key](minimumCapacity: minimumCapacity) 48 | } 49 | 50 | /// Constructs a bimap from a dictionary. 51 | public init(_ elements: Dictionary) { 52 | for (k, value) in elements { 53 | self[key: k] = value 54 | } 55 | } 56 | 57 | /// Constructs a bimap from a sequence of key-value pairs. 58 | public init(_ elements: S) where S.Iterator.Element == (Key, Value) { 59 | for (k, value) in elements { 60 | self[key: k] = value 61 | } 62 | } 63 | 64 | // MARK: Querying a Bimap 65 | 66 | /// Number of key-value pairs stored in the bimap. 67 | public var count: Int { 68 | return keysToValues.count 69 | } 70 | 71 | /// Returns `true` if and only if `count == 0`. 72 | public var isEmpty: Bool { 73 | return keysToValues.isEmpty 74 | } 75 | 76 | /// A collection containing all the bimap's keys. 77 | public var keys: AnyCollection { 78 | return AnyCollection(keysToValues.keys) 79 | } 80 | 81 | /// A collection containing all the bimap's values. 82 | public var values: AnyCollection { 83 | return AnyCollection(valuesToKeys.keys) 84 | } 85 | 86 | // MARK: Accessing and Changing Bimap Elements 87 | 88 | // Gets, sets, or deletes a key-value pair in the bimap using square bracket subscripting. 89 | public subscript(value value: Value) -> Key? { 90 | get { 91 | return valuesToKeys[value] 92 | } 93 | set(newKey) { 94 | let oldKey = valuesToKeys.removeValue(forKey: value) 95 | if let oldKey = oldKey { 96 | keysToValues.removeValue(forKey: oldKey) 97 | } 98 | valuesToKeys[value] = newKey 99 | if let newKey = newKey { 100 | keysToValues[newKey] = value 101 | } 102 | } 103 | } 104 | 105 | // Gets, sets, or deletes a key-value pair in the bimap using square bracket subscripting. 106 | public subscript(key key: Key) -> Value? { 107 | get { 108 | return keysToValues[key] 109 | } 110 | set { 111 | let oldValue = keysToValues.removeValue(forKey: key) 112 | if let oldValue = oldValue { 113 | valuesToKeys.removeValue(forKey: oldValue) 114 | } 115 | keysToValues[key] = newValue 116 | if let newValue = newValue { 117 | valuesToKeys[newValue] = key 118 | } 119 | } 120 | } 121 | 122 | /// Inserts or updates a value for a given key and returns the previous value 123 | /// for that key if one existed, or `nil` if a previous value did not exist. 124 | /// Subscript access is preferred. 125 | @discardableResult 126 | public mutating func updateValue(_ value: Value, forKey key: Key) -> Value? { 127 | let previous = self[key: key] 128 | self[key: key] = value 129 | return previous 130 | } 131 | 132 | /// Removes the key-value pair for the given key and returns its value, 133 | /// or `nil` if a value for that key did not previously exist. 134 | /// Subscript access is preferred. 135 | @discardableResult 136 | public mutating func removeValueForKey(_ key: Key) -> Value? { 137 | let previous = self[key: key] 138 | self[key: key] = nil 139 | return previous 140 | } 141 | 142 | /// Removes the key-value pair for the given value and returns its key, 143 | /// or `nil` if a key for that value did not previously exist. 144 | /// Subscript access is preferred. 145 | @discardableResult 146 | public mutating func removeKeyForValue(_ value: Value) -> Key? { 147 | let previous = self[value: value] 148 | self[value: value] = nil 149 | return previous 150 | } 151 | 152 | /// Removes all the elements from the bimap, and by default 153 | /// clears the underlying storage buffer. 154 | public mutating func removeAll(keepCapacity keep: Bool = true) { 155 | valuesToKeys.removeAll(keepingCapacity: keep) 156 | keysToValues.removeAll(keepingCapacity: keep) 157 | } 158 | 159 | // MARK: Private Properties and Helper Methods 160 | 161 | /// Internal structure mapping keys to values. 162 | fileprivate var keysToValues = [Key: Value]() 163 | 164 | /// Internal structure values keys to keys. 165 | fileprivate var valuesToKeys = [Value: Key]() 166 | } 167 | 168 | extension Bimap: Sequence { 169 | 170 | // MARK: Sequence Protocol Conformance 171 | 172 | /// Provides for-in loop functionality. 173 | /// 174 | /// - returns: A generator over the elements. 175 | public func makeIterator() -> DictionaryIterator { 176 | return keysToValues.makeIterator() 177 | } 178 | } 179 | 180 | extension Bimap: Collection { 181 | 182 | 183 | // MARK: Collection Protocol Conformance 184 | 185 | /// The position of the first element in a non-empty bimap. 186 | /// 187 | /// Identical to `endIndex` in an empty bimap 188 | /// 189 | /// Complexity: amortized O(1) 190 | public var startIndex: DictionaryIndex { 191 | return keysToValues.startIndex 192 | } 193 | 194 | /// The collection's "past the end" position. 195 | /// 196 | /// `endIndex` is not a valid argument to `subscript`, and is always 197 | /// reachable from `startIndex` by zero or more applications of 198 | /// `successor()`. 199 | /// 200 | /// Complexity: amortized O(1) 201 | public var endIndex: DictionaryIndex { 202 | return keysToValues.endIndex 203 | } 204 | 205 | /// Returns the position immediately after the given index. 206 | /// 207 | /// - Parameter i: A valid index of the collection. `i` must be less than 208 | /// `endIndex`. 209 | /// - Returns: The index value immediately after `i`. 210 | public func index(after i: DictionaryIndex) -> DictionaryIndex { 211 | return keysToValues.index(after: i) 212 | } 213 | 214 | 215 | public subscript(position: DictionaryIndex) -> (key: Key, value: Value) { 216 | return keysToValues[position] 217 | } 218 | } 219 | 220 | extension Bimap: ExpressibleByDictionaryLiteral { 221 | 222 | // MARK: ExpressibleByDictionaryLiteral Protocol Conformance 223 | 224 | /// Constructs a bimap using a dictionary literal. 225 | public init(dictionaryLiteral elements: (Key, Value)...) { 226 | self.init(elements) 227 | } 228 | } 229 | 230 | extension Bimap: CustomStringConvertible { 231 | 232 | // MARK: CustomStringConvertible Protocol Conformance 233 | 234 | /// A string containing a suitable textual 235 | /// representation of the bimap. 236 | public var description: String { 237 | return keysToValues.description 238 | } 239 | } 240 | 241 | extension Bimap: Hashable { 242 | 243 | // MARK: Hashable Protocol Conformance 244 | 245 | /// The hash value. 246 | /// `x == y` implies `x.hashValue == y.hashValue` 247 | public var hashValue: Int { 248 | var result = 78 249 | for (key, value) in self { 250 | result = (31 ^ result) ^ key.hashValue 251 | result = (31 ^ result) ^ value.hashValue 252 | } 253 | return result 254 | } 255 | } 256 | 257 | // MARK: Bimap Equatable Conformance 258 | 259 | /// Returns `true` if and only if the bimaps contain the same key-value pairs. 260 | public func ==(lhs: Bimap, rhs: Bimap) -> Bool { 261 | if lhs.count != rhs.count{ 262 | return false 263 | } 264 | for (k,v) in lhs { 265 | if rhs[key: k] != v { 266 | return false 267 | } 268 | } 269 | return true 270 | } 271 | 272 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/BinaryHeap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Forked from mauriciosantos/Buckets-Swift/ 24 | 25 | import Foundation 26 | 27 | // Max Heap 28 | struct BinaryHeap : Sequence { 29 | 30 | var isEmpty: Bool { 31 | return items.isEmpty 32 | } 33 | var count: Int { 34 | return items.count 35 | } 36 | var max: T? { 37 | return items.first 38 | } 39 | 40 | // returns true if the first argument has the highest priority 41 | fileprivate let isOrderedBefore: (T,T) -> Bool 42 | fileprivate var items = [T]() 43 | 44 | init(compareFunction: @escaping (T,T) -> Bool) { 45 | isOrderedBefore = compareFunction 46 | } 47 | 48 | mutating func insert(_ element: T) { 49 | items.append(element) 50 | siftUp() 51 | } 52 | 53 | mutating func removeMax() -> T? { 54 | if !isEmpty { 55 | let value = items[0] 56 | items[0] = items[count - 1] 57 | items.removeLast() 58 | if !isEmpty { 59 | siftDown() 60 | } 61 | return value 62 | } 63 | return nil 64 | } 65 | 66 | mutating func removeAll(keepingCapacity keep: Bool = false) { 67 | items.removeAll(keepingCapacity: keep) 68 | } 69 | 70 | func makeIterator() -> AnyIterator { 71 | return AnyIterator(items.makeIterator()) 72 | } 73 | 74 | fileprivate mutating func siftUp() { 75 | func parent(_ index: Int) -> Int { 76 | return (index - 1) / 2 77 | } 78 | 79 | var i = count - 1 80 | var parentIndex = parent(i) 81 | while i > 0 && !isOrderedBefore(items[parentIndex], items[i]) { 82 | swap(&items[i], &items[parentIndex]) 83 | i = parentIndex 84 | parentIndex = parent(i) 85 | } 86 | } 87 | 88 | fileprivate mutating func siftDown() { 89 | // Returns the index of the maximum element if it exists, otherwise -1 90 | func maxIndex(_ i: Int, _ j: Int) -> Int { 91 | if j >= count && i >= count { 92 | return -1 93 | } else if j >= count && i < count { 94 | return i 95 | } else if isOrderedBefore(items[i], items[j]) { 96 | return i 97 | } else { 98 | return j 99 | } 100 | } 101 | 102 | func leftChild(_ index: Int) -> Int { 103 | return (2 * index) + 1 104 | } 105 | 106 | func rightChild(_ index: Int) -> Int { 107 | return (2 * index) + 2 108 | } 109 | 110 | var i = 0 111 | var max = maxIndex(leftChild(i), rightChild(i)) 112 | while max >= 0 && !isOrderedBefore(items[i], items[max]) { 113 | swap(&items[max], &items[i]) 114 | i = max 115 | max = maxIndex(leftChild(i), rightChild(i)) 116 | } 117 | } 118 | } 119 | 120 | // MARK: Heap Operators 121 | 122 | /// Returns `true` if and only if the heaps contain the same elements 123 | /// in the same order. 124 | /// The underlying elements must conform to the `Equatable` protocol. 125 | func ==(lhs: BinaryHeap, rhs: BinaryHeap) -> Bool { 126 | return lhs.items.sorted(by: lhs.isOrderedBefore) == rhs.items.sorted(by: rhs.isOrderedBefore) 127 | } 128 | 129 | func !=(lhs: BinaryHeap, rhs: BinaryHeap) -> Bool { 130 | return !(lhs==rhs) 131 | } 132 | 133 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/BinarySearchTree.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | 24 | import Foundation 25 | 26 | fileprivate func < (lhs: T?, rhs: T?) -> Bool { 27 | switch (lhs, rhs) { 28 | case let (l?, r?): 29 | return l < r 30 | case (nil, _?): 31 | return true 32 | default: 33 | return false 34 | } 35 | } 36 | 37 | fileprivate func > (lhs: T?, rhs: T?) -> Bool { 38 | switch (lhs, rhs) { 39 | case let (l?, r?): 40 | return l > r 41 | default: 42 | return rhs < lhs 43 | } 44 | } 45 | 46 | 47 | indirect public enum BinarySearchTree: Sequence, ExpressibleByArrayLiteral { 48 | 49 | public typealias Element = T 50 | 51 | /// A node with data 52 | case node(value: T, left: BinarySearchTree, right: BinarySearchTree) 53 | 54 | /// Empty node 55 | case Empty 56 | 57 | /// Conforming types can be initialized with array literals. 58 | public init(arrayLiteral elements: Element...) { 59 | func create(_ array: [T], start: Int, end: Int) -> BinarySearchTree { 60 | if abs(end - start) == 1 { 61 | return BinarySearchTree.node(value: array[start], left: .Empty, right: .Empty) 62 | } 63 | let mid = (start + end)/2 64 | let tree = BinarySearchTree.node(value: array[mid], 65 | left: create(array, start: start, end: mid-1), 66 | right: create(array, start: mid+1, end: end)) 67 | return tree 68 | } 69 | self = create(elements.sorted(), start: 0, end: elements.count-1) 70 | } 71 | 72 | /// Wether this is an empty node or not 73 | public var empty: Bool { 74 | get { 75 | switch self { 76 | case .Empty: return true 77 | default: return false 78 | } 79 | } 80 | } 81 | 82 | /// The value associated to this node 83 | public var value: T? { 84 | get { 85 | switch self { 86 | case .node(let value, _, _): return value 87 | default: return nil 88 | } 89 | } 90 | } 91 | 92 | fileprivate var left: BinarySearchTree? { 93 | get { 94 | switch self { 95 | case .node(_, let left, _): return left 96 | default: return nil 97 | } 98 | } 99 | } 100 | 101 | fileprivate var right: BinarySearchTree? { 102 | get { 103 | switch self { 104 | case .node(_, _, let right): return right 105 | default: return nil 106 | } 107 | } 108 | } 109 | 110 | /// Returns the height of this tree 111 | ///- Complexity: O(n) 112 | public func height() -> Int { 113 | func heightRecursive(tree: BinarySearchTree) -> Int { 114 | switch tree { 115 | case .Empty: return 0 116 | case .node(_, let left, let right): 117 | let left = heightRecursive(tree: left) 118 | let right = heightRecursive(tree: right) 119 | return (left > right ? left : right) + 1 120 | } 121 | } 122 | return heightRecursive(tree: self) 123 | } 124 | 125 | /// A balanced tree is defined to be a tree such that the heights of the two 126 | /// subtrees of any node never differ by more than one 127 | ///- Complexity: O(n) 128 | public func balanced() -> Bool { 129 | switch self { 130 | case .Empty: 131 | return true 132 | case .node(_, let left, let right): 133 | return abs(left.height() - right.height()) <= 1 134 | } 135 | } 136 | 137 | /// Returns the index for the seearched document, NSNotFound otherwise 138 | ///- Complexity: O(logn) 139 | public func indexOf(_ element: T) -> (Int, BinarySearchTree) { 140 | 141 | var queue = [BinarySearchTree]() 142 | queue.enqueue(self) 143 | 144 | var idx = 0 145 | while !queue.isEmpty { 146 | 147 | let node = queue.dequeue()! 148 | switch node { 149 | case .Empty: 150 | return (NSNotFound, .Empty) 151 | case .node(let value, let left, let right): 152 | if (value == element) { 153 | return (idx, node) 154 | 155 | } else if element < value && !left.empty { 156 | queue.enqueue(left) 157 | 158 | } else if element > value && !right.empty { 159 | queue.enqueue(right) 160 | } 161 | } 162 | idx += 1 163 | } 164 | 165 | return (NSNotFound, .Empty) 166 | } 167 | 168 | fileprivate func leftmostNode() -> BinarySearchTree { 169 | var current = self 170 | while let left = current.left { 171 | current = left 172 | } 173 | return current 174 | } 175 | 176 | /// Returns the successor of the node passed in as argument 177 | /// Call this method on the root 178 | public func inorderSuccessor(_ node: BinarySearchTree) -> BinarySearchTree? { 179 | 180 | if let right = node.right { 181 | return right.leftmostNode() 182 | } 183 | 184 | var succ: BinarySearchTree? = nil 185 | var root: BinarySearchTree? = self 186 | while let r = root , !r.empty { 187 | 188 | if node.value < r.value { 189 | succ = r 190 | root = r.left 191 | 192 | } else if node.value > r.value { 193 | root = r.right 194 | 195 | } else { 196 | break 197 | } 198 | } 199 | 200 | return succ 201 | } 202 | 203 | 204 | // MARK: Trasversal 205 | 206 | /// Returns a list of tree levels 207 | ///- Complexity: O(n) 208 | public func elementsAtLevel() -> [[T]] { 209 | var result = [[T]]() 210 | var current = [T]() 211 | 212 | var queue = Array<(node: BinarySearchTree, marker: Bool)>() 213 | queue.enqueue((self, false)) 214 | 215 | // marker 216 | queue.enqueue((BinarySearchTree.Empty, true)) 217 | 218 | while !queue.isEmpty { 219 | 220 | let item = queue.dequeue()! 221 | 222 | if item.marker && !queue.isEmpty { 223 | result.append(current) 224 | current = [T]() 225 | queue.enqueue((BinarySearchTree.Empty, true)) 226 | 227 | } else { 228 | switch item.node { 229 | case .Empty: break 230 | case .node(let value, let left, let right): 231 | current.append(value) 232 | queue.enqueue((left, false)) 233 | queue.enqueue((right, false)) 234 | } 235 | } 236 | } 237 | 238 | return result 239 | } 240 | 241 | /// Performs a visit inorder of the tree 242 | public func inorder() -> [T] { 243 | func visit(_ node: BinarySearchTree, result: inout [T]) { 244 | switch node { 245 | case .Empty: return 246 | case .node(let value, let left, let right): 247 | visit(left, result: &result) 248 | result.append(value) 249 | visit(right, result: &result) 250 | } 251 | } 252 | 253 | var result = [T]() 254 | visit(self, result: &result) 255 | return result 256 | } 257 | 258 | /// Performs a visit postorder of the tree 259 | public func postorder() -> [T] { 260 | func visit(_ node: BinarySearchTree, result: inout [T]) { 261 | switch node { 262 | case .Empty: return 263 | case .node(let value, let left, let right): 264 | visit(left, result: &result) 265 | visit(right, result: &result) 266 | result.append(value) 267 | } 268 | } 269 | 270 | var result = [T]() 271 | visit(self, result: &result) 272 | return result 273 | } 274 | 275 | /// Performs a visit preorder of the tree 276 | public func preorder() -> [T] { 277 | func visit(_ node: BinarySearchTree, result: inout [T]) { 278 | switch node { 279 | case .Empty: return 280 | case .node(let value, let left, let right): 281 | result.append(value) 282 | visit(left, result: &result) 283 | visit(right, result: &result) 284 | } 285 | } 286 | 287 | var result = [T]() 288 | visit(self, result: &result) 289 | return result 290 | } 291 | 292 | 293 | public typealias Iterator = BinarySearchTreeGenerator 294 | 295 | /// Return a *generator* over the elements of this *sequence*. 296 | public func makeIterator() -> Iterator { 297 | return BinarySearchTreeGenerator(node: self) 298 | } 299 | } 300 | 301 | public struct BinarySearchTreeGenerator: IteratorProtocol { 302 | 303 | public typealias Element = T 304 | fileprivate let list: [T] 305 | fileprivate var index = 0 306 | 307 | fileprivate init(node: BinarySearchTree) { 308 | self.list = node.inorder() 309 | } 310 | 311 | ///Advance to the next element and return it, or `nil` if no next element exists. 312 | public mutating func next() -> Element? { 313 | if self.index < self.list.count { 314 | let result = self.list[index] 315 | index += 1 316 | return result 317 | } 318 | return nil 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/BitArray.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Forked from mauriciosantos/Buckets-Swift/ 24 | 25 | /// An array of boolean values stored 26 | /// using individual bits, thus providing a 27 | /// very small memory footprint. It has most of the features of a 28 | /// standard array such as constant time random access and 29 | /// amortized constant time insertion at the end of the array. 30 | /// 31 | /// Conforms to `MutableCollection`, `ExpressibleByArrayLiteral` 32 | /// , `Equatable`, `Hashable`, `CustomStringConvertible` 33 | public struct BitArray { 34 | 35 | // MARK: Creating a BitArray 36 | 37 | /// Constructs an empty bit array. 38 | public init() {} 39 | 40 | /// Constructs a bit array from a `Bool` sequence, such as an array. 41 | public init(_ elements: S) where S.Iterator.Element == Bool { 42 | for value in elements { 43 | append(value) 44 | } 45 | } 46 | 47 | /// Constructs a new bit array from an `Int` array representation. 48 | /// All values different from 0 are considered `true`. 49 | public init(intRepresentation : [Int]) { 50 | bits.reserveCapacity((intRepresentation.count/Constants.IntSize) + 1) 51 | for value in intRepresentation { 52 | append(value != 0) 53 | } 54 | } 55 | 56 | /// Constructs a new bit array with `count` bits set to the specified value. 57 | public init(repeating repeatedValue: Bool, count: Int) { 58 | precondition(count >= 0, "Can't construct BitArray with count < 0") 59 | 60 | let numberOfInts = (count/Constants.IntSize) + 1 61 | let intValue = repeatedValue ? ~0 : 0 62 | bits = [Int](repeating: intValue, count: numberOfInts) 63 | self.count = count 64 | 65 | if repeatedValue { 66 | bits[bits.count - 1] = 0 67 | let missingBits = count % Constants.IntSize 68 | self.count = count - missingBits 69 | for _ in 0..= bits.count { 104 | bits.append(0) 105 | } 106 | setValue(bit, atIndex: count) 107 | count += 1 108 | } 109 | 110 | /// Inserts a bit into the array at a given index. 111 | /// Use this method to insert a new bit anywhere within the range 112 | /// of existing bits, or as the last bit. The index must be less 113 | /// than or equal to the number of bits in the bit array. If you 114 | /// attempt to remove a bit at a greater index, you’ll trigger an error. 115 | public mutating func insert(_ bit: Bool, at index: Int) { 116 | checkIndex(index, lessThan: count + 1) 117 | append(bit) 118 | for i in stride(from: (count - 2), through: index, by: -1) { 119 | let iBit = valueAtIndex(i) 120 | setValue(iBit, atIndex: i+1) 121 | } 122 | setValue(bit, atIndex: index) 123 | 124 | } 125 | 126 | /// Removes the last bit from the bit array and returns it. 127 | /// 128 | /// - returns: The last bit, or nil if the bit array is empty. 129 | @discardableResult 130 | public mutating func removeLast() -> Bool { 131 | if let value = last { 132 | setValue(false, atIndex: count-1) 133 | count -= 1 134 | return value 135 | } 136 | preconditionFailure("Array is empty") 137 | } 138 | 139 | /// Removes the bit at the given index and returns it. 140 | /// The index must be less than the number of bits in the 141 | /// bit array. If you attempt to remove a bit at a 142 | /// greater index, you’ll trigger an error. 143 | @discardableResult 144 | public mutating func remove(at index: Int) -> Bool { 145 | checkIndex(index) 146 | let bit = valueAtIndex(index) 147 | 148 | for i in (index + 1).. Bool { 175 | let indexPath = realIndexPath(logicalIndex) 176 | var mask = 1 << indexPath.bitIndex 177 | mask = mask & bits[indexPath.arrayIndex] 178 | return mask != 0 179 | } 180 | 181 | fileprivate mutating func setValue(_ newValue: Bool, atIndex logicalIndex: Int) { 182 | let indexPath = realIndexPath(logicalIndex) 183 | let mask = 1 << indexPath.bitIndex 184 | let oldValue = mask & bits[indexPath.arrayIndex] != 0 185 | 186 | switch (oldValue, newValue) { 187 | case (false, true): 188 | cardinality += 1 189 | case (true, false): 190 | cardinality -= 1 191 | default: 192 | break 193 | } 194 | 195 | if newValue { 196 | bits[indexPath.arrayIndex] |= mask 197 | } else { 198 | bits[indexPath.arrayIndex] &= ~mask 199 | } 200 | } 201 | 202 | fileprivate func realIndexPath(_ logicalIndex: Int) -> (arrayIndex: Int, bitIndex: Int) { 203 | return (logicalIndex / Constants.IntSize, logicalIndex % Constants.IntSize) 204 | } 205 | 206 | fileprivate func checkIndex(_ index: Int, lessThan: Int? = nil) { 207 | let bound = lessThan == nil ? count : lessThan 208 | precondition(count >= 0 && index < bound!, "Index out of range (\(index))") 209 | } 210 | 211 | // MARK: Constants 212 | 213 | fileprivate struct Constants { 214 | // Int size in bits 215 | static let IntSize = MemoryLayout.size * 8 216 | } 217 | } 218 | 219 | extension BitArray: MutableCollection { 220 | 221 | // MARK: MutableCollection Protocol Conformance 222 | 223 | /// Always zero, which is the index of the first bit when non-empty. 224 | public var startIndex : Int { 225 | return 0 226 | } 227 | 228 | /// Always `count`, which the successor of the last valid 229 | /// subscript argument. 230 | public var endIndex : Int { 231 | return count 232 | } 233 | 234 | /// Returns the position immediately after the given index. 235 | /// 236 | /// - Parameter i: A valid index of the collection. `i` must be less than 237 | /// `endIndex`. 238 | /// - Returns: The index value immediately after `i`. 239 | public func index(after i: Int) -> Int { 240 | return i + 1 241 | } 242 | 243 | /// Provides random access to individual bits using square bracket noation. 244 | /// The index must be less than the number of items in the bit array. 245 | /// If you attempt to get or set a bit at a greater 246 | /// index, you’ll trigger an error. 247 | public subscript(index: Int) -> Bool { 248 | get { 249 | checkIndex(index) 250 | return valueAtIndex(index) 251 | } 252 | set { 253 | checkIndex(index) 254 | setValue(newValue, atIndex: index) 255 | } 256 | } 257 | } 258 | 259 | extension BitArray: ExpressibleByArrayLiteral { 260 | 261 | // MARK: ExpressibleByArrayLiteral Protocol Conformance 262 | 263 | /// Constructs a bit array using a `Bool` array literal. 264 | /// `let example: BitArray = [true, false, true]` 265 | public init(arrayLiteral elements: Bool...) { 266 | bits.reserveCapacity((elements.count/Constants.IntSize) + 1) 267 | for element in elements { 268 | append(element) 269 | } 270 | } 271 | } 272 | 273 | extension BitArray: CustomStringConvertible { 274 | 275 | // MARK: CustomStringConvertible Protocol Conformance 276 | 277 | /// A string containing a suitable textual 278 | /// representation of the bit array. 279 | public var description: String { 280 | return "[" + self.map {"\($0)"}.joined(separator: ", ") + "]" 281 | } 282 | } 283 | 284 | extension BitArray: Equatable { 285 | } 286 | 287 | // MARK: BitArray Equatable Protocol Conformance 288 | 289 | /// Returns `true` if and only if the bit arrays contain the same bits in the same order. 290 | public func ==(lhs: BitArray, rhs: BitArray) -> Bool { 291 | if lhs.count != rhs.count || lhs.cardinality != rhs.cardinality { 292 | return false 293 | } 294 | return lhs.elementsEqual(rhs) 295 | } 296 | 297 | extension BitArray: Hashable { 298 | // MARK: Hashable Protocol Conformance 299 | 300 | /// The hash value. 301 | /// `x == y` implies `x.hashValue == y.hashValue` 302 | public var hashValue: Int { 303 | var result = 43 304 | result = (31 ^ result) ^ count 305 | for element in self { 306 | result = (31 ^ result) ^ element.hashValue 307 | } 308 | return result 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/BloomFilter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Forked from mauriciosantos/Buckets-Swift/ 24 | 25 | import Foundation 26 | 27 | /// A Bloom filter is a probabilistic set designed to check rapidly and memory-efficiently, 28 | /// whether an element is definitely not in the set or may be in the set. The false 29 | /// positive probability is provided at construction time. 30 | /// 31 | /// Inserted elements must conform to the `BloomFilterType` protocol. Types already conforming 32 | /// to the protocol include, but are not limited to: `Int`, `Double` and `String`. 33 | public struct BloomFilter { 34 | 35 | // MARK: Creating a BloomFilter 36 | 37 | /// Creates a Bloom filter with the expected number of elements and a default 38 | /// false positive probability of 3%. 39 | /// Inserting significantly more elements than specified will result a deterioration of the 40 | /// false positive probability. 41 | public init(expectedCount: Int) { 42 | self.init(expectedCount: expectedCount, FPP: Constants.DefaultFPP) 43 | } 44 | 45 | /// Creates a Bloom filter with the expected number of elements and 46 | /// expected false positive probability. 47 | /// Inserting significantly more elements than specified will result in a deterioration of the 48 | /// false positive probability. 49 | public init(expectedCount: Int, FPP: Double) { 50 | if expectedCount < 0 { 51 | fatalError("Can't construct a Bloom filter with expectedCount < 0") 52 | } 53 | if FPP <= 0.0 || FPP >= 1.0 { 54 | fatalError("Can't construct BloomFilter with false positive probability >= 1 or <= 0") 55 | } 56 | 57 | // See: http://en.wikipedia.org/wiki/Bloom_filter for calculations 58 | 59 | let n = Double(expectedCount) 60 | let m = n*log(1/FPP) / pow(log(2), 2) 61 | 62 | let bitArraySize = Int(m) 63 | bits = BitArray(repeating: false, count: bitArraySize) 64 | 65 | let k = (m/n) * log(2) 66 | numberOfHashFunctions = Int(ceil(k)) 67 | 68 | self.FPP = FPP 69 | } 70 | 71 | // MARK: Querying a BloomFilter 72 | 73 | /// The expected false positive probability. 74 | /// In other words, the probability that `contains()` will erroneously return true. 75 | public let FPP: Double 76 | 77 | /// Returns the approximated number of elements in the bloom filter. 78 | public var roughCount: Int { 79 | let count = Double(bits.count) 80 | let bitsSetToOne = Double(bits.cardinality) 81 | let hashFunctions = Double(numberOfHashFunctions) 82 | 83 | let result = -count*log(1.0 - bitsSetToOne/count)/hashFunctions 84 | if !result.isFinite { 85 | return Int.max 86 | } 87 | return Int(min(result, Double(Int.max))) 88 | } 89 | 90 | /// Returns `true` if no element has been inserted into the Bloom filter. 91 | public var isEmpty: Bool { 92 | return bits.cardinality == 0 93 | } 94 | 95 | /// Returns `true` if the given element might be in the Bloom filter or false if 96 | /// it's definitely not. 97 | public func contains(_ element: T) -> Bool { 98 | for i in 0.. (T) -> Int { 135 | let i = UInt(index) 136 | 137 | // Hi(x) = H0(x) + i*H1(x) mod table.size 138 | 139 | return { 140 | let bytes = $0.bytes 141 | return Int((fnv1(bytes) &+ i&*fnv1a(bytes)) % UInt(self.bits.count)) 142 | } 143 | } 144 | } 145 | 146 | // MARK:- Constants 147 | 148 | private struct Constants { 149 | static let DefaultFPP = 0.03 150 | } 151 | 152 | public protocol BloomFilterType { 153 | 154 | /// Returns a data representation of self. 155 | var bytes: Data {get} 156 | } 157 | 158 | 159 | extension Bool: BloomFilterType { 160 | public var bytes: Data {return bytesFromStruct(self)} 161 | } 162 | extension Double: BloomFilterType { 163 | public var bytes: Data {return bytesFromStruct(self)} 164 | } 165 | extension Float: BloomFilterType { 166 | public var bytes: Data {return bytesFromStruct(self)} 167 | } 168 | extension Int: BloomFilterType { 169 | public var bytes: Data {return bytesFromStruct(self)} 170 | } 171 | extension Int8: BloomFilterType { 172 | public var bytes: Data {return bytesFromStruct(self)} 173 | } 174 | extension Int16: BloomFilterType { 175 | public var bytes: Data {return bytesFromStruct(self)} 176 | } 177 | extension Int32: BloomFilterType { 178 | public var bytes: Data {return bytesFromStruct(self)} 179 | } 180 | extension Int64: BloomFilterType { 181 | public var bytes: Data {return bytesFromStruct(self)} 182 | } 183 | extension UInt: BloomFilterType { 184 | public var bytes: Data {return bytesFromStruct(self)} 185 | } 186 | extension UInt8: BloomFilterType { 187 | public var bytes: Data {return bytesFromStruct(self)} 188 | } 189 | extension UInt16: BloomFilterType { 190 | public var bytes: Data {return bytesFromStruct(self)} 191 | } 192 | extension UInt32: BloomFilterType { 193 | public var bytes: Data {return bytesFromStruct(self)} 194 | } 195 | extension UInt64: BloomFilterType { 196 | public var bytes: Data {return bytesFromStruct(self)} 197 | } 198 | extension String: BloomFilterType { 199 | public var bytes: Data {return self.data(using: .utf8)!} 200 | } 201 | 202 | private func bytesFromStruct(_ value: T) -> Data { 203 | var data = Data() 204 | var input = value 205 | let buffer = UnsafeBufferPointer(start: &input, count: 1) 206 | data.append(buffer) 207 | return data 208 | } 209 | 210 | 211 | struct FNVConstants { 212 | 213 | // FNV parameters 214 | 215 | #if arch(arm64) || arch(x86_64) // 64-bit 216 | 217 | static let OffsetBasis: UInt = 14695981039346656037 218 | static let FNVPrime: UInt = 1099511628211 219 | 220 | #else // 32-bit 221 | 222 | static let OffsetBasis: UInt = 2166136261 223 | static let FNVPrime: UInt = 16777619 224 | 225 | #endif 226 | } 227 | 228 | // MARK:- Public API 229 | 230 | /// Calculates FNV-1 hash from a raw byte sequence, such as an array. 231 | func fnv1(_ bytes: S) -> UInt where S.Iterator.Element == UInt8 { 232 | var hash = FNVConstants.OffsetBasis 233 | for byte in bytes { 234 | hash = hash &* FNVConstants.FNVPrime // &* means multiply with overflow 235 | hash ^= UInt(byte) 236 | } 237 | return hash 238 | } 239 | 240 | /// Calculates FNV-1a hash from a raw byte sequence, such as an array. 241 | func fnv1a(_ bytes: S) -> UInt where S.Iterator.Element == UInt8 { 242 | var hash = FNVConstants.OffsetBasis 243 | for byte in bytes { 244 | hash ^= UInt(byte) 245 | hash = hash &* FNVConstants.FNVPrime 246 | } 247 | return hash 248 | } 249 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/DataStructures.h: -------------------------------------------------------------------------------- 1 | // 2 | // DataStructures.h 3 | // DataStructures 4 | // 5 | // Created by Alex Usbergo on 29/12/15. 6 | // Copyright © 2015 Alex Usbergo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for DataStructures. 12 | FOUNDATION_EXPORT double DataStructuresVersionNumber; 13 | 14 | //! Project version string for DataStructures. 15 | FOUNDATION_EXPORT const unsigned char DataStructuresVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/EditDistance.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | 24 | import Foundation 25 | 26 | ///Represent an edit operation 27 | public enum EditDistanceOperation { 28 | 29 | case insertion(source: Int, target: Int) 30 | case removal(source: Int) 31 | case substitution(source: Int, target: Int) 32 | case allChanged 33 | 34 | public static func compute(_ from: [Any], 35 | to: [Any], 36 | comparator:(_ lhs:Any, _ rhs:Any) -> Bool) -> [EditDistanceOperation] { 37 | 38 | let m = from.count + 1 39 | let n = to.count + 1 40 | 41 | if m == 1 || n == 1 { 42 | return [EditDistanceOperation.allChanged] 43 | } 44 | 45 | // for all i and j, d[i,j] will hold the Levenshtein distance between 46 | // the first i characters of s and the first j characters of t; 47 | // note that d has (m+1)*(n+1) values 48 | // set each element to zero 49 | var d = [[Int]](repeating: [Int](repeating: 0, count: n), count: m) 50 | 51 | // source prefixes can be transformed into empty string by 52 | // dropping all characters 53 | for i in 1...m-1 { 54 | d[i][0] = i 55 | } 56 | 57 | // target prefixes can be reached from empty source prefix 58 | // by inserting every character 59 | for j in 1...n-1 { 60 | d[0][j] = j 61 | } 62 | 63 | // create the matrix 64 | for j in 1...n-1 { 65 | for i in 1...m-1 { 66 | 67 | if comparator(from[i-1], to[j-1]) { 68 | 69 | // no operation required 70 | d[i][j] = d[i-1][j-1] 71 | 72 | } else { 73 | 74 | // min(deletion_score, min(insertion_score, substitution_score)) 75 | d[i][j] = min(d[i-1][j], min(d[i][j-1], d[i-1][j-1])) + 1 76 | } 77 | } 78 | } 79 | 80 | // compute minimal set of edit operations 81 | var operations = [EditDistanceOperation]() 82 | 83 | var i = m - 1 84 | var j = n - 1 85 | 86 | while i > 0 || j > 0 { 87 | 88 | // remove, if applicable 89 | let removalScore = i > 0 ? d[i-1][j] : Int.max 90 | 91 | // insertion, if applicable 92 | let insertionScore = j > 0 ? d[i][j-1] : Int.max 93 | 94 | // substituion, if applicable 95 | let substitutionScore = i > 0 && j > 0 ? d[i-1][j-1] : Int.max 96 | 97 | // removal 98 | if (removalScore < insertionScore && removalScore < substitutionScore) { 99 | operations.append(EditDistanceOperation.removal(source: i-1)) 100 | i -= 1 101 | 102 | // insertion 103 | } else if (insertionScore < removalScore && insertionScore < substitutionScore) { 104 | operations.append(EditDistanceOperation.insertion(source: i, target: j-1)) 105 | j -= 1 106 | 107 | // no change 108 | } else if (substitutionScore == d[i][j]) { 109 | i -= 1 110 | j -= 1 111 | 112 | // substitution 113 | } else { 114 | operations.append(EditDistanceOperation.substitution(source: i-1, target: j-1)) 115 | i -= 1 116 | j -= 1 117 | } 118 | } 119 | 120 | return operations 121 | } 122 | 123 | public static func computeObjectArray(_ from: [AnyObject], to: [AnyObject]) -> [EditDistanceOperation] { 124 | 125 | var fromAny = Array() 126 | for obj in from { fromAny.append(obj) } 127 | 128 | var toAny = Array() 129 | for obj in to { toAny.append(obj) } 130 | 131 | return self.compute(fromAny, to: toAny, comparator: { 132 | let l = $0 as AnyObject, r = $1 as AnyObject 133 | return l.isEqual(r); 134 | }) 135 | } 136 | 137 | public static func compute(_ from: [T], to: [T]) -> [EditDistanceOperation] { 138 | 139 | // wraps it in [Any] (due to Swift beta5 bug) 140 | var fromAny = [Any](), toAny = [Any]() 141 | for obj in from { fromAny.append(obj) } 142 | for obj in to { toAny.append(obj) } 143 | 144 | return self.compute(fromAny, to: toAny, comparator: { 145 | let l = $0 as! T, r = $1 as! T 146 | return l == r 147 | }) 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/Graph.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | 24 | import Foundation 25 | 26 | private struct Edge: Equatable { 27 | 28 | ///The vertices associated to this edge 29 | fileprivate var vertices: (from:Vertex, to:Vertex) 30 | 31 | ///The wight for this edge 32 | fileprivate let weight: Double 33 | 34 | ///Creates a new edge 35 | fileprivate init(from: Vertex, to: Vertex, weight: Double = 1) { 36 | self.vertices = (from, to) 37 | self.weight = weight 38 | } 39 | } 40 | 41 | private enum VertexColor: Int { case white, gray, black } 42 | 43 | open class Vertex: Hashable { 44 | 45 | ///The value for the vertex 46 | open let value: T 47 | 48 | ///Wheter this vertex has been visited or not 49 | fileprivate var color = VertexColor.white 50 | 51 | ///The edges from this vertex 52 | fileprivate var edges = [Edge]() 53 | 54 | fileprivate let id: Int = UUID().uuidString.hash 55 | 56 | ///The hash value 57 | open var hashValue: Int { 58 | return id 59 | } 60 | 61 | fileprivate init(value: T) { 62 | self.value = value 63 | } 64 | } 65 | 66 | extension Vertex: CustomStringConvertible { 67 | 68 | ///A textual representation of `self`. 69 | public var description: String { 70 | return "" 71 | } 72 | } 73 | 74 | public func ==(lhs: Vertex, rhs: Vertex) -> Bool { 75 | return lhs.id == rhs.id 76 | } 77 | 78 | private func ==(lhs: Edge, rhs: Edge) -> Bool { 79 | return lhs.vertices.from.value == rhs.vertices.from.value 80 | && rhs.vertices.to.value == rhs.vertices.to.value && lhs.weight == rhs.weight 81 | } 82 | 83 | public struct Graph: ExpressibleByArrayLiteral { 84 | 85 | public typealias Element = T 86 | 87 | ///All the vertices in this graph 88 | public var vertices = [Vertex]() 89 | 90 | ///Wether this is a directed graph or not 91 | public var directed: Bool = false 92 | 93 | ///Wether the graph is weighted or not 94 | public var weighted: Bool = false 95 | 96 | ///The default starting vertex for graph traversals 97 | public var head: Vertex? 98 | 99 | public subscript(index: T) -> [Vertex] { 100 | return vertices.filter() { $0.value == index } 101 | } 102 | 103 | public subscript(index: T) -> Vertex { 104 | return vertices.filter() { $0.value == index }.first! 105 | } 106 | 107 | public subscript(from: T, to:T) -> Double { 108 | 109 | get { 110 | guard let fromVertex: Vertex = self[from], 111 | let toVertex: Vertex = self[to] else { return Double.infinity } 112 | 113 | guard let edge = fromVertex.edges.filter({ return $0.vertices.to == toVertex}).first else { return Double.infinity } 114 | 115 | return edge.weight 116 | } 117 | 118 | set (weight) { 119 | guard let fromVertex: Vertex = self[from], 120 | let toVertex: Vertex = self[to] else { return } 121 | 122 | //creates a edge 123 | self.addEdge(fromVertex, to: toVertex, weight: weight) 124 | } 125 | } 126 | 127 | 128 | /// Create a new instance of the graph 129 | public init(directed: Bool = false, weighted: Bool = false) { 130 | self.directed = directed 131 | self.weighted = weighted 132 | } 133 | 134 | /// Create an instance initialized with `elements`. 135 | public init(arrayLiteral elements: Element...) { 136 | for element in elements { 137 | self.addVertex(element) 138 | } 139 | } 140 | 141 | ///Add a node to the graph 142 | public mutating func addVertex(_ value: T) -> Vertex { 143 | let vertex = Vertex(value: value) 144 | self.vertices.append(vertex) 145 | return vertex 146 | } 147 | 148 | ///Remove a vertex from the graph 149 | public mutating func removeVertext(_ vertex: Vertex) { 150 | 151 | func removeVertexFromEdges(_ fromVertex: Vertex) { 152 | let edges = fromVertex.edges.filter() { return $0.vertices.to != vertex } 153 | fromVertex.edges = edges 154 | } 155 | 156 | for v in self.vertices { 157 | removeVertexFromEdges(v) 158 | } 159 | 160 | self.vertices = self.vertices.filter() { return $0 != vertex } 161 | } 162 | 163 | ///Creates an edge from/to the vertices passed as argument 164 | public func addEdge(_ from: Vertex, to: Vertex, weight: Double = 1) { 165 | 166 | let edge = Edge(from: from, to: to, weight: weight) 167 | from.edges.append(edge) 168 | 169 | if !self.directed { 170 | let reversedEdge = Edge(from: to, to: from, weight: weight) 171 | if !to.edges.contains(reversedEdge) { 172 | to.edges.append(reversedEdge) 173 | } 174 | } 175 | } 176 | 177 | ///Remove an edge from the graph 178 | public func removeEdge(_ from: Vertex, to: Vertex) { 179 | 180 | let edges = from.edges.filter() { return $0.vertices.to != to } 181 | from.edges = edges 182 | 183 | if !self.directed { 184 | let toEdges = to.edges.filter() { return $0.vertices.from != from } 185 | to.edges = toEdges 186 | } 187 | } 188 | 189 | } 190 | 191 | extension Graph { 192 | 193 | ///Performs a bfs search, complexity 194 | ///- Complexity: O(|E|+|V|) 195 | public func traverseBreadthFirst(_ start: Vertex? = nil) -> [Vertex] { 196 | 197 | let head = self.head ?? self.vertices.first 198 | guard let start = start ?? head else { return [Vertex]() } 199 | 200 | var result = [Vertex]() 201 | 202 | var queue = [Vertex]() 203 | queue.enqueue(start) 204 | 205 | while !queue.isEmpty { 206 | 207 | //get a vertex 208 | let vertex = queue.dequeue()! 209 | 210 | for e in vertex.edges { 211 | 212 | //adds the 'to' vertex if the node is node visited yet 213 | if e.vertices.to.color == VertexColor.white { 214 | e.vertices.to.color = VertexColor.gray 215 | queue.enqueue(e.vertices.to) 216 | } 217 | } 218 | 219 | //mark this node as visited 220 | vertex.color = VertexColor.black 221 | result.enqueue(vertex) 222 | } 223 | 224 | //reset the vertices 225 | for vertex in result { 226 | vertex.color = VertexColor.white 227 | } 228 | 229 | return result 230 | } 231 | 232 | ///Performs a dfs search 233 | ///- Complexity: O(|E|+|V|) 234 | public func traverseDepthFirst(_ start: Vertex? = nil) -> [Vertex] { 235 | 236 | let head = self.head ?? self.vertices.first 237 | guard let start = start ?? head else { return [Vertex]() } 238 | 239 | var result = [Vertex]() 240 | 241 | var stack = [Vertex]() 242 | stack.push(start) 243 | 244 | while !stack.isEmpty { 245 | 246 | //get a vertex 247 | let vertex = stack.pop()! 248 | 249 | //mark this node as visited 250 | result.append(vertex) 251 | vertex.color = VertexColor.black 252 | 253 | for e in vertex.edges { 254 | 255 | //adds the 'to' vertex if the node is node visited yet 256 | if e.vertices.to.color == VertexColor.white { 257 | e.vertices.to.color = VertexColor.gray 258 | stack.push(e.vertices.to) 259 | } 260 | } 261 | } 262 | 263 | //reset the vertices 264 | for vertex in result { 265 | vertex.color = VertexColor.white 266 | } 267 | 268 | return result 269 | } 270 | } 271 | 272 | extension Graph: CustomStringConvertible { 273 | 274 | ///A textual representation of `self`. 275 | public var description: String { 276 | return self.map() { return $0 }.description 277 | } 278 | } 279 | 280 | extension Graph: Sequence { 281 | 282 | public typealias Iterator = GraphGenerator 283 | 284 | ///Return a *generator* over the elements of this *sequence*. 285 | public func makeIterator() -> Iterator { 286 | let bfs = self.traverseBreadthFirst(self.head).map() { return $0.value } 287 | return GraphGenerator(bfs: bfs) 288 | } 289 | } 290 | 291 | public struct GraphGenerator: IteratorProtocol { 292 | 293 | public typealias Element = T 294 | 295 | fileprivate let bfs: [Element] 296 | fileprivate var index: Int = 0 297 | 298 | fileprivate init(bfs: [Element]) { 299 | self.bfs = bfs 300 | } 301 | 302 | ///Advance to the next element and return it, or `nil` if no next element exists. 303 | public mutating func next() -> Element? { 304 | if index < bfs.count { 305 | let result = self.bfs[self.index] 306 | self.index += 1 307 | return result 308 | } 309 | return nil 310 | } 311 | } 312 | 313 | //MARK: - Shortest Path 314 | 315 | public struct Path: Equatable { 316 | 317 | ///The cost and the previous cost 318 | public let cost: Double 319 | 320 | ///All the vertices included in the path 321 | public let vertices: [Vertex] 322 | 323 | ///The final destination for this path 324 | public var destination: Vertex? { 325 | return self.vertices.last 326 | } 327 | 328 | fileprivate init(cost: Double, vertices: [Vertex] = [Vertex]()) { 329 | self.cost = cost 330 | self.vertices = vertices 331 | } 332 | 333 | ///Creates a new path to the vertex passed as argument and with the additional cost 334 | fileprivate func appendNew(_ increment: Double, to:Vertex) -> Path { 335 | var v = self.vertices 336 | v.append(to) 337 | return Path(cost: self.cost + increment, vertices: v) 338 | } 339 | } 340 | 341 | extension Path: CustomStringConvertible { 342 | 343 | ///A textual representation of `self`. 344 | public var description: String { 345 | return "" 346 | } 347 | } 348 | 349 | public func ==(lhs: Path, rhs: Path) -> Bool { 350 | return lhs.cost == rhs.cost && lhs.vertices == rhs.vertices 351 | } 352 | 353 | private func +(lhs: Path, rhs:(Double,Vertex)) -> Path { 354 | return lhs.appendNew(rhs.0, to: rhs.1) 355 | } 356 | 357 | extension Graph { 358 | 359 | ///Compute the shortest path from a node to another using Dijkstra's algorithm. 360 | ///- Note: Make sure your graph is a DAG before attempting to compute the shortest path. 361 | /// You can do so by calling the 'isDirectedAcyclic()' method. 362 | ///- Complexity: O(|E|+|V|log|V|) 363 | public func shortestPath(_ from: Vertex, to: Vertex) -> Path? { 364 | 365 | var frontier = PriorityQueue>(sortedBy: { return $0.cost < $1.cost }) 366 | var final = [Path]() 367 | 368 | //use the source edges to create the frontier 369 | for e in from.edges { 370 | frontier.enqueue(Path(cost: e.weight, vertices: [from, e.vertices.to])) 371 | } 372 | 373 | //support path changes using the greedy approach 374 | while !frontier.isEmpty { 375 | 376 | let bestPath = frontier.dequeue() 377 | 378 | //enumerate the bestPath edges 379 | guard let edges = bestPath.destination?.edges else { continue } 380 | 381 | for e in edges { 382 | let path = bestPath + (e.weight, e.vertices.to) 383 | 384 | if !frontier.contains(path) { 385 | frontier.enqueue(path) 386 | } 387 | } 388 | 389 | //preserve the best path 390 | if bestPath.destination == to { 391 | final.append(bestPath) 392 | } 393 | 394 | } 395 | 396 | var shortestPath = Path(cost: Double.infinity) 397 | 398 | for path in final { 399 | if path.destination == to && path.cost < shortestPath.cost { 400 | shortestPath = path 401 | } 402 | } 403 | 404 | //there's no path found 405 | if shortestPath.destination == nil { 406 | return nil 407 | } 408 | 409 | return shortestPath 410 | } 411 | 412 | } 413 | 414 | //MARK: - Topological Sort 415 | 416 | extension Graph where T: Hashable { 417 | 418 | ///Creates a graph with a dependency list 419 | ///e.g: {"foo": ["bar", "baz"], "bar"; ["baz"], "baz": [], "etc": []} 420 | public mutating func populateFromDependencyList(_ dependencyList: [T:[T]]) { 421 | self.directed = true 422 | 423 | //creates all the vertices 424 | for (key,_) in dependencyList { 425 | self.addVertex(key) 426 | } 427 | 428 | //adds the edges from the dependency list 429 | for (key, list) in dependencyList { 430 | for value in list { 431 | self.addEdge(self[key], to: self[value]) 432 | } 433 | } 434 | } 435 | 436 | ///Export the graph into a dependency list. 437 | ///- Note: If this graph is weighted, that information is going to be lost 438 | ///- Note: This method fails if this graph is a undirected one 439 | public func toDependencyList() -> [T: [T]] { 440 | 441 | //A directed graph has a 442 | assert(self.directed) 443 | 444 | var dependencyList = [T: [T]]() 445 | for v in self.vertices { 446 | dependencyList[v.value] = [T]() 447 | } 448 | 449 | for v in self.vertices { 450 | for e in v.edges { 451 | dependencyList[v.value]?.append(e.vertices.to.value) 452 | } 453 | } 454 | 455 | return dependencyList 456 | } 457 | } 458 | 459 | extension Graph { 460 | 461 | ///Returns 'true' if this graph is a directed acyclic graph 462 | ///- Complexity: is O(|E|+|V|) 463 | public func isDirectedAcyclic() -> Bool { 464 | 465 | //not directed 466 | if !self.directed { 467 | return false 468 | } 469 | 470 | do { 471 | 472 | //Try to run a toposort, if there's a cycle an exception is going to be thrown 473 | try self.topologicalSort() 474 | return true 475 | 476 | } catch { 477 | //cycle error 478 | return false 479 | } 480 | } 481 | 482 | ///Topological ordering of a directed graph is a linear ordering of its vertices such that for 483 | ///every directed edge uv from vertex u to vertex v, u comes before v in the ordering. 484 | ///- Complexity: is O(|E|+|V|) 485 | public func topologicalSort() throws -> [Vertex] { 486 | 487 | //Creates a dependency list based on the vertices ids 488 | var dependencyList = [Int: [Int]]() 489 | var map = [Int: Vertex]() 490 | for v in self.vertices { 491 | map[v.id] = v 492 | dependencyList[v.id] = [Int]() 493 | } 494 | 495 | for v in self.vertices { 496 | for e in v.edges { 497 | dependencyList[v.id]?.append(e.vertices.to.id) 498 | } 499 | } 500 | 501 | return try topoSort(dependencyList).map() { return map[$0]! } 502 | } 503 | } 504 | 505 | enum TopologicalSortError : Error { 506 | 507 | ///The dependency list contains a loop 508 | case cycleError(String) 509 | } 510 | 511 | ///General topological sort function 512 | public func topoSort(_ dependencyList:[T:[T]]) throws -> [T] { 513 | 514 | //Simple helper method to check if a dependecy list is empty 515 | func isEmpty(_ graph: [T:[T]]) -> Bool { 516 | for (_, value) in graph { 517 | if value.count > 0 { return false } 518 | } 519 | return true 520 | } 521 | 522 | var sorted: [T] = [] 523 | var nextDepth: [T] = [] 524 | var graph = dependencyList 525 | 526 | for key in graph.keys { if graph[key]! == [] { nextDepth.append(key) } } 527 | for key in nextDepth { graph.removeValue(forKey: key) } 528 | 529 | while nextDepth.count != 0 { 530 | 531 | nextDepth.sort() { return $0 > $1} 532 | let node = nextDepth.removeLast() 533 | 534 | sorted.append(node) 535 | 536 | for key in graph.keys { 537 | 538 | if graph[key]!.filter({ $0 == node}).count > 0 { 539 | graph[key] = graph[key]?.filter({$0 != node}) 540 | if graph[key]?.count == 0 { nextDepth.append(key) } 541 | } 542 | } 543 | } 544 | 545 | if !isEmpty(graph) { throw TopologicalSortError.cycleError("This dependency list contains a cycle") 546 | } else { return sorted } 547 | } 548 | 549 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/LinkedList.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | 24 | import Foundation 25 | 26 | final public class LinkedListNode: HeadLinkedListNode { 27 | 28 | /// The actual payload of the node 29 | public let element: T 30 | 31 | fileprivate init(element: T, linkedList: LinkedList) { 32 | self.element = element; 33 | super.init(linkedList: linkedList) 34 | } 35 | 36 | /// Remove the node 37 | public func remove() { 38 | 39 | // this was the last node 40 | if self.next == nil { 41 | self.linkedList?.current = self.prev 42 | } 43 | 44 | self.linkedList?.count -= 1 45 | self.prev?.next = self.next 46 | 47 | self.linkedList?.__didRemove(self) 48 | } 49 | 50 | /// Insert the node before this 51 | public func inserBefore(_ node: LinkedListNode) { 52 | node.next = self 53 | node.prev = self.prev 54 | self.prev = node 55 | } 56 | } 57 | 58 | open class HeadLinkedListNode { 59 | 60 | // a reference to the linked list 61 | fileprivate var linkedList: LinkedList? 62 | 63 | // the previous and the next node 64 | internal var next: LinkedListNode? 65 | internal var prev: HeadLinkedListNode? 66 | 67 | fileprivate init(linkedList: LinkedList? = nil) { 68 | self.linkedList = linkedList 69 | } 70 | 71 | /// Insert the node passed as argument after this 72 | open func insertAfter(_ node: LinkedListNode) { 73 | 74 | node.prev = self 75 | 76 | // node in-between 77 | if let next = self.next { 78 | node.next = next 79 | 80 | // this is the last node 81 | } else { 82 | self.linkedList?.current = node 83 | } 84 | 85 | self.next = node 86 | self.linkedList?.count += 1 87 | } 88 | } 89 | 90 | //MARK: - LinkedList 91 | 92 | /// All of the operations perform as could be expected for a doubly-linked list. 93 | /// Operations that index into the list will traverse the list from the beginning or the end, 94 | /// whichever is closer to the specified index. 95 | /// Note that this implementation is not synchronized. If multiple threads access a linked 96 | /// list concurrently, 97 | /// and at least one of the threads modifies the list structurally, it must be synchronized 98 | /// externally. 99 | open class LinkedList: ExpressibleByArrayLiteral { 100 | 101 | public typealias Element = T 102 | 103 | /// The element count 104 | open fileprivate(set) var count: UInt = 0 105 | 106 | /// The head of the linked list 107 | internal var head: HeadLinkedListNode 108 | weak fileprivate var current: HeadLinkedListNode? 109 | 110 | open var tail: LinkedListNode? { 111 | return self.current as? LinkedListNode 112 | } 113 | 114 | open subscript(index: UInt) -> T? { 115 | return self.node(forIndex: index)?.element 116 | } 117 | 118 | init() { 119 | self.head = HeadLinkedListNode() 120 | self.current = self.head 121 | self.head.linkedList = self 122 | } 123 | 124 | /// Create an instance initialized with `elements`. 125 | public required convenience init(arrayLiteral elements: Element...) { 126 | self.init() 127 | 128 | for item in elements { 129 | self.append(item) 130 | } 131 | } 132 | 133 | /// Appends an element to the linkedlist 134 | open func append(_ element: T) { 135 | let node = LinkedListNode(element: element, linkedList: self) 136 | self.current?.insertAfter(node) 137 | 138 | self.__didAppend(node) 139 | } 140 | 141 | /// Remove the first element from the list 142 | open func removeFirst() -> T? { 143 | let node = self.head.next 144 | node?.remove() 145 | return node?.element 146 | } 147 | 148 | /// Remove the last element from the list 149 | open func removeLast() -> T? { 150 | guard let node = self.current as? LinkedListNode else { return nil } 151 | node.remove() 152 | return node.element 153 | } 154 | 155 | /// Returns the node at the nth index 156 | open func node(forIndex index: UInt) -> LinkedListNode? { 157 | 158 | //tail 159 | if index == self.count-1 { 160 | return self.current as? LinkedListNode 161 | 162 | //iterate from head 163 | } else if index < self.count/2 { 164 | 165 | var idx: UInt = 0 166 | var node = self.head 167 | 168 | while let n = node.next { 169 | node = n 170 | if idx == index { 171 | idx += 1 172 | return n 173 | } 174 | idx += 1 175 | } 176 | 177 | //iterate from tail 178 | } else { 179 | 180 | var idx: UInt = self.count-1 181 | var node = self.current 182 | 183 | while let n = node?.prev { 184 | node = n 185 | if idx == index { 186 | idx -= 1 187 | return n as? LinkedListNode 188 | } 189 | idx -= 1 190 | } 191 | } 192 | 193 | return nil 194 | } 195 | 196 | /// Remove the node at the given index 197 | open func remove(atIndex index: UInt) { 198 | self.node(forIndex: index)?.remove() 199 | } 200 | 201 | /// Remove all the nodes from the linkedlist 202 | open func removeAll() { 203 | self.head.next = nil 204 | self.current = self.head 205 | self.count = 0 206 | } 207 | 208 | open func toArray() -> [T] { 209 | var array = [T]() 210 | for e in self { array.append(e) } 211 | return array 212 | } 213 | 214 | fileprivate func __didAppend(_ node: LinkedListNode) {} 215 | fileprivate func __didRemove(_ node: LinkedListNode) {} 216 | 217 | public typealias Index = LinkedListIndex 218 | 219 | /// Indexable protocol 220 | 221 | open var startIndex: Index { 222 | return LinkedListIndex(index: 0, node: self.head.next) 223 | } 224 | 225 | open var endIndex: Index { 226 | return LinkedListIndex(index: 0, node: self.current as? LinkedListNode) 227 | } 228 | 229 | open subscript (position: Index) -> Element { 230 | return position.node!.element 231 | } 232 | } 233 | 234 | extension LinkedList where T: Equatable { 235 | 236 | /// Remove the node for the associated element 237 | public func remove(forElement element: T) { 238 | self.node(forElement: element)?.remove() 239 | } 240 | 241 | /// Returns 'true' if the list contains the element, 'false' otherwise 242 | public func contains(_ element: T) -> Bool { 243 | return self.node(forElement: element) != nil 244 | } 245 | 246 | /// Returns the node for the element passed as argument (if it exists) 247 | public func node(forElement element: T) -> LinkedListNode? { 248 | 249 | var node = self.head 250 | while let n = node.next { 251 | node = n 252 | if element == n.element { return n } 253 | } 254 | 255 | return nil 256 | } 257 | 258 | ///Return the index of the element passed as argument 259 | public func index(forElement element: T) -> UInt? { 260 | 261 | var node = self.head 262 | var idx: UInt = 0 263 | while let n = node.next { 264 | node = n 265 | if element == n.element { 266 | return idx 267 | } 268 | idx += 1 269 | } 270 | 271 | return nil 272 | } 273 | } 274 | 275 | extension LinkedList: Sequence { 276 | 277 | public typealias Iterator = LinkedListGenerator 278 | 279 | ///Return a *generator* over the elements of this *sequence*. 280 | public func makeIterator() -> Iterator { 281 | return LinkedListGenerator(linkedList: self) 282 | } 283 | } 284 | 285 | extension LinkedList: CustomStringConvertible { 286 | 287 | ///A textual representation of `self`. 288 | public var description: String { 289 | get { 290 | return self.map() { return $0 }.description 291 | } 292 | } 293 | } 294 | 295 | public struct LinkedListGenerator: IteratorProtocol { 296 | 297 | public typealias Element = T 298 | 299 | fileprivate let linkedList: LinkedList 300 | fileprivate var current: HeadLinkedListNode? 301 | 302 | fileprivate init(linkedList: LinkedList) { 303 | self.linkedList = linkedList 304 | self.current = linkedList.head 305 | } 306 | 307 | ///Advance to the next element and return it, or `nil` if no next element exists. 308 | public mutating func next() -> Element? { 309 | 310 | let node = self.current?.next 311 | self.current = node 312 | return node?.element 313 | } 314 | } 315 | 316 | //MARK: - Index 317 | 318 | public struct LinkedListIndex: Comparable, Equatable, _Incrementable { 319 | /// Returns a Boolean value indicating whether the value of the first 320 | /// argument is less than that of the second argument. 321 | /// 322 | /// This function is the only requirement of the `Comparable` protocol. The 323 | /// remainder of the relational operator functions are implemented by the 324 | /// standard library for any type that conforms to `Comparable`. 325 | /// 326 | /// - Parameters: 327 | /// - lhs: A value to compare. 328 | /// - rhs: Another value to compare. 329 | public static func <(lhs: LinkedListIndex, rhs: LinkedListIndex) -> Bool { 330 | guard let ln = lhs.node, let rn = rhs.node else { return false } 331 | return ln === rn && lhs.index == rhs.index 332 | } 333 | 334 | public typealias Distance = Int 335 | 336 | fileprivate let index: Distance 337 | fileprivate let node: LinkedListNode? 338 | 339 | fileprivate func advanceByOne() -> LinkedListIndex { 340 | guard let node = self.node else { return self } 341 | guard let next = node.next else { return self } 342 | return LinkedListIndex(index: index+1, node: next) 343 | } 344 | 345 | public func advancedBy(_ n: Distance) -> LinkedListIndex { 346 | var result = self 347 | for _ in 0..) -> LinkedListIndex { 352 | return self.advancedBy(n) 353 | } 354 | 355 | public func distanceTo(_ end: LinkedListIndex) -> Distance { 356 | 357 | guard let node = self.node else { return 0 } 358 | 359 | var i = 0 360 | var current = node 361 | while let n = current.next { 362 | current = n 363 | i += 1 364 | } 365 | return i 366 | } 367 | 368 | public func successor() -> LinkedListIndex { 369 | return self.advanceByOne() 370 | } 371 | 372 | } 373 | 374 | public func ==(lhs: LinkedListIndex, rhs: LinkedListIndex) -> Bool { 375 | guard let ln = lhs.node, let rn = rhs.node else { return false } 376 | return ln === rn && lhs.index == rhs.index 377 | } 378 | 379 | //MARK: - SortedLinkedList 380 | 381 | /// A LinkedList where the elment are inserted in order. 382 | /// Use the 'sortClosure' property to define the sort policy 383 | /// Every insertion has complexity O(n) 384 | open class SortedLinkedList: LinkedList { 385 | 386 | /// Set this property to have a custom sort closure. 387 | /// The default one is $0 < $1 388 | open var sortClosure: (T, T) -> Bool = { return $0 < $1 } 389 | 390 | /// Appends the element in the list respecting the order 391 | open override func append(_ element: T) { 392 | 393 | var node = self.head 394 | while let n = node.next { 395 | node = n 396 | if sortClosure(element, n.element) { 397 | n.inserBefore(LinkedListNode(element: element, linkedList: self)) 398 | break 399 | } 400 | } 401 | } 402 | 403 | // /Resort the element passed as argument in the list 404 | open func resort(_ element: T) { 405 | guard let node = self.node(forElement: element) else { return } 406 | node.remove() 407 | self.append(node.element) 408 | } 409 | 410 | /// Resort the whole list 411 | open func resortAll() { 412 | let array = self.toArray() 413 | self.removeAll() 414 | for e in array { self.append(e) } 415 | } 416 | 417 | } 418 | 419 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/Matrix.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Forked from mauriciosantos/Buckets-Swift/ 24 | 25 | /// A Matrix is a fixed size generic 2D collection. 26 | /// You can set and get elements using subscript notation. Example: 27 | /// `matrix[row, column] = value` 28 | /// 29 | /// This collection also provides linear algebra functions and operators such as 30 | /// `inverse()`, `+` and `*` using Apple's Accelerate framework where vailable. Please note that 31 | /// these operations are designed to work exclusively with `Double` matrices. 32 | /// Check the `Functions` section for more information. 33 | /// 34 | /// Conforms to `MutableCollection`, 35 | /// `ExpressibleByArrayLiteral` and `CustomStringConvertible`. 36 | public struct Matrix { 37 | 38 | // MARK: Creating a Matrix 39 | 40 | /// Constructs a new matrix with all positions set to the specified value. 41 | public init(rows: Int, columns: Int, repeating repeatedValue: T) { 42 | precondition(rows >= 0, "Can't create matrix. Invalid number of rows") 43 | precondition(columns >= 0, "Can't create matrix. Invalid number of columns") 44 | 45 | self.rows = rows 46 | self.columns = columns 47 | grid = Array(repeating: repeatedValue, count: rows * columns) 48 | } 49 | 50 | /// Constructs a new matrix using a 1D array in row-major order. 51 | /// `Matrix[i,j] == grid[i*columns + j]` 52 | public init(rows: Int, columns: Int, grid: [T]) { 53 | precondition(grid.count == rows*columns, "") 54 | 55 | self.rows = rows 56 | self.columns = columns 57 | self.grid = grid 58 | } 59 | 60 | /// Constructs a new matrix using a 2D array. 61 | /// All columns must be the same size, otherwise an error is triggered. 62 | public init(_ rowsArray: [[T]]) { 63 | let rows = rowsArray.count 64 | precondition(rows > 0, "Can't create an empty matrix") 65 | precondition(rowsArray[0].count > 0, "Can't create a matrix column with no elements") 66 | 67 | let columns = rowsArray[0].count 68 | for subArray in rowsArray { 69 | if subArray.count != columns { 70 | preconditionFailure("Can't create a matrix with different sized columns") 71 | } 72 | } 73 | var grid = Array() 74 | grid.reserveCapacity(rows*columns) 75 | for i in 0.. { 97 | var result = Matrix(rows: columns, columns: rows, repeating: self[0,0]) 98 | for i in 0.. T { 112 | get { 113 | precondition(indexIsValidForRow(row, column: column), "Index out of range") 114 | return grid[(row * columns) + column] 115 | } 116 | set { 117 | precondition(indexIsValidForRow(row, column: column), "Index out of range") 118 | grid[(row * columns) + column] = newValue 119 | } 120 | } 121 | 122 | // MARK: Private Properties and Helper Methods 123 | 124 | fileprivate func indexIsValidForRow(_ row: Int, column: Int) -> Bool { 125 | return row >= 0 && row < rows && column >= 0 && column < columns 126 | } 127 | } 128 | 129 | 130 | extension Matrix: MutableCollection { 131 | 132 | 133 | // MARK: MutableCollectionType Protocol Conformance 134 | 135 | public typealias MatrixIndex = Int 136 | 137 | /// Always zero, which is the index of the first element when non-empty. 138 | public var startIndex : MatrixIndex { 139 | return 0 140 | } 141 | 142 | /// Always `rows*columns`, which is the successor of the last valid subscript argument. 143 | public var endIndex : MatrixIndex { 144 | return rows*columns 145 | } 146 | 147 | /// Returns the position immediately after the given index. 148 | /// - Parameter i: A valid index of the collection. `i` must be less than 149 | /// `endIndex`. 150 | /// - Returns: The index value immediately after `i`. 151 | public func index(after i: Int) -> Int { 152 | return i + 1 153 | } 154 | 155 | /// Provides random access to elements using the matrix back-end array coordinate 156 | /// in row-major order. 157 | /// Matrix[row, column] is preferred. 158 | public subscript(position: MatrixIndex) -> T { 159 | get { 160 | return self[position/columns, position % columns] 161 | } 162 | set { 163 | self[position/columns, position % columns] = newValue 164 | } 165 | } 166 | } 167 | 168 | extension Matrix: ExpressibleByArrayLiteral { 169 | 170 | // MARK: ExpressibleByArrayLiteral Protocol Conformance 171 | 172 | /// Constructs a matrix using an array literal. 173 | public init(arrayLiteral elements: Array...) { 174 | self.init(elements) 175 | } 176 | } 177 | 178 | extension Matrix: CustomStringConvertible { 179 | 180 | // MARK: CustomStringConvertible Protocol Conformance 181 | 182 | /// A string containing a suitable textual 183 | /// representation of the matrix. 184 | public var description: String { 185 | var result = "[" 186 | for i in 0..(lhs: Matrix, rhs: Matrix) -> Bool { 205 | return lhs.columns == rhs.columns && lhs.rows == rhs.rows && 206 | lhs.grid == rhs.grid 207 | } 208 | 209 | public func !=(lhs: Matrix, rhs: Matrix) -> Bool { 210 | return !(lhs == rhs) 211 | } 212 | 213 | #if os(OSX) || os(iOS) 214 | import Foundation 215 | import Accelerate 216 | 217 | // MARK: Matrix Linear Algebra Operations 218 | 219 | // Inversion 220 | 221 | /// Returns the inverse of the given matrix or nil if it doesn't exist. 222 | /// If the argument is a non-square matrix an error is triggered. 223 | public func inverse(_ matrix: Matrix) -> Matrix? { 224 | if matrix.columns != matrix.rows { 225 | fatalError("Can't invert a non-square matrix.") 226 | } 227 | var invMatrix = matrix 228 | var N = __CLPK_integer(sqrt(Double(invMatrix.grid.count))) 229 | var pivots = [__CLPK_integer](repeating: 0, count: Int(N)) 230 | var workspace = [Double](repeating: 0.0, count: Int(N)) 231 | var error : __CLPK_integer = 0 232 | // LU factorization 233 | dgetrf_(&N, &N, &invMatrix.grid, &N, &pivots, &error) 234 | if error != 0 { 235 | return nil 236 | } 237 | // Matrix inversion 238 | dgetri_(&N, &invMatrix.grid, &N, &pivots, &workspace, &N, &error) 239 | if error != 0 { 240 | return nil 241 | } 242 | return invMatrix 243 | } 244 | 245 | // Addition 246 | 247 | /// Performs matrix and matrix addition. 248 | public func +(lhs: Matrix, rhs: Matrix) -> Matrix { 249 | if lhs.rows != rhs.rows || lhs.columns != rhs.columns { 250 | fatalError("Impossible to add different size matrices") 251 | } 252 | var result = rhs 253 | cblas_daxpy(Int32(lhs.grid.count), 1.0, lhs.grid, 1, &(result.grid), 1) 254 | return result 255 | } 256 | 257 | /// Performs matrix and matrix addition. 258 | public func +=(lhs: inout Matrix, rhs: Matrix) { 259 | lhs.grid = (lhs + rhs).grid 260 | } 261 | 262 | /// Performs matrix and scalar addition. 263 | public func +(lhs: Matrix, rhs: Double) -> Matrix { 264 | let scalar = rhs 265 | var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeating: scalar) 266 | cblas_daxpy(Int32(lhs.grid.count), 1, lhs.grid, 1, &(result.grid), 1) 267 | return result 268 | } 269 | 270 | /// Performs scalar and matrix addition. 271 | public func +(lhs: Double, rhs: Matrix) -> Matrix { 272 | return rhs + lhs 273 | } 274 | 275 | /// Performs matrix and scalar addition. 276 | public func +=(lhs: inout Matrix, rhs: Double) { 277 | lhs.grid = (lhs + rhs).grid 278 | } 279 | 280 | // Subtraction 281 | 282 | /// Performs matrix and matrix subtraction. 283 | public func -(lhs: Matrix, rhs: Matrix) -> Matrix { 284 | if lhs.rows != rhs.rows || lhs.columns != rhs.columns { 285 | fatalError("Impossible to substract different size matrices.") 286 | } 287 | var result = lhs 288 | cblas_daxpy(Int32(lhs.grid.count), -1.0, rhs.grid, 1, &(result.grid), 1) 289 | return result 290 | } 291 | 292 | /// Performs matrix and matrix subtraction. 293 | public func -=(lhs: inout Matrix, rhs: Matrix) { 294 | lhs.grid = (lhs - rhs).grid 295 | } 296 | 297 | /// Performs matrix and scalar subtraction. 298 | public func -(lhs: Matrix, rhs: Double) -> Matrix { 299 | return lhs + (-rhs) 300 | } 301 | 302 | /// Performs matrix and scalar subtraction. 303 | public func -=(lhs: inout Matrix, rhs: Double) { 304 | lhs.grid = (lhs - rhs).grid 305 | } 306 | 307 | // Negation 308 | 309 | /// Negates all the values in a matrix. 310 | public prefix func -(m: Matrix) -> Matrix { 311 | var result = m 312 | cblas_dscal(Int32(m.grid.count), -1.0, &(result.grid), 1) 313 | return result 314 | } 315 | 316 | // Multiplication 317 | 318 | /// Performs matrix and matrix multiplication. 319 | /// The first argument's number of columns must match the second argument's number of rows, 320 | /// otherwise an error is triggered. 321 | public func *(lhs: Matrix, rhs: Matrix) -> Matrix { 322 | if lhs.columns != rhs.rows { 323 | fatalError("Matrix product is undefined: first.columns != second.rows") 324 | } 325 | var result = Matrix(rows: lhs.rows, columns: rhs.columns, repeating: 0.0) 326 | cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, Int32(lhs.rows), Int32(rhs.columns), 327 | Int32(lhs.columns), 1.0, lhs.grid, Int32(lhs.columns), rhs.grid, Int32(rhs.columns), 328 | 0.0, &(result.grid), Int32(result.columns)) 329 | 330 | return result 331 | } 332 | 333 | /// Performs matrix and scalar multiplication. 334 | public func *(lhs: Matrix, rhs: Double) -> Matrix { 335 | var result = lhs 336 | cblas_dscal(Int32(lhs.grid.count), rhs, &(result.grid), 1) 337 | return result 338 | } 339 | 340 | /// Performs scalar and matrix multiplication. 341 | public func *(lhs: Double, rhs: Matrix) -> Matrix { 342 | return rhs*lhs 343 | } 344 | 345 | /// Performs matrix and scalar multiplication. 346 | public func *=(lhs: inout Matrix, rhs: Double) { 347 | lhs.grid = (lhs*rhs).grid 348 | } 349 | 350 | // Division 351 | 352 | /// Performs matrix and scalar division. 353 | public func /(lhs: Matrix, rhs: Double) -> Matrix { 354 | return lhs * (1/rhs) 355 | } 356 | 357 | /// Performs matrix and scalar division. 358 | public func /=(lhs: inout Matrix, rhs: Double) { 359 | lhs.grid = (lhs/rhs).grid 360 | } 361 | #endif 362 | 363 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/Multimap.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Forked from mauriciosantos/Buckets-Swift/ 24 | 25 | import Foundation 26 | 27 | /// A Multimap is a special kind of dictionary in which each key may be 28 | /// associated with multiple values. This implementation allows duplicate key-value pairs. 29 | /// 30 | /// Comforms to `Sequence`, `ExpressibleByDictionaryLiteral`, 31 | /// `Equatable` and `CustomStringConvertible` 32 | public struct Multimap { 33 | 34 | // MARK: Creating a Multimap 35 | 36 | /// Constructs an empty multimap. 37 | public init() {} 38 | 39 | /// Constructs a multimap from a dictionary. 40 | public init(_ elements: Dictionary) { 41 | for (key ,value) in elements { 42 | insertValue(value, forKey: key) 43 | } 44 | } 45 | 46 | // MARK: Querying a Multimap 47 | 48 | /// Number of key-value pairs stored in the multimap. 49 | public fileprivate(set) var count = 0 50 | 51 | /// Number of distinct keys stored in the multimap. 52 | public var keyCount: Int { 53 | return dictionary.count 54 | } 55 | 56 | /// Returns `true` if and only if `count == 0`. 57 | public var isEmpty: Bool { 58 | return count == 0 59 | } 60 | 61 | /// A sequence containing the multimap's unique keys. 62 | public var keys: AnySequence { 63 | return AnySequence(dictionary.keys) 64 | } 65 | 66 | /// A sequence containing the multimap's values. 67 | public var values: AnySequence { 68 | let selfIterator = makeIterator() 69 | let valueIterator = AnyIterator { selfIterator.next()?.1 } 70 | return AnySequence(valueIterator) 71 | } 72 | 73 | /// Returns an array containing the values associated with the specified key. 74 | /// An empty array is returned if the key does not exist in the multimap. 75 | public subscript(key: Key) -> [Value] { 76 | if let values = dictionary[key] { 77 | return values 78 | } 79 | return [] 80 | } 81 | 82 | /// Returns `true` if the multimap contains at least one key-value pair with the given key. 83 | public mutating func containsKey(_ key: Key) -> Bool { 84 | return dictionary[key] != nil 85 | } 86 | 87 | /// Returns `true` if the multimap contains at least one key-value pair with the given 88 | /// key and value. 89 | public func containsValue(_ value: Value, forKey key: Key) -> Bool { 90 | if let values = dictionary[key] { 91 | return values.contains(value) 92 | } 93 | return false 94 | } 95 | 96 | // MARK: Accessing and Changing Multimap Elements 97 | 98 | /// Inserts a key-value pair into the multimap. 99 | public mutating func insertValue(_ value: Value, forKey key: Key) { 100 | insertValues([value], forKey: key) 101 | 102 | } 103 | 104 | /// Inserts multiple key-value pairs into the multimap. 105 | /// - parameter values: A sequence of values to associate with the given key 106 | public mutating func insertValues(_ values: S, forKey key: Key) 107 | where S.Iterator.Element == Value { 108 | var result = dictionary[key] ?? [] 109 | let originalSize = result.count 110 | result += values 111 | count += result.count - originalSize 112 | if !result.isEmpty { 113 | dictionary[key] = result 114 | } 115 | } 116 | 117 | /// Replaces all the values associated with a given key. 118 | /// If the key does not exist in the multimap, the values are inserted. 119 | /// - parameter values: A sequence of values to associate with the given key 120 | public mutating func replaceValues(_ values: S, forKey key: Key) 121 | where S.Iterator.Element == Value { 122 | removeValuesForKey(key) 123 | insertValues(values, forKey: key) 124 | } 125 | 126 | /// Removes a single key-value pair with the given key and value from the multimap, if it exists. 127 | /// - returns: The removed value, or nil if no matching pair is found. 128 | @discardableResult 129 | public mutating func removeValue(_ value: Value, forKey key: Key) -> Value? { 130 | if var values = dictionary[key] { 131 | if let removeIndex = values.index(of: value) { 132 | let removedValue = values.remove(at: removeIndex) 133 | count -= 1 134 | dictionary[key] = values 135 | return removedValue 136 | } 137 | if values.isEmpty { 138 | dictionary.removeValue(forKey: key) 139 | } 140 | } 141 | return nil 142 | } 143 | 144 | /// Removes all values associated with the given key. 145 | public mutating func removeValuesForKey(_ key: Key) { 146 | if let values = dictionary.removeValue(forKey: key) { 147 | count -= values.count 148 | } 149 | } 150 | 151 | /// Removes all the elements from the multimap, and by default 152 | /// clears the underlying storage buffer. 153 | public mutating func removeAll(keepingCapacity keep: Bool = true) { 154 | dictionary.removeAll(keepingCapacity: keep) 155 | count = 0 156 | } 157 | 158 | // MARK: Private Properties and Helper Methods 159 | 160 | /// Internal dictionary holding the elements. 161 | fileprivate var dictionary = [Key: [Value]]() 162 | } 163 | 164 | extension Multimap: Sequence { 165 | 166 | // MARK: SequenceType Protocol Conformance 167 | 168 | /// Provides for-in loop functionality. 169 | /// - returns: A generator over the elements. 170 | public func makeIterator() -> AnyIterator<(Key,Value)> { 171 | var keyValueGenerator = dictionary.makeIterator() 172 | var index = 0 173 | var pairs = keyValueGenerator.next() 174 | return AnyIterator { 175 | if let tuple = pairs { 176 | let value = tuple.1[index] 177 | index += 1 178 | if index >= tuple.1.count { 179 | index = 0 180 | pairs = keyValueGenerator.next() 181 | } 182 | return (tuple.0, value) 183 | } 184 | return nil 185 | } 186 | } 187 | } 188 | 189 | extension Multimap: ExpressibleByDictionaryLiteral { 190 | 191 | // MARK: DictionaryLiteralConvertible Protocol Conformance 192 | 193 | /// Constructs a multiset using a dictionary literal. 194 | /// Unlike a set, multiple copies of an element are inserted. 195 | public init(dictionaryLiteral elements: (Key, Value)...) { 196 | self.init() 197 | for (key, value) in elements { 198 | insertValue(value, forKey: key) 199 | } 200 | } 201 | } 202 | 203 | extension Multimap: CustomStringConvertible { 204 | 205 | // MARK: CustomStringConvertible Protocol Conformance 206 | 207 | /// A string containing a suitable textual 208 | /// representation of the multimap. 209 | public var description: String { 210 | return "[" + map{"\($0.0): \($0.1)"}.joined(separator: ", ") + "]" 211 | } 212 | } 213 | 214 | extension Multimap: Equatable { 215 | 216 | // MARK: Multimap Equatable Conformance 217 | 218 | /// Returns `true` if and only if the multimaps contain the same key-value pairs. 219 | public static func ==(lhs: Multimap, rhs: Multimap) -> Bool { 220 | if lhs.count != rhs.count || lhs.keyCount != rhs.keyCount { 221 | return false 222 | } 223 | for (key, _) in lhs { 224 | let leftValues = lhs[key] 225 | var rightValues = rhs[key] 226 | if leftValues.count != rightValues.count { 227 | return false 228 | } 229 | for element in leftValues { 230 | if let index = rightValues.index(of: element) { 231 | rightValues.remove(at: index) 232 | } 233 | } 234 | if !rightValues.isEmpty { 235 | return false 236 | } 237 | } 238 | return true 239 | } 240 | } 241 | 242 | 243 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/PriorityQueue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Forked from mauriciosantos/Buckets-Swift/ 24 | 25 | import Foundation 26 | 27 | /// In a priority queue each element is associated with a "priority", 28 | /// elements are dequeued in highest-priority-first order (the 29 | /// elements with the highest priority are dequeued first). 30 | /// The `enqueue` and `dequeue` operations run in O(log(n)) time. 31 | /// Conforms to `Sequence`, `CustomStringConvertible`. 32 | public struct PriorityQueue { 33 | 34 | /// Constructs an empty priority queue using a closure to 35 | /// determine the order of a provided pair of elements. The closure that you supply for 36 | /// `sortedBy` should return a boolean value to indicate whether one element 37 | /// should be before (`true`) or after (`false`) another element using strict weak ordering. 38 | /// See http://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings 39 | /// 40 | /// - parameter sortedBy: Strict weak ordering function checking if the first element 41 | /// has higher priority. 42 | public init(sortedBy sortFunction: @escaping (T,T) -> Bool) { 43 | self.init([], sortedBy: sortFunction) 44 | } 45 | 46 | /// Constructs a priority queue from a sequence, such as an array, using a given closure to 47 | /// determine the order of a provided pair of elements. The closure that you supply for 48 | /// `sortedBy` should return a boolean value to indicate whether one element 49 | /// should be before (`true`) or after (`false`) another element using strict weak ordering. 50 | /// See http://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings 51 | /// 52 | /// - parameter sortedBy: Strict weak ordering function for checking if the first element 53 | /// has higher priority. 54 | public init(_ elements: S, sortedBy sortFunction: @escaping (T,T) -> Bool) 55 | where S.Iterator.Element == T { 56 | heap = BinaryHeap(compareFunction: sortFunction) 57 | for e in elements { 58 | enqueue(e) 59 | } 60 | } 61 | 62 | // MARK: Querying a Priority Queue 63 | 64 | /// Number of elements stored in the priority queue. 65 | public var count: Int { 66 | return heap.count 67 | } 68 | 69 | /// Returns `true` if and only if `count == 0`. 70 | public var isEmpty: Bool { 71 | return count == 0 72 | } 73 | 74 | /// The highest priority element in the queue, or `nil` if the queue is empty. 75 | public var first: T? { 76 | return heap.max 77 | } 78 | 79 | // MARK: Adding and Removing Elements 80 | 81 | /// Inserts an element into the priority queue. 82 | public mutating func enqueue(_ element: T) { 83 | heap.insert(element) 84 | } 85 | 86 | /// Retrieves and removes the highest priority element of the queue. 87 | /// - returns: The highest priority element, or `nil` if the queue is empty. 88 | @discardableResult 89 | public mutating func dequeue() -> T { 90 | precondition(!isEmpty, "Queue is empty") 91 | return heap.removeMax()! 92 | } 93 | 94 | /// Removes all the elements from the priority queue, and by default 95 | /// clears the underlying storage buffer. 96 | public mutating func removeAll(keepingCapacity keep: Bool = false) { 97 | heap.removeAll(keepingCapacity: keep) 98 | } 99 | 100 | // MARK: Private Properties and Helper Methods 101 | 102 | /// Internal structure holding the elements. 103 | fileprivate var heap : BinaryHeap 104 | } 105 | 106 | extension PriorityQueue: Sequence { 107 | 108 | // MARK: Sequence Protocol Conformance 109 | 110 | /// Provides for-in loop functionality. Generates elements in no particular order. 111 | /// - returns: A generator over the elements. 112 | public func makeIterator() -> AnyIterator { 113 | return heap.makeIterator() 114 | } 115 | } 116 | 117 | extension PriorityQueue: CustomStringConvertible { 118 | 119 | // MARK: CustomStringConvertible Protocol Conformance 120 | 121 | /// A string containing a suitable textual 122 | /// representation of the priority queue. 123 | public var description: String { 124 | return "[" + map{"\($0)"}.joined(separator: ", ") + "]" 125 | } 126 | } 127 | 128 | // MARK: - Operators 129 | 130 | // MARK: Priority Queue Operators 131 | 132 | /// Returns `true` if and only if the priority queues contain the same elements 133 | /// in the same order. 134 | /// The underlying elements must conform to the `Equatable` protocol. 135 | public func ==(lhs: PriorityQueue, rhs: PriorityQueue) -> Bool { 136 | return lhs.heap == rhs.heap 137 | } 138 | 139 | public func !=(lhs: PriorityQueue, rhs: PriorityQueue) -> Bool { 140 | return !(lhs==rhs) 141 | } 142 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/QueueExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | 24 | import Foundation 25 | 26 | public protocol Queue { associatedtype Q } 27 | 28 | /// FIFO (first-in first-out) Queue 29 | extension LinkedList: Queue { 30 | 31 | public typealias Q = T 32 | 33 | /// Add this element at the end of the queue 34 | public func enqueue(_ element: Q) { 35 | self.append(element) 36 | } 37 | 38 | /// Returns and remove the first element of the queue 39 | public func dequeue() -> Q? { 40 | return self.removeFirst() 41 | } 42 | 43 | /// Returns the first element of the queue 44 | public func peekQueue() -> Q? { 45 | return self.head.next?.element 46 | } 47 | } 48 | 49 | /// FIFO (first-in first-out) Queue 50 | extension Array: Queue { 51 | 52 | public typealias Q = Element 53 | 54 | // /Add this element at the end of the queue 55 | public mutating func enqueue(_ element: Q) { 56 | self.append(element) 57 | } 58 | 59 | /// Returns and remove the first element of the quemutating ue 60 | public mutating func dequeue() -> Q? { 61 | return self.removeFirst() 62 | } 63 | 64 | /// Returns the first element of the queue 65 | public func peekQueue() -> Q? { 66 | return self.first 67 | } 68 | } 69 | 70 | extension PriorityQueue: Queue { 71 | 72 | public typealias Q = T 73 | 74 | /// Returns the first element of the queue 75 | public func peekQueue() -> Q? { 76 | return self.first 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/RedBlackTree.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | // Forked from https://github.com/oisdk/SwiftDataStructures 24 | // 25 | 26 | import Foundation 27 | 28 | public enum Color { case r, b } 29 | 30 | /// A red-black binary search tree. Adapted from Airspeed Velocity's implementation, 31 | /// Chris Okasaki's Purely Functional Data Structures, and Stefan Kahrs' Red-black RedBlackTrees 32 | // with types, which is implemented in the Haskell standard library. 33 | public enum RedBlackTree : Equatable { 34 | case empty 35 | indirect case node(Color,RedBlackTree,Element,RedBlackTree) 36 | } 37 | 38 | public func ==(lhs: RedBlackTree, rhs: RedBlackTree) -> Bool { 39 | return lhs.elementsEqual(rhs) 40 | } 41 | 42 | // MARK: Initializers 43 | 44 | extension RedBlackTree : ExpressibleByArrayLiteral { 45 | 46 | /// Create an empty `RedBlackTree`. 47 | public init() { self = .empty } 48 | 49 | fileprivate init( 50 | _ x: Element, 51 | color: Color = .b, 52 | left: RedBlackTree = .empty, 53 | right: RedBlackTree = .empty 54 | ) { 55 | self = .node(color, left, x, right) 56 | } 57 | 58 | /// Create a `RedBlackTree` from a sequence 59 | public init(_ seq: S) where S.Iterator.Element == Element { 60 | self.init() 61 | for x in seq { insert(x) } 62 | } 63 | 64 | /// Create a `RedBlackTree` of `elements` 65 | public init(arrayLiteral elements: Element...) { 66 | self.init(elements) 67 | } 68 | } 69 | 70 | extension RedBlackTree: CustomDebugStringConvertible { 71 | 72 | /// A description of `self`, suitable for debugging 73 | public var debugDescription: String { 74 | return Array(self).debugDescription 75 | } 76 | } 77 | 78 | // MARK: Properties 79 | 80 | extension RedBlackTree { 81 | 82 | /// Returns the smallest element in `self` if it's present, or `nil` if `self` is empty 83 | ///- Complexity: O(*log n*) 84 | public var first: Element? { 85 | return minElement() 86 | } 87 | 88 | /// Returns the largest element in `self` if it's present, or `nil` if `self` is empty 89 | ///- Complexity: O(*log n*) 90 | public var last: Element? { 91 | return maxElement() 92 | } 93 | 94 | /// Returns `true` iff `self` is empty 95 | public var isEmpty: Bool { 96 | return self == .empty 97 | } 98 | 99 | /// Returns the number of elements in `self` 100 | ///- Complexity: O(`count`) 101 | public var count: Int { 102 | guard case let .node(_, l, _, r) = self else { return 0 } 103 | return 1 + l.count + r.count 104 | } 105 | } 106 | 107 | // MARK: Balance 108 | 109 | internal enum RedBlackTreeBalance { 110 | case balanced(blackHeight: Int) 111 | case unBalanced 112 | } 113 | 114 | extension RedBlackTree { 115 | internal var isBalanced: Bool { 116 | switch balance { 117 | case .balanced: return true 118 | case .unBalanced: return false 119 | } 120 | } 121 | 122 | internal var color: Color { 123 | if case .node(.r, _, _, _) = self { return .r } 124 | return .b 125 | } 126 | 127 | internal var balance: RedBlackTreeBalance { 128 | guard case let .node(c, l, _, r) = self else { return .balanced(blackHeight: 1) } 129 | if 130 | case let .node(_, _, lx, _) = l, 131 | case let .node(_, _, rx, _) = r 132 | , lx >= rx { return .unBalanced } 133 | guard 134 | case let .balanced(x) = l.balance, 135 | case let .balanced(y) = r.balance 136 | , x == y else { return .unBalanced } 137 | if case .b = c { return .balanced(blackHeight: x + 1) } 138 | guard case .b = l.color, case .b = r.color else { return .unBalanced } 139 | return .balanced(blackHeight: x) 140 | } 141 | 142 | fileprivate func balL() -> RedBlackTree { 143 | switch self { 144 | case let .node(.b, .node(.r, .node(.r, a, x, b), y, c), z, d): 145 | return .node(.r, .node(.b,a,x,b),y,.node(.b,c,z,d)) 146 | case let .node(.b, .node(.r, a, x, .node(.r, b, y, c)), z, d): 147 | return .node(.r, .node(.b,a,x,b),y,.node(.b,c,z,d)) 148 | default: 149 | return self 150 | } 151 | } 152 | 153 | fileprivate func balR() -> RedBlackTree { 154 | switch self { 155 | case let .node(.b, a, x, .node(.r, .node(.r, b, y, c), z, d)): 156 | return .node(.r, .node(.b,a,x,b),y,.node(.b,c,z,d)) 157 | case let .node(.b, a, x, .node(.r, b, y, .node(.r, c, z, d))): 158 | return .node(.r, .node(.b,a,x,b),y,.node(.b,c,z,d)) 159 | default: 160 | return self 161 | } 162 | } 163 | 164 | fileprivate func unbalancedR() -> (result: RedBlackTree, wasBlack: Bool) { 165 | guard case let .node(c, l, x, .node(rc, rl, rx, rr)) = self else { 166 | preconditionFailure( 167 | "Should not call unbalancedR on an empty RedBlackTree or a RedBlackTree with an empty right" 168 | ) 169 | } 170 | switch rc { 171 | case .b: 172 | return (RedBlackTree.node(.b, l, x, .node(.r, rl, rx, rr)).balR(), c == .b) 173 | case .r: 174 | guard case let .node(_, rll, rlx, rlr) = rl else { 175 | preconditionFailure("rl empty") 176 | } 177 | return ( 178 | RedBlackTree.node(.b, 179 | RedBlackTree.node(.b, l, x, .node(.r, rll, rlx, rlr)).balR(), rx, rr), false 180 | ) 181 | } 182 | } 183 | 184 | fileprivate func unbalancedL() -> (result: RedBlackTree, wasBlack: Bool) { 185 | guard case let .node(c, .node(lc, ll, lx, lr), x, r) = self else { 186 | preconditionFailure( 187 | "Should not call unbalancedL on an empty RedBlackTree or a RedBlackTree with an empty left" 188 | ) 189 | } 190 | switch lc { 191 | case .b: 192 | return (RedBlackTree.node(.b, .node(.r, ll, lx, lr), x, r).balL(), c == .b) 193 | case .r: 194 | guard case let .node(_, lrl, lrx, lrr) = lr else { 195 | preconditionFailure("lr empty") 196 | } 197 | return ( 198 | RedBlackTree.node(.b, ll, lx, 199 | RedBlackTree.node(.b, .node(.r, lrl, lrx, lrr), x, r).balL()), false 200 | ) 201 | } 202 | } 203 | } 204 | 205 | // MARK: Contains 206 | 207 | extension RedBlackTree { 208 | 209 | fileprivate func cont(_ x: Element, _ p: Element) -> Bool { 210 | guard case let .node(_, l, y, r) = self else { return x == p } 211 | return x < y ? l.cont(x, p) : r.cont(x, y) 212 | } 213 | 214 | /// Returns `true` iff `self` contains `x` 215 | ///- Complexity: O(*log n*) 216 | public func contains(_ x: Element) -> Bool { 217 | guard case let .node(_, l, y, r) = self else { return false } 218 | return x < y ? l.contains(x) : r.cont(x, y) 219 | } 220 | } 221 | 222 | 223 | extension RedBlackTree { 224 | 225 | fileprivate func ins(_ x: Element) -> RedBlackTree { 226 | guard case let .node(c, l, y, r) = self else { return RedBlackTree(x, color: .r) } 227 | if x < y { return RedBlackTree(y, color: c, left: l.ins(x), right: r).balL() } 228 | if y < x { return RedBlackTree(y, color: c, left: l, right: r.ins(x)).balR() } 229 | return self 230 | } 231 | 232 | /// Inserts `x` into `self 233 | ///- Complexity: O(*log n*) 234 | public mutating func insert(_ x: Element) { 235 | guard case let .node(_, l, y, r) = ins(x) else { 236 | preconditionFailure("ins should not return an empty RedBlackTree") 237 | } 238 | self = .node(.b, l, y, r) 239 | } 240 | } 241 | 242 | extension RedBlackTree : Sequence { 243 | 244 | /// Runs a `RedBlackTreeGenerator` over the elements of `self`. (The elements are presented in 245 | /// order, from smallest to largest) 246 | public func makeIterator() -> RedBlackTreeGenerator { 247 | return RedBlackTreeGenerator(stack: [], curr: self) 248 | } 249 | } 250 | 251 | /// A `Generator` for a RedBlackTree 252 | public struct RedBlackTreeGenerator : IteratorProtocol { 253 | 254 | fileprivate var (stack, curr): ([RedBlackTree], RedBlackTree) 255 | 256 | /// Advance to the next element and return it, or return `nil` if no next element exists. 257 | public mutating func next() -> Element? { 258 | while case let .node(_, l, x, r) = curr { 259 | if case .empty = l { 260 | curr = r 261 | return x 262 | } else { 263 | stack.append(curr) 264 | curr = l 265 | } 266 | } 267 | guard case let .node(_, _, x, r)? = stack.popLast() 268 | else { return nil } 269 | curr = r 270 | return x 271 | } 272 | } 273 | 274 | // MARK: Max, min 275 | 276 | extension RedBlackTree { 277 | 278 | /// Returns the smallest element in `self` if it's present, or `nil` if `self` is empty 279 | ///- Complexity: O(*log n*) 280 | public func minElement() -> Element? { 281 | switch self { 282 | case .empty: return nil 283 | case .node(_, .empty, let e, _): return e 284 | case .node(_, let l, _, _): return l.minElement() 285 | } 286 | } 287 | 288 | /// Returns the largest element in `self` if it's present, or `nil` if `self` is empty 289 | ///- Complexity: O(*log n*) 290 | public func maxElement() -> Element? { 291 | switch self { 292 | case .empty: return nil 293 | case .node(_, _, let e, .empty) : return e 294 | case .node(_, _, _, let r): return r.maxElement() 295 | } 296 | } 297 | 298 | fileprivate func _deleteMin() -> (RedBlackTree, Bool, Element) { 299 | switch self { 300 | case .empty: 301 | preconditionFailure("Should not call _deleteMin on an empty RedBlackTree") 302 | case let .node(.b, .empty, x, .empty): 303 | return (.empty, true, x) 304 | case let .node(.b, .empty, x, .node(.r, rl, rx, rr)): 305 | return (.node(.b, rl, rx, rr), false, x) 306 | case let .node(.r, .empty, x, r): 307 | return (r, false, x) 308 | case let .node(c, l, x, r): 309 | let (l0, d, m) = l._deleteMin() 310 | guard d else { return (.node(c, l0, x, r), false, m) } 311 | let tD = RedBlackTree.node(c, l0, x, r).unbalancedR() 312 | return (tD.0, tD.1, m) 313 | } 314 | } 315 | 316 | /// Removes the smallest element from `self` and returns it if it exists, or returns `nil` 317 | /// if `self` is empty. 318 | ///- Complexity: O(*log n*) 319 | public mutating func popFirst() -> Element? { 320 | guard case .node = self else { return nil } 321 | let (t, _, x) = _deleteMin() 322 | self = t 323 | return x 324 | } 325 | 326 | /// Removes the smallest element from `self` and returns it. 327 | ///- Complexity: O(*log n*) 328 | ///- Precondition: `!self.isEmpty` 329 | public mutating func removeFirst() -> Element? { 330 | guard case .node = self else { return nil } 331 | let (t, _, x) = _deleteMin() 332 | self = t 333 | return x 334 | } 335 | 336 | fileprivate func _deleteMax() -> (RedBlackTree, Bool, Element) { 337 | switch self { 338 | case .empty: 339 | preconditionFailure("Should not call _deleteMax on an empty RedBlackTree") 340 | case let .node(.b, .empty, x, .empty): 341 | return (.empty, true, x) 342 | case let .node(.b, .node(.r, rl, rx, rr), x, .empty): 343 | return (.node(.b, rl, rx, rr), false, x) 344 | case let .node(.r, l, x, .empty): 345 | return (l, false, x) 346 | case let .node(c, l, x, r): 347 | let (r0, d, m) = r._deleteMax() 348 | guard d else { return (.node(c, l, x, r0), false, m) } 349 | let tD = RedBlackTree.node(c, l, x, r0).unbalancedL() 350 | return (tD.0, tD.1, m) 351 | } 352 | } 353 | 354 | /// Removes the largest element from `self` and returns it if it exists, or returns `nil` 355 | /// if `self` is empty. 356 | ///- Complexity: O(*log n*) 357 | public mutating func popLast() -> Element? { 358 | guard case .node = self else { return nil } 359 | let (t, _, x) = _deleteMax() 360 | self = t 361 | return x 362 | } 363 | 364 | /// Removes the largest element from `self` and returns it. 365 | ///- Complexity: O(*log n*) 366 | ///- Precondition: `!self.isEmpty 367 | public mutating func removeLast() -> Element { 368 | let (t, _, x) = _deleteMax() 369 | self = t 370 | return x 371 | } 372 | } 373 | 374 | // MARK: Delete 375 | 376 | extension RedBlackTree { 377 | 378 | fileprivate func del(_ x: Element) -> (RedBlackTree, Bool)? { 379 | guard case let .node(c, l, y, r) = self else { return nil } 380 | 381 | if x < y { 382 | guard let (l0, d) = l.del(x) else { return nil } 383 | let t = RedBlackTree.node(c, l0, y, r) 384 | return d ? t.unbalancedR() : (t, false) 385 | 386 | } else if y < x { 387 | guard let (r0, d) = r.del(x) else { return nil } 388 | let t = RedBlackTree.node(c, l, y, r0) 389 | return d ? t.unbalancedL() : (t, false) 390 | } 391 | 392 | if case .empty = r { 393 | guard case .b = c else { return (l, false) } 394 | if case let .node(.r, ll, lx, lr) = l { return (.node(.b, ll, lx, lr), false) } 395 | return (l, true) 396 | } 397 | 398 | let (r0, d, m) = r._deleteMin() 399 | let t = RedBlackTree.node(c, l, m, r0) 400 | return d ? t.unbalancedL() : (t, false) 401 | } 402 | 403 | /// Removes `x` from `self` and returns it if it is present, or `nil` if it is not 404 | ///- Complexity: O(*log n*) 405 | public mutating func remove(_ x: Element) -> Element? { 406 | guard let (t, _) = del(x) else { return nil } 407 | if case let .node(_, l, y, r) = t { 408 | self = .node(.b, l, y, r) 409 | } else { 410 | self = .empty 411 | } 412 | return x 413 | } 414 | } 415 | 416 | // MARK: Reverse 417 | 418 | extension RedBlackTree { 419 | 420 | /// Returns a sequence of the elements of `self` from largest to smallest 421 | public func reverse() -> ReverseRedBlackTreeGenerator { 422 | return ReverseRedBlackTreeGenerator(stack: [], curr: self) 423 | } 424 | } 425 | 426 | /// A `Generator` for a RedBlackTree, that iterates over it in reverse. 427 | public struct ReverseRedBlackTreeGenerator : IteratorProtocol, Sequence { 428 | 429 | fileprivate var (stack, curr): ([RedBlackTree], RedBlackTree) 430 | 431 | public mutating func next() -> Element? { 432 | while case let .node(_, l, x, r) = curr { 433 | if case .empty = r { 434 | curr = l 435 | return x 436 | } else { 437 | stack.append(curr) 438 | curr = r 439 | } 440 | } 441 | guard case let .node(_, l, x, _)? = stack.popLast() 442 | else { return nil } 443 | curr = l 444 | return x 445 | } 446 | } 447 | 448 | // MARK: Higher-Order 449 | 450 | extension RedBlackTree { 451 | 452 | public func reduce(initial: T, combine: (T, Element) throws -> T) rethrows -> T { 453 | guard case let .node(_, l, x, r) = self else { return initial } 454 | let lx = try l.reduce(initial, combine) 455 | let xx = try combine(lx, x) 456 | let rx = try r.reduce(xx, combine) 457 | return rx 458 | } 459 | 460 | public func forEach(body: (Element) throws -> ()) rethrows { 461 | guard case let .node(_, l, x, r) = self else { return } 462 | try l.forEach(body) 463 | try body(x) 464 | try r.forEach(body) 465 | } 466 | } 467 | 468 | public protocol SetType : Sequence { 469 | 470 | /// Create an empty instance of `self` 471 | init() 472 | 473 | /// Create an instance of `self` containing the elements of `sequence` 474 | init(_ sequence: S) where S.Iterator.Element == Iterator.Element 475 | 476 | /// Remove `x` from `self` and return it if it was present. If not, return `nil`. 477 | mutating func remove(_ x: Iterator.Element) -> Iterator.Element? 478 | 479 | /// Insert `x` into `self` 480 | mutating func insert(_ x: Iterator.Element) 481 | 482 | /// returns `true` iff `self` contains `x` 483 | func contains(_ x: Iterator.Element) -> Bool 484 | 485 | /// Remove the member if it was present, insert it if it was not. 486 | mutating func XOR(_ x: Iterator.Element) 487 | } 488 | 489 | extension SetType { 490 | 491 | /// Return a new SetType with elements that are either in `self` or a finite 492 | /// sequence but do not occur in both. 493 | public func exclusiveOr(_ sequence: S) -> Self 494 | where S.Iterator.Element == Iterator.Element { 495 | var result = self 496 | result.exclusiveOrInPlace(sequence) 497 | return result 498 | } 499 | 500 | /// For each element of a finite sequence, remove it from `self` if it is a 501 | /// common element, otherwise add it to the SetType. 502 | public mutating func exclusiveOrInPlace(_ sequence: S) 503 | where S.Iterator.Element == Iterator.Element { 504 | var seen = Self() 505 | for x in sequence where !seen.contains(x) { 506 | XOR(x) 507 | seen.insert(x) 508 | } 509 | } 510 | 511 | /// Return a new set with elements common to `self` and a finite sequence. 512 | public func intersect(_ sequence: S) -> Self 513 | where S.Iterator.Element == Iterator.Element { 514 | var result = Self() 515 | for x in sequence where contains(x) { result.insert(x) } 516 | return result 517 | } 518 | 519 | /// Remove any elements of `self` that aren't also in a finite sequence. 520 | public mutating func intersectInPlace (_ sequence: S) 521 | where S.Iterator.Element == Iterator.Element { 522 | self = intersect(sequence) 523 | } 524 | 525 | /// Returns true if no elements in `self` are in a finite sequence. 526 | public func isDisjointWith(_ sequence: S) -> Bool 527 | where S.Iterator.Element == Iterator.Element { 528 | return !sequence.contains(where: contains) 529 | } 530 | 531 | /// Returns true if `self` is a superset of a finite sequence. 532 | public func isSupersetOf(_ sequence: S) -> Bool 533 | where S.Iterator.Element == Iterator.Element { 534 | return !sequence.contains { !self.contains($0) } 535 | } 536 | 537 | /// Returns true if `self` is a subset of a finite sequence 538 | public func isSubsetOf(_ sequence: S) -> Bool 539 | where S.Iterator.Element == Iterator.Element { 540 | return Self(sequence).isSupersetOf(self) 541 | } 542 | 543 | /// Return a new SetType with elements in `self` that do not occur 544 | /// in a finite sequence. 545 | public func subtract(_ sequence: S) -> Self 546 | where S.Iterator.Element == Iterator.Element { 547 | var result = self 548 | for x in sequence { result.remove(x) } 549 | return result 550 | } 551 | 552 | /// Remove all elements in `self` that occur in a finite sequence. 553 | public mutating func subtractInPlace(_ sequence: S) 554 | where S.Iterator.Element == Iterator.Element { 555 | for x in sequence { remove(x) } 556 | } 557 | 558 | /// Return a new SetType with items in both `self` and a finite sequence. 559 | public func union(_ sequence: S) -> Self 560 | where S.Iterator.Element == Iterator.Element { 561 | var result = self 562 | for x in sequence { result.insert(x) } 563 | return result 564 | } 565 | 566 | /// Insert the elements of a finite sequence into `self` 567 | public mutating func unionInPlace(_ sequence: S) 568 | where S.Iterator.Element == Iterator.Element { 569 | for x in sequence { insert(x) } 570 | } 571 | } 572 | 573 | extension RedBlackTree: SetType { 574 | 575 | /// Remove the member if it was present, insert it if it was not. 576 | public mutating func XOR(_ x: Element) { 577 | if case nil = remove(x) { insert(x) } 578 | } 579 | } 580 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/StackExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | 24 | import Foundation 25 | 26 | public protocol Stack { associatedtype E } 27 | 28 | /// LIFO (last-in first-out) Stack 29 | extension LinkedList: Stack { 30 | 31 | public typealias E = T 32 | 33 | /// Removes the object at the top of this stack and returns that object as the value 34 | /// of this function. 35 | public func pop() -> E? { 36 | return self.removeLast() 37 | } 38 | 39 | /// Pushes an item onto the top of this stack. 40 | public func push(_ element: E) { 41 | self.append(element) 42 | } 43 | 44 | /// Looks at the object at the top of this stack without removing it from the stack. 45 | public func peekStack() -> E? { 46 | guard let node = self.tail else { return nil } 47 | return node.element 48 | } 49 | } 50 | 51 | ///LIFO (last-in first-out) Stack 52 | extension Array: Stack { 53 | 54 | public typealias E = Element 55 | 56 | /// Removes the object at the top of this stack and returns that object as the value 57 | // of this function. 58 | public mutating func pop() -> E? { 59 | return self.removeLast() 60 | } 61 | 62 | /// Pushes an item onto the top of this stack. 63 | public mutating func push(_ element: E) { 64 | self.append(element) 65 | } 66 | 67 | /// Looks at the object at the top of this stack without removing it from the stack. 68 | public func peekStack() -> E? { 69 | return self.last 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /DataStructures/DataStructures/Trie.swift: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // 23 | 24 | /// A Trie (sometimes called a prefix tree) is used for storing a set of 25 | /// strings compactly and searching for full words or partial prefixes very efficiently. 26 | /// 27 | /// The operations for insertion, removal, lookup, and prefix matching run in O(n) time, 28 | /// where n is the length of the sequence or prefix. 29 | /// 30 | /// Conforms to `CustomStringConvertible`, `Hashable`. 31 | public struct Trie { 32 | 33 | // MARK: Creating a Trie 34 | 35 | /// Constructs an empty Trie. 36 | public init() {} 37 | 38 | /// Constructs a trie from a sequence, such as an array. Inserts all the elements 39 | /// from the given sequence into the trie. 40 | public init(_ elements: S) where S.Iterator.Element == String { 41 | for e in elements { 42 | insert(e) 43 | } 44 | } 45 | 46 | // MARK: Querying a Trie 47 | 48 | /// Number of words stored in the trie. 49 | public fileprivate(set) var count = 0 50 | 51 | /// Returns `true` if and only if `count == 0`. 52 | public var isEmpty: Bool { 53 | return count == 0 54 | } 55 | 56 | /// Reconstructs and returns all the words stored in the trie. 57 | public var elements: [String] { 58 | var emptyGenerator = "".characters.makeIterator() 59 | var result = [String]() 60 | var lastKeys = [Character]() 61 | result.reserveCapacity(count) 62 | findPrefix(&emptyGenerator, charStack: &lastKeys, result: &result, node: root) 63 | return result 64 | } 65 | 66 | /// Returns `true` if the trie contains the given word 67 | /// and it's not just a prefix of another word. 68 | public func contains(_ word: String) -> Bool { 69 | var keys = word.characters.makeIterator() 70 | let nodePair = nodePairForPrefix(&keys, node: root, parent: nil) 71 | return nodePair.endNode?.isWord ?? false 72 | } 73 | 74 | /// Returns `true` if the trie contains at least one word matching the given prefix or if the 75 | /// given prefix is empty. 76 | public func isPrefix(_ prefix: String) -> Bool { 77 | var keys = prefix.characters.makeIterator() 78 | let nodePair = nodePairForPrefix(&keys, node: root, parent: nil) 79 | return nodePair.endNode != nil 80 | } 81 | 82 | /// Returns all the words in the trie matching the given prefix. 83 | public func findPrefix(_ prefix: String) -> [String] { 84 | var prefixKeys = prefix.characters.makeIterator() 85 | var result = [String]() 86 | var lastKeys = [Character]() 87 | findPrefix(&prefixKeys, charStack: &lastKeys, result:&result, node: root) 88 | return result 89 | } 90 | 91 | /// Returns the longest prefix in the trie matching the given word. 92 | /// The returned value is not necessarily a full word in the trie. 93 | public func longestPrefixIn(_ element: String) -> String { 94 | var keys = element.characters.makeIterator() 95 | return longestPrefixIn(&keys, lastChars:[], node: root) 96 | } 97 | 98 | // MARK: Adding and Removing Elements 99 | 100 | /// Inserts the given word into the trie. 101 | /// 102 | /// - returns: `true` if the trie did not already contain the word. 103 | @discardableResult 104 | public mutating func insert(_ word: String) -> Bool { 105 | if !contains(word) { 106 | copyMyself() 107 | var keyGenerator = word.characters.makeIterator() 108 | if insert(&keyGenerator, node: root) { 109 | count += 1 110 | return true 111 | } 112 | } 113 | return false 114 | } 115 | 116 | /// Removes the given word from the trie and returns 117 | /// it if it was present. This does not affect other words 118 | /// matching the given word as a prefix. 119 | @discardableResult 120 | public mutating func remove(_ word: String) -> String? { 121 | if contains(word) { 122 | copyMyself() 123 | var generator = word.characters.makeIterator() 124 | let nodePair = nodePairForPrefix(&generator, node: root, parent: nil) 125 | 126 | if let elementNode = nodePair.endNode , elementNode.isWord { 127 | elementNode.isWord = false 128 | if let parentNode = nodePair.parent, let key = elementNode.key 129 | , elementNode.children.isEmpty { 130 | parentNode.children.removeValue(forKey: key) 131 | } 132 | count -= 1 133 | return word 134 | } 135 | } 136 | return nil 137 | } 138 | 139 | /// Removes all the words from the trie. 140 | public mutating func removeAll() { 141 | root = TrieNode(key: nil) 142 | count = 0 143 | } 144 | 145 | // MARK: Private Properties and Helper Methods 146 | 147 | /// The root node containing an empty word. 148 | fileprivate var root = TrieNode(key: nil) 149 | 150 | /// Returns the node containing the last key of the prefix and its parent. 151 | fileprivate func nodePairForPrefix(_ charGenerator: inout IndexingIterator, 152 | node: TrieNode, 153 | parent: TrieNode?) -> (endNode: TrieNode?, parent: TrieNode?) { 154 | 155 | let nextChar: Character! = charGenerator.next() 156 | if nextChar == nil { 157 | return (node, parent) 158 | } 159 | 160 | if let nextNode = node.children[nextChar] { 161 | return nodePairForPrefix(&charGenerator, node: nextNode, parent: node) 162 | } else { 163 | return (nil, node) 164 | } 165 | } 166 | 167 | fileprivate func findPrefix(_ prefixGenerator: inout IndexingIterator, 168 | charStack: inout [Character], result: inout [String], node: TrieNode){ 169 | 170 | if let key = node.key { 171 | charStack.append(key) 172 | } 173 | if let theKey = prefixGenerator.next() { 174 | if let nextNode = node.children[theKey] { 175 | findPrefix(&prefixGenerator, charStack: &charStack, result:&result, node: nextNode) 176 | } 177 | } else { 178 | if node.isWord { 179 | result.append(String(charStack)) 180 | } 181 | for subNode in node.children.values { 182 | findPrefix(&prefixGenerator, charStack: &charStack, result:&result, node: subNode) 183 | } 184 | } 185 | if let _ = node.key { 186 | charStack.removeLast() 187 | } 188 | } 189 | 190 | fileprivate func longestPrefixIn(_ keyGenerator: inout IndexingIterator, 191 | lastChars: [Character], node: TrieNode) -> String { 192 | let chars: [Character] 193 | if let key = node.key { 194 | chars = lastChars + [key] 195 | } else { 196 | chars = lastChars 197 | } 198 | if let theKey = keyGenerator.next(), let nextNode = node.children[theKey] { 199 | return longestPrefixIn(&keyGenerator, lastChars:chars, node: nextNode) 200 | } 201 | return String(chars) 202 | } 203 | 204 | fileprivate func insert(_ keyGenerator: inout IndexingIterator, 205 | node: TrieNode) -> Bool { 206 | if let nextKey = keyGenerator.next() { 207 | let nextNode = node.children[nextKey] ?? TrieNode(key: nextKey) 208 | node.children[nextKey] = nextNode 209 | return insert(&keyGenerator, node: nextNode ) 210 | } else { 211 | let trieWasModified = node.isWord != true 212 | node.isWord = true 213 | return trieWasModified 214 | } 215 | } 216 | 217 | /// Creates a new copy of the root node and all its sub nodes if there´s 218 | /// more than one strong reference pointing to the root node. 219 | /// 220 | /// The Trie itself is a value type but a TrieNode is a reference type, 221 | /// calling this method ensures copy-on-write behavior. 222 | fileprivate mutating func copyMyself() { 223 | if !isKnownUniquelyReferenced(&root) { 224 | root = deepCopyNode(root) 225 | } 226 | } 227 | 228 | fileprivate func deepCopyNode(_ node: TrieNode) -> TrieNode { 229 | let copy = TrieNode(key: node.key, isWord: node.isWord) 230 | for (key, subNode) in node.children { 231 | copy.children[key] = deepCopyNode(subNode) 232 | } 233 | return copy 234 | } 235 | } 236 | 237 | extension Trie: CustomStringConvertible, CustomDebugStringConvertible { 238 | 239 | // MARK: CustomStringConvertible Protocol Conformance 240 | 241 | /// A string containing a suitable textual 242 | /// representation of the trie. 243 | public var description: String { 244 | return "[" + elements.map {"\($0)"}.joined(separator: ", ") + "]" 245 | } 246 | 247 | // MARK: CustomDebugStringConvertible Protocol Conformance 248 | 249 | /// A string containing a suitable textual representation 250 | /// of the trie when debugging. 251 | public var debugDescription: String { 252 | return description 253 | } 254 | } 255 | 256 | extension Trie: Hashable { 257 | 258 | // MARK: Hashable Protocol Conformance 259 | 260 | /// The hash value. 261 | /// `x == y` implies `x.hashValue == y.hashValue` 262 | public var hashValue: Int { 263 | return hashValue(root) 264 | } 265 | 266 | fileprivate func hashValue(_ node: TrieNode) -> Int { 267 | var result = 71 268 | result = (31 ^ result) ^ node.isWord.hashValue 269 | result = (31 ^ result) ^ (node.key?.hashValue ?? 0) 270 | for (_, subNode) in node.children { 271 | result = (31 ^ result) ^ hashValue(subNode) 272 | } 273 | return result 274 | } 275 | } 276 | 277 | // MARK: Trie Equatable Conformance 278 | 279 | /// Returns `true` if and only if the tries contain the same elements. 280 | public func ==(lhs: Trie, rhs: Trie) -> Bool { 281 | if lhs.count != rhs.count { 282 | return false 283 | } 284 | return lhs.root == rhs.root 285 | } 286 | 287 | 288 | // MARK: - TrieNode 289 | 290 | private class TrieNode: Equatable { 291 | let key: Character? 292 | var isWord : Bool = false 293 | var children = [Character : TrieNode]() 294 | 295 | init(key: Character?, isWord: Bool = false) { 296 | self.key = key 297 | self.isWord = isWord 298 | } 299 | } 300 | 301 | private func ==(lhs: TrieNode, rhs: TrieNode) -> Bool { 302 | if lhs.key != rhs.key || lhs.isWord != rhs.isWord 303 | || lhs.children.count != rhs.children.count { 304 | return false 305 | } 306 | for (key, leftNode) in lhs.children { 307 | if leftNode != rhs.children[key] { 308 | return false 309 | } 310 | } 311 | return true 312 | } 313 | -------------------------------------------------------------------------------- /DataStructures/DataStructuresTests/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/test_output/report.junit: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DataStructures 2 | 3 | [![Swift](https://img.shields.io/badge/swift-3-orange.svg?style=flat)](#) 4 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 5 | [![Build](https://img.shields.io/badge/build-passing-green.svg?style=flat)](#) 6 | [![Build](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://opensource.org/licenses/MIT) 7 | 8 | A collection of data structures implemented in Swift. 9 | 10 | 11 | The available data structures are: 12 | 13 | - LinkedList 14 | - SortedLinkedList 15 | - Stack 16 | - Queue 17 | - Graph 18 | - BinaryHeap 19 | - PriorityQueue* 20 | - BloomFilter* 21 | - Trie* 22 | - Multimap* 23 | - Bimap* 24 | - Bag 25 | - BinarySearchTree 26 | - RedBlackTree* 27 | - AVLTree 28 | 29 | ## Installation 30 | 31 | ### Carthage 32 | 33 | To install Carthage, run (using Homebrew): 34 | 35 | ```bash 36 | $ brew update 37 | $ brew install carthage 38 | ``` 39 | 40 | Then add the following line to your `Cartfile`: 41 | 42 | ``` 43 | github "alexdrone/DataStructures" "master" 44 | ``` 45 | 46 | ## Usage 47 | 48 | All collection types are implemented as structures with the exception of the LinkedList data structure. This means they are copied when they are assigned to a new constant or variable, or when they are passed to a function or method. 49 | 50 | About copying structs: 51 | 52 | > The behavior you see in your code will always be as if a copy took place. However, Swift only performs an actual copy behind the scenes when it is absolutely necessary to do so. Swift manages all value copying to ensure optimal performance, and you should not avoid assignment to try to preempt this optimization. 53 | 54 | ## Data Structures 55 | 56 | #### LinkedList 57 | 58 | All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index. 59 | 60 | Note that this implementation is not synchronized. If multiple threads access a linked list concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. 61 | 62 | ```swift 63 | let linkedList = LinkedList() 64 | linkedList.append(1) 65 | linkedList.append(2) 66 | 67 | print(linkedList) //[1,2] 68 | 69 | let sortedLinkedList = SortedLinkedList() 70 | linkedList.append(3) 71 | linkedList.append(1) 72 | linkedList.append(2) 73 | 74 | print(sortedLinkedList) //[1,2,3] 75 | 76 | ``` 77 | 78 | #### Graph 79 | 80 | A graph can be constructed from a array literal, or a dependency list. 81 | Operations like *BFS* and *DFS* visit, *shortestPath* and *topologicalSort* are available to the user. 82 | 83 | Note that this implementation is not synchronized, it must be synchronized externally. 84 | 85 | ```swift 86 | //Graph (graphs can be directed/undirected and weighted/not weighted) 87 | var graph = Graph(arrayLiteral: 1,7,4,3,5,2,6) 88 | 89 | graph.addEdge(graph[1], to: graph[2]) 90 | graph.addEdge(graph[1], to: graph[3]) 91 | graph.addEdge(graph[1], to: graph[5]) 92 | graph.addEdge(graph[2], to: graph[4]) 93 | graph.addEdge(graph[4], to: graph[5]) 94 | graph.addEdge(graph[5], to: graph[6]) 95 | 96 | 97 | //bfs visit expected [1, 2, 3, 5, 4, 6] 98 | let bfs = graph.traverseBreadthFirst().map() { return $0.value } 99 | 100 | //shortest path 101 | 102 | var g = Graph(arrayLiteral: 1,7,4,3,5,2,6) 103 | g.directed = true 104 | g.weighted = true 105 | 106 | g.addEdge()g[1], to:g[2], weight: 2) 107 | g.addEdge(g[1], to:g[3], weight: 3) 108 | g.addEdge(g[1], to:g[5], weight: 6) 109 | g.addEdge(g[2], to:g[4], weight: 1) 110 | g.addEdge(g[4], to:g[5], weight: 1) 111 | g.addEdge(g[5], to:g[6], weight: 10) 112 | 113 | //..or you can use the shorthand subscript to create an edge 114 | graph[1,2] = 2 115 | graph[1,3] = 3 116 | graph[1,5] = 6 117 | graph[2,4] = 1 118 | graph[4,5] = 1 119 | graph[5,6] = 10 120 | 121 | //shortest path from 1 to 5, expected [1, 2, 4, 5] with cost 4 122 | let p = g.shortestPath(g[1], to: g[5]) 123 | (p?.vertices.map(){ return $0.value} //[1,2,4,5] 124 | 125 | ///topological sort and cycle check 126 | let noCycle: Dictionary = [ "A": [], "B": [], "C": ["D"], "D": ["A"], "E": ["C", "B"], "F": ["E"] ] 127 | 128 | var g = Graph(directed: true, weighted: false) 129 | g.populateFromDependencyList(noCycle) 130 | 131 | g.isDirectedAcyclic() //true 132 | g.topologicalSort() // ["A", "B", "D", "C", "E", "F"] 133 | 134 | ``` 135 | 136 | #### Stack and Queue 137 | 138 | Stacks and Queues are implemented through Array and LinkedList extension 139 | Note that this implementation is not synchronized, it must be synchronized externally. 140 | 141 | ```swift 142 | 143 | extension LinkedList : Stack { 144 | public func pop() -> T? 145 | public func push(element: T) 146 | public func peekStack() -> T? 147 | } 148 | 149 | extension Array : Stack { 150 | public func pop() -> T? 151 | public func push(element: T) 152 | public func peekStack() -> T? 153 | } 154 | 155 | extension LinkedList: Queue { 156 | public func enqueue(element: Q) 157 | public func dequeue() -> Q? 158 | public func peekQueue() -> Q? 159 | } 160 | 161 | extension Array: Queue { 162 | public func enqueue(element: Q) 163 | public func dequeue() -> Q? 164 | public func peekQueue() -> Q? 165 | } 166 | 167 | ``` 168 | 169 | #### PriorityQueue 170 | An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to the sort closure passed as argument in the constructor. 171 | The head of this queue is the least element with respect to the specified ordering. If multiple elements are tied for least value, the head is one of those elements -- ties are broken arbitrarily. 172 | 173 | Note that this implementation is not synchronized. Multiple threads should not access a PriorityQueue instance concurrently if any of the threads modifies the queue 174 | 175 | ```swift 176 | var pQueue = PriorityQueue(<) 177 | pQueue.enqueue(3) 178 | pQueue.enqueue(1) 179 | pQueue.enqueue(2) 180 | pQueue.dequeue() // 1 181 | 182 | ``` 183 | 184 | #### BloomFilter 185 | 186 | A Bloom filter is a space-efficient probabilistic data structure that is used to test whether an element is a member of a set. False positive matches are possible, but false negatives are not, thus a Bloom filter has a 100% recall rate. In other words, a query returns either "possibly in set" or "definitely not in set". 187 | 188 | ```swift 189 | var bFilter = BloomFilter(expectedCount: 100) 190 | bFilter.insert("a") 191 | bFilter.contains("a") // true 192 | 193 | ``` 194 | 195 | #### Trie 196 | 197 | Is an ordered tree data structure that is used to store a dynamic set or associative array where the keys are strings. 198 | Note that this implementation is not synchronized, it must be synchronized externally. 199 | 200 | ```swift 201 | var trie = Trie() 202 | trie.insert("A") 203 | trie.insert("AB") 204 | trie.findPrefix("A") // ["A", "AB"] 205 | 206 | ``` 207 | #### RedBlackTree 208 | 209 | A red–black tree is a kind of self-balancing binary search tree. 210 | Balance is preserved by painting each node of the tree with one of two colors (typically called 'red' and 'black') in a way that satisfies certain properties, which collectively constrain how unbalanced the tree can become in the worst case. 211 | 212 | 213 | The balancing of the tree is not perfect but it is good enough to allow it to guarantee searching in O(log n) time, where n is the total number of elements in the tree. The insertion and deletion operations, along with the tree rearrangement and recoloring, are also performed in O(log n) time. 214 | 215 | Note that this implementation is not synchronized, it must be synchronized externally. 216 | 217 | ```swift 218 | import DataStructures 219 | 220 | var tree = RedBlackTree(arrayLiteral:[1, 3, 5, 6, 7, 8, 9]) 221 | tree.popFirst() 222 | 223 | ``` 224 | 225 | #### Multimap 226 | 227 | A generalization of a map or associative array data type in which more than one value may be associated with and returned for a given key. 228 | Note that this implementation is not synchronized, it must be synchronized externally. 229 | 230 | 231 | ```swift 232 | var multimap = Multimap() 233 | multimap.insertValue(1, forKey: "a") 234 | multimap.insertValue(5, forKey: "a") 235 | multimap["a"] // [1, 5] 236 | 237 | ``` 238 | 239 | #### Bimap 240 | 241 | A generalization of a map or associative array data type in which more than one value may be associated with and returned for a given key. 242 | Note that this implementation is not synchronized, it must be synchronized externally. 243 | 244 | 245 | ```swift 246 | var bimap = Bimap() 247 | bimap[key: "a"] = 1 248 | bimap[value: 3] = "b" 249 | bimap[value: 1] // "a" 250 | bimap[key: "b"] // 3 251 | 252 | ``` 253 | 254 | #### Bag 255 | 256 | Similar to a set but allows repeated ("equal") values (duplicates). This is used in two distinct senses: either equal values are considered identical, and are simply counted, or equal values are considered equivalent, and are stored as distinct items. 257 | 258 | ```swift 259 | var bag = Bag() 260 | bag.insert("a") 261 | bag.insert("b") 262 | bag.insert("a") 263 | bag.distinctCount // 2 264 | bag.count("a") // 2 265 | 266 | ``` 267 | 268 | ## Additions 269 | 270 | #### Edit Distance for Arrays 271 | 272 | The edit distance is a way of quantifying how dissimilar two arrays are to one another by counting the minimum number of operations required to transform one array into the other 273 | 274 | ```swift 275 | public enum EditDistanceOperation { 276 | 277 | case Insertion(source: Int, target: Int) 278 | case Removal(source: Int) 279 | case Substitution(source: Int, target: Int) 280 | case AllChanged 281 | 282 | public static func compute(from: [T], to: [T]) -> [EditDistanceOperation] 283 | 284 | ``` 285 | 286 | #### Bitmask Operations 287 | 288 | ```swift 289 | public struct BitMask { 290 | 291 | ///Check the bit at the given index 292 | public static func check(n: Int, index: Int) -> Bool 293 | 294 | ///Set the bit to 1 at the index passed as argument 295 | public static func set(n: Int, index: Int) -> Int 296 | 297 | ///Clear the bit passed as argument 298 | public static func clear(n: Int, index: Int) -> Int 299 | } 300 | 301 | ``` 302 | 303 | ## Credits 304 | \* The PriorityQueue,Multimap,Bimap and BloomFilter data structures are forked from the excellent [Buckets](https://github.com/mauriciosantos/Buckets-Swift/) github project. I higly suggest to check it out! 305 | The RedBlackTree datastructure is adapted from [SwiftDataStructures](https://github.com/oisdk/SwiftDataStructures) 306 | --------------------------------------------------------------------------------