Skip to content

Commit afbb684

Browse files
committed
changes to count, distance and offsetBy
1 parent 3c0e501 commit afbb684

File tree

2 files changed

+62
-14
lines changed

2 files changed

+62
-14
lines changed

Diff for: Sources/Algorithms/Stride.swift

+9-8
Original file line numberDiff line numberDiff line change
@@ -91,19 +91,22 @@ extension Stride: Collection {
9191
base.index(i.base, offsetBy: distance * stride, limitedBy: limit.base)
9292
.map(Index.init)
9393
}
94-
94+
9595
public var count: Int {
96-
(base.count - 1) / stride + 1
96+
let limit = base.count - 1
97+
return limit / stride + (limit < 0 ? 0 : 1)
9798
}
9899

99100
public func distance(from start: Index, to end: Index) -> Int {
100-
base.distance(from: start.base, to: end.base) / stride
101+
let distance = base.distance(from: start.base, to: end.base)
102+
return distance / stride + (distance % stride > 0 ? 1 : 0)
101103
}
102104

103105
public func index(_ i: Index, offsetBy distance: Int) -> Index {
104-
Index(base.index(i.base, offsetBy: distance * stride))
106+
precondition(i.base < base.endIndex, "Advancing past end index")
107+
let limit = distance > 0 ? endIndex : startIndex
108+
return index(i, offsetBy: distance, limitedBy: limit) ?? limit
105109
}
106-
107110
}
108111

109112
extension Stride: BidirectionalCollection
@@ -137,8 +140,7 @@ extension Stride: Equatable
137140
where Base.Element: Equatable {
138141

139142
public static func == (lhs: Stride, rhs: Stride) -> Bool {
140-
guard lhs.count == rhs.count else { return false }
141-
return lhs.elementsEqual(rhs, by: ==)
143+
lhs.elementsEqual(rhs, by: ==)
142144
}
143145

144146
}
@@ -147,7 +149,6 @@ extension Stride: Hashable
147149
where Base.Element: Hashable {
148150

149151
public func hash(into hasher: inout Hasher) {
150-
hasher.combine(count)
151152
hasher.combine(stride)
152153
for element in self {
153154
hasher.combine(element)

Diff for: Tests/SwiftAlgorithmsTests/StrideTests.swift

+53-6
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ final class StridingTests: XCTestCase {
7676
}
7777

7878
func testCount() {
79+
let empty = [Int]().striding(by: 2)
80+
XCTAssertEqual(empty.count, 0)
7981
let a = (0...10)
8082
XCTAssertEqual(a.striding(by: 1).count, (0...10).count)
8183
XCTAssertEqual(a.striding(by: 2).count, [0, 2, 4, 6, 8, 10].count)
@@ -87,12 +89,50 @@ final class StridingTests: XCTestCase {
8789
}
8890

8991
func testDistance() {
90-
let a = (0...100).striding(by: 12)
91-
var i = a.startIndex
92-
a.formIndex(&i, offsetBy: 3)
93-
XCTAssertEqual(a.distance(from: a.startIndex, to: i), 3)
94-
XCTAssertEqual(a[i], 36)
95-
XCTAssertEqual(a.distance(from: a.startIndex, to: a.endIndex), a.count - 1)
92+
93+
do {
94+
let a = (0...100).striding(by: 11)
95+
XCTAssertEqual(a.distance(from: a.startIndex, to: a.endIndex), a.count)
96+
for (i, index) in a.indices.enumerated() {
97+
XCTAssertEqual(a.distance(from: a.startIndex, to: index), i)
98+
}
99+
100+
var i = a.startIndex
101+
a.formIndex(&i, offsetBy: 3)
102+
XCTAssertEqual(a.distance(from: a.startIndex, to: i), 3)
103+
XCTAssertEqual(a[i], 33)
104+
}
105+
106+
do {
107+
108+
let a = (0...100).striding(by: 10)
109+
XCTAssertEqual(a.distance(from: a.startIndex, to: a.endIndex), a.count)
110+
111+
for (i, index) in a.indices.enumerated() {
112+
XCTAssertEqual(a.distance(from: a.startIndex, to: index), i)
113+
}
114+
115+
var i = a.startIndex
116+
a.formIndex(&i, offsetBy: 3)
117+
XCTAssertEqual(a.distance(from: a.startIndex, to: i), 3)
118+
XCTAssertEqual(a[i], 30)
119+
}
120+
121+
do {
122+
123+
let a = (0...100).striding(by: 101)
124+
XCTAssertEqual(a.distance(from: a.startIndex, to: a.endIndex), a.count)
125+
126+
for (i, index) in a.indices.enumerated() {
127+
XCTAssertEqual(a.distance(from: a.startIndex, to: index), i)
128+
}
129+
130+
var i = a.startIndex
131+
a.formIndex(&i, offsetBy: 3)
132+
XCTAssertEqual(a.distance(from: a.startIndex, to: i), a.count)
133+
XCTAssertEqual(i, a.endIndex)
134+
// a[i] // == Fatal error: Index out of range
135+
}
96136
}
97137

98138
func testOffsetBy() {
@@ -102,4 +142,11 @@ final class StridingTests: XCTestCase {
102142
XCTAssertEqual(a[a.index(a.startIndex, offsetBy: i)], b[i])
103143
}
104144
}
145+
146+
func testOffsetByEndIndex() {
147+
let a = 1...5
148+
let b = a.striding(by: 3) // [1, 4]
149+
let i = b.index(b.startIndex, offsetBy: 2)
150+
XCTAssertEqual(i, b.endIndex)
151+
}
105152
}

0 commit comments

Comments
 (0)