Skip to content

Commit 0e361b0

Browse files
authored
Merge pull request kodecocodes#590 from YeralYamil/master
[Swift 4] Update Bucket Search - Update playground source
2 parents 9d22271 + 22984bb commit 0e361b0

File tree

5 files changed

+138
-66
lines changed

5 files changed

+138
-66
lines changed

Bucket Sort/BucketSort.playground/Contents.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ extension Int: IntConvertible, Sortable {
3434
// MARK: Playing code
3535
//////////////////////////////////////
3636

37-
let input = [1, 2, 4, 6, 10]
37+
let input = [1, 2, 4, 6, 10, 5]
3838
var buckets = [Bucket<Int>(capacity: 15), Bucket<Int>(capacity: 15), Bucket<Int>(capacity: 15)]
3939

40-
let sortedElements = bucketSort(elements: input, distributor: RangeDistributor(), sorter: InsertionSorter(), buckets: &buckets)
40+
let sortedElements = bucketSort(input, distributor: RangeDistributor(), sorter: InsertionSorter(), buckets: buckets)
4141

4242
print(sortedElements)

Bucket Sort/BucketSort.playground/Sources/BucketSort.swift

Lines changed: 106 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,81 @@
2121
//
2222

2323
import Foundation
24+
// FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
25+
// Consider refactoring the code to use the non-optional operators.
26+
fileprivate func < <T: Comparable>(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+
// FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
38+
// Consider refactoring the code to use the non-optional operators.
39+
fileprivate func >= <T: Comparable>(lhs: T?, rhs: T?) -> Bool {
40+
switch (lhs, rhs) {
41+
case let (l?, r?):
42+
return l >= r
43+
default:
44+
return !(lhs < rhs)
45+
}
46+
}
2447

2548
//////////////////////////////////////
2649
// MARK: Main algorithm
2750
//////////////////////////////////////
2851

29-
public func bucketSort<T: Sortable>(elements: [T], distributor: Distributor, sorter: Sorter, buckets: inout [Bucket<T>]) -> [T] {
30-
for elem in elements {
31-
distributor.distribute(element: elem, buckets: &buckets)
32-
}
52+
/**
53+
Performs bucket sort algorithm on the given input elements.
54+
[Bucket Sort Algorithm Reference](https://en.wikipedia.org/wiki/Bucket_sort)
55+
56+
- Parameter elements: Array of Sortable elements
57+
- Parameter distributor: Performs the distribution of each element of a bucket
58+
- Parameter sorter: Performs the sorting inside each bucket, after all the elements are distributed
59+
- Parameter buckets: An array of buckets
60+
61+
- Returns: A new array with sorted elements
62+
*/
3363

34-
var results = [T]()
64+
public func bucketSort<T>(_ elements: [T], distributor: Distributor, sorter: Sorter, buckets: [Bucket<T>]) -> [T] {
65+
precondition(allPositiveNumbers(elements))
66+
precondition(enoughSpaceInBuckets(buckets, elements: elements))
67+
68+
var bucketsCopy = buckets
69+
for elem in elements {
70+
distributor.distribute(elem, buckets: &bucketsCopy)
71+
}
72+
73+
var results = [T]()
74+
75+
for bucket in bucketsCopy {
76+
results += bucket.sort(sorter)
77+
}
78+
79+
return results
80+
}
3581

36-
for bucket in buckets {
37-
results += bucket.sort(algorithm: sorter)
38-
}
82+
private func allPositiveNumbers<T: Sortable>(_ array: [T]) -> Bool {
83+
return array.filter { $0.toInt() >= 0 }.count > 0
84+
}
3985

40-
return results
86+
private func enoughSpaceInBuckets<T>(_ buckets: [Bucket<T>], elements: [T]) -> Bool {
87+
let maximumValue = elements.max()?.toInt()
88+
let totalCapacity = buckets.count * (buckets.first?.capacity)!
89+
90+
return totalCapacity >= maximumValue
4191
}
4292

4393
//////////////////////////////////////
4494
// MARK: Distributor
4595
//////////////////////////////////////
4696

4797
public protocol Distributor {
48-
func distribute<T: Sortable>(element: T, buckets: inout [Bucket<T>])
98+
func distribute<T>(_ element: T, buckets: inout [Bucket<T>])
4999
}
50100

51101
/*
@@ -64,24 +114,24 @@ public protocol Distributor {
64114
* By following the formula: element / capacity = #ofBucket
65115
*/
66116
public struct RangeDistributor: Distributor {
67-
68-
public init() {}
69-
70-
public func distribute<T: Sortable>(element: T, buckets: inout [Bucket<T>]) {
71-
let value = element.toInt()
72-
let bucketCapacity = buckets.first!.capacity
73-
74-
let bucketIndex = value / bucketCapacity
75-
buckets[bucketIndex].add(item: element)
76-
}
117+
118+
public init() {}
119+
120+
public func distribute<T>(_ element: T, buckets: inout [Bucket<T>]) {
121+
let value = element.toInt()
122+
let bucketCapacity = buckets.first!.capacity
123+
124+
let bucketIndex = value / bucketCapacity
125+
buckets[bucketIndex].add(element)
126+
}
77127
}
78128

79129
//////////////////////////////////////
80130
// MARK: Sortable
81131
//////////////////////////////////////
82132

83133
public protocol IntConvertible {
84-
func toInt() -> Int
134+
func toInt() -> Int
85135
}
86136

87137
public protocol Sortable: IntConvertible, Comparable {
@@ -92,50 +142,51 @@ public protocol Sortable: IntConvertible, Comparable {
92142
//////////////////////////////////////
93143

94144
public protocol Sorter {
95-
func sort<T: Sortable>(items: [T]) -> [T]
145+
func sort<T: Sortable>(_ items: [T]) -> [T]
96146
}
97147

98148
public struct InsertionSorter: Sorter {
99-
100-
public init() {}
101-
102-
public func sort<T: Sortable>(items: [T]) -> [T] {
103-
var results = items
104-
for i in 0 ..< results.count {
105-
var j = i
106-
while j > 0 && results[j-i] > results[j] {
107-
108-
let auxiliar = results[i]
109-
results[i] = results[j]
110-
results[j] = auxiliar
111-
112-
j -= 1
113-
}
149+
150+
public init() {}
151+
152+
public func sort<T: Sortable>(_ items: [T]) -> [T] {
153+
var results = items
154+
for i in 0 ..< results.count {
155+
var j = i
156+
while j > 0 && results[j-1] > results[j] {
157+
158+
let auxiliar = results[j-1]
159+
results[j-1] = results[j]
160+
results[j] = auxiliar
161+
162+
j -= 1
163+
}
164+
}
165+
return results
114166
}
115-
return results
116-
}
117167
}
118168

119169
//////////////////////////////////////
120170
// MARK: Bucket
121171
//////////////////////////////////////
122172

123173
public struct Bucket<T: Sortable> {
124-
var elements: [T]
125-
let capacity: Int
126-
127-
public init(capacity: Int) {
128-
self.capacity = capacity
129-
elements = [T]()
130-
}
131-
132-
public mutating func add(item: T) {
133-
if elements.count < capacity {
134-
elements.append(item)
174+
var elements: [T]
175+
let capacity: Int
176+
177+
public init(capacity: Int) {
178+
self.capacity = capacity
179+
elements = [T]()
180+
}
181+
182+
public mutating func add(_ item: T) {
183+
if elements.count < capacity {
184+
elements.append(item)
185+
}
186+
}
187+
188+
public func sort(_ algorithm: Sorter) -> [T] {
189+
return algorithm.sort(elements)
135190
}
136-
}
137-
138-
public func sort(algorithm: Sorter) -> [T] {
139-
return algorithm.sort(items: elements)
140-
}
141191
}
192+

Bucket Sort/BucketSort.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fileprivate func >= <T: Comparable>(lhs: T?, rhs: T?) -> Bool {
6161
- Returns: A new array with sorted elements
6262
*/
6363

64-
public func bucketSort<T: Sortable>(_ elements: [T], distributor: Distributor, sorter: Sorter, buckets: [Bucket<T>]) -> [T] {
64+
public func bucketSort<T>(_ elements: [T], distributor: Distributor, sorter: Sorter, buckets: [Bucket<T>]) -> [T] {
6565
precondition(allPositiveNumbers(elements))
6666
precondition(enoughSpaceInBuckets(buckets, elements: elements))
6767

@@ -83,7 +83,7 @@ private func allPositiveNumbers<T: Sortable>(_ array: [T]) -> Bool {
8383
return array.filter { $0.toInt() >= 0 }.count > 0
8484
}
8585

86-
private func enoughSpaceInBuckets<T: Sortable>(_ buckets: [Bucket<T>], elements: [T]) -> Bool {
86+
private func enoughSpaceInBuckets<T>(_ buckets: [Bucket<T>], elements: [T]) -> Bool {
8787
let maximumValue = elements.max()?.toInt()
8888
let totalCapacity = buckets.count * (buckets.first?.capacity)!
8989

@@ -95,7 +95,7 @@ private func enoughSpaceInBuckets<T: Sortable>(_ buckets: [Bucket<T>], elements:
9595
//////////////////////////////////////
9696

9797
public protocol Distributor {
98-
func distribute<T: Sortable>(_ element: T, buckets: inout [Bucket<T>])
98+
func distribute<T>(_ element: T, buckets: inout [Bucket<T>])
9999
}
100100

101101
/*
@@ -117,7 +117,7 @@ public struct RangeDistributor: Distributor {
117117

118118
public init() {}
119119

120-
public func distribute<T: Sortable>(_ element: T, buckets: inout [Bucket<T>]) {
120+
public func distribute<T>(_ element: T, buckets: inout [Bucket<T>]) {
121121
let value = element.toInt()
122122
let bucketCapacity = buckets.first!.capacity
123123

Bucket Sort/Tests/Tests.xcodeproj/project.pbxproj

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@
8383
isa = PBXProject;
8484
attributes = {
8585
LastSwiftUpdateCheck = 0730;
86-
LastUpgradeCheck = 0720;
86+
LastUpgradeCheck = 0900;
8787
ORGANIZATIONNAME = "Swift Algorithm Club";
8888
TargetAttributes = {
8989
7B2BBC7F1C779D720067B71D = {
9090
CreatedOnToolsVersion = 7.2;
91-
LastSwiftMigration = 0810;
91+
LastSwiftMigration = 0900;
9292
};
9393
};
9494
};
@@ -141,13 +141,21 @@
141141
CLANG_CXX_LIBRARY = "libc++";
142142
CLANG_ENABLE_MODULES = YES;
143143
CLANG_ENABLE_OBJC_ARC = YES;
144+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
144145
CLANG_WARN_BOOL_CONVERSION = YES;
146+
CLANG_WARN_COMMA = YES;
145147
CLANG_WARN_CONSTANT_CONVERSION = YES;
146148
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
147149
CLANG_WARN_EMPTY_BODY = YES;
148150
CLANG_WARN_ENUM_CONVERSION = YES;
151+
CLANG_WARN_INFINITE_RECURSION = YES;
149152
CLANG_WARN_INT_CONVERSION = YES;
153+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
154+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
150155
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
156+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
157+
CLANG_WARN_STRICT_PROTOTYPES = YES;
158+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
151159
CLANG_WARN_UNREACHABLE_CODE = YES;
152160
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
153161
CODE_SIGN_IDENTITY = "-";
@@ -185,13 +193,21 @@
185193
CLANG_CXX_LIBRARY = "libc++";
186194
CLANG_ENABLE_MODULES = YES;
187195
CLANG_ENABLE_OBJC_ARC = YES;
196+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
188197
CLANG_WARN_BOOL_CONVERSION = YES;
198+
CLANG_WARN_COMMA = YES;
189199
CLANG_WARN_CONSTANT_CONVERSION = YES;
190200
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
191201
CLANG_WARN_EMPTY_BODY = YES;
192202
CLANG_WARN_ENUM_CONVERSION = YES;
203+
CLANG_WARN_INFINITE_RECURSION = YES;
193204
CLANG_WARN_INT_CONVERSION = YES;
205+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
206+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
194207
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
208+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
209+
CLANG_WARN_STRICT_PROTOTYPES = YES;
210+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
195211
CLANG_WARN_UNREACHABLE_CODE = YES;
196212
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
197213
CODE_SIGN_IDENTITY = "-";
@@ -210,6 +226,7 @@
210226
MACOSX_DEPLOYMENT_TARGET = 10.11;
211227
MTL_ENABLE_DEBUG_INFO = NO;
212228
SDKROOT = macosx;
229+
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
213230
};
214231
name = Release;
215232
};
@@ -223,7 +240,8 @@
223240
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
224241
PRODUCT_NAME = "$(TARGET_NAME)";
225242
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
226-
SWIFT_VERSION = 3.0;
243+
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
244+
SWIFT_VERSION = 4.0;
227245
};
228246
name = Debug;
229247
};
@@ -236,7 +254,8 @@
236254
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
237255
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
238256
PRODUCT_NAME = "$(TARGET_NAME)";
239-
SWIFT_VERSION = 3.0;
257+
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
258+
SWIFT_VERSION = 4.0;
240259
};
241260
name = Release;
242261
};

Bucket Sort/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0720"
3+
LastUpgradeVersion = "0900"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
2626
buildConfiguration = "Debug"
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
language = ""
2930
shouldUseLaunchSchemeArgsEnv = "YES">
3031
<Testables>
3132
<TestableReference
@@ -46,6 +47,7 @@
4647
buildConfiguration = "Debug"
4748
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
4849
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
50+
language = ""
4951
launchStyle = "0"
5052
useCustomWorkingDirectory = "NO"
5153
ignoresPersistentStateOnLaunch = "NO"

0 commit comments

Comments
 (0)