21
21
//
22
22
23
23
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
+ }
24
47
25
48
//////////////////////////////////////
26
49
// MARK: Main algorithm
27
50
//////////////////////////////////////
28
51
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
+ */
29
63
30
- public func bucketSort< T: Sortable > ( elements: [ T ] , distributor: Distributor , sorter: Sorter , buckets: [ Bucket < T > ] ) -> [ T ] {
31
- var bucketsCopy = buckets
32
- for elem in elements {
33
- distributor. distribute ( elem, buckets: & bucketsCopy)
34
- }
35
-
36
- 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
+ }
37
81
38
- for bucket in buckets {
39
- results += bucket . sort ( sorter )
40
- }
82
+ private func allPositiveNumbers < T : Sortable > ( _ array : [ T ] ) -> Bool {
83
+ return array . filter { $0 . toInt ( ) >= 0 } . count > 0
84
+ }
41
85
42
- 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
43
91
}
44
92
45
93
//////////////////////////////////////
46
94
// MARK: Distributor
47
95
//////////////////////////////////////
48
96
49
-
50
97
public protocol Distributor {
51
- func distribute< T: Sortable > ( element: T , inout buckets: [ Bucket < T > ] )
98
+ func distribute< T> ( _ element: T , buckets: inout [ Bucket < T > ] )
52
99
}
53
100
54
101
/*
@@ -67,24 +114,24 @@ public protocol Distributor {
67
114
* By following the formula: element / capacity = #ofBucket
68
115
*/
69
116
public struct RangeDistributor : Distributor {
70
-
71
- public init ( ) { }
72
-
73
- public func distribute< T: Sortable > ( element: T , inout buckets: [ Bucket < T > ] ) {
74
- let value = element. toInt ( )
75
- let bucketCapacity = buckets. first!. capacity
76
-
77
- let bucketIndex = value / bucketCapacity
78
- buckets [ bucketIndex] . add ( element)
79
- }
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
+ }
80
127
}
81
128
82
129
//////////////////////////////////////
83
130
// MARK: Sortable
84
131
//////////////////////////////////////
85
132
86
133
public protocol IntConvertible {
87
- func toInt( ) -> Int
134
+ func toInt( ) -> Int
88
135
}
89
136
90
137
public protocol Sortable : IntConvertible , Comparable {
@@ -95,50 +142,51 @@ public protocol Sortable: IntConvertible, Comparable {
95
142
//////////////////////////////////////
96
143
97
144
public protocol Sorter {
98
- func sort< T: Sortable > ( items: [ T ] ) -> [ T ]
145
+ func sort< T: Sortable > ( _ items: [ T ] ) -> [ T ]
99
146
}
100
147
101
148
public struct InsertionSorter : Sorter {
102
-
103
- public init ( ) { }
104
-
105
- public func sort< T: Sortable > ( items: [ T ] ) -> [ T ] {
106
- var results = items
107
- for i in 0 ..< results. count {
108
- var j = i
109
- while j > 0 && results [ j- i] > results [ j] {
110
-
111
- let auxiliar = results [ i]
112
- results [ i] = results [ j]
113
- results [ j] = auxiliar
114
-
115
- j -= 1
116
- }
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
117
166
}
118
- return results
119
- }
120
167
}
121
168
122
169
//////////////////////////////////////
123
170
// MARK: Bucket
124
171
//////////////////////////////////////
125
172
126
- public struct Bucket < T: Sortable > {
127
- var elements : [ T ]
128
- let capacity : Int
129
-
130
- public init ( capacity: Int ) {
131
- self . capacity = capacity
132
- elements = [ T] ( )
133
- }
134
-
135
- public mutating func add( item: T ) {
136
- if elements. count < capacity {
137
- elements. append ( item)
173
+ public struct Bucket < T: Sortable > {
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)
138
190
}
139
- }
140
-
141
- public func sort( algorithm: Sorter ) -> [ T ] {
142
- return algorithm. sort ( elements)
143
- }
144
191
}
192
+
0 commit comments