Skip to content

Commit c67dd34

Browse files
authored
Implement distance(from:to:) for Chain (#3)
* Add Chain.distance(from:to:) * Add test
1 parent 546c8bf commit c67dd34

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

Sources/Algorithms/Chain.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,20 @@ extension Chain: Collection where Base1: Collection, Base2: Collection {
209209
}
210210
}
211211

212-
// TODO: Add distance(from:to:)
212+
public func distance(from start: Index, to end: Index) -> Int {
213+
switch (start.position, end.position) {
214+
case let (.first(i), .first(j)):
215+
return base1.distance(from: i, to: j)
216+
case let (.second(i), .second(j)):
217+
return base2.distance(from: i, to: j)
218+
case let (.first(i), .second(j)):
219+
return base1.distance(from: i, to: base1.endIndex)
220+
+ base2.distance(from: base2.startIndex, to: j)
221+
case let (.second(i), .first(j)):
222+
return base2.distance(from: i, to: base2.startIndex)
223+
+ base1.distance(from: base1.endIndex, to: j)
224+
}
225+
}
213226
}
214227

215228
extension Chain: BidirectionalCollection

Tests/SwiftAlgorithmsTests/ChainTests.swift

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,17 @@
1010
//===----------------------------------------------------------------------===//
1111

1212
import XCTest
13-
import Algorithms
13+
@testable import Algorithms
1414

1515
final class ChainTests: XCTestCase {
16+
// intentionally does not depend on `Chain.index(_:offsetBy:)` in order to
17+
// avoid making assumptions about the code being tested
18+
func index<A, B>(atOffset offset: Int, in chain: Chain<A, B>) -> Chain<A, B>.Index {
19+
offset < chain.base1.count
20+
? .init(first: chain.base1.index(chain.base1.startIndex, offsetBy: offset))
21+
: .init(second: chain.base2.index(chain.base2.startIndex, offsetBy: offset - chain.base1.count))
22+
}
23+
1624
func testChainSequences() {
1725
let run = (1...).prefix(10).chained(with: 20...)
1826
XCTAssertEqualSequences(run.prefix(20), Array(1...10) + (20..<30))
@@ -35,5 +43,20 @@ final class ChainTests: XCTestCase {
3543
XCTAssertEqualSequences(s1.reversed().chained(with: s2), "JIHGFEDCBAklmnopqrstuv")
3644
}
3745

38-
// TODO: Add tests that check distance and index(offsetBy:)
46+
// TODO: Add tests that check index(offsetBy:)
47+
48+
func testChainDistanceFromTo() {
49+
let s1 = "abcde"
50+
let s2 = "VWXYZ"
51+
let chain = s1.chained(with: s2)
52+
53+
XCTAssertEqual(chain.count, s1.count + s2.count)
54+
55+
for (startOffset, endOffset) in product(0...chain.count, 0...chain.count) {
56+
let start = index(atOffset: startOffset, in: chain)
57+
let end = index(atOffset: endOffset, in: chain)
58+
let distance = endOffset - startOffset
59+
XCTAssertEqual(chain.distance(from: start, to: end), distance)
60+
}
61+
}
3962
}

0 commit comments

Comments
 (0)