Product.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // This source file is part of the Swift Algorithms open source project
  4. //
  5. // Copyright (c) 2020 Apple Inc. and the Swift project authors
  6. // Licensed under Apache License v2.0 with Runtime Library Exception
  7. //
  8. // See https://swift.org/LICENSE.txt for license information
  9. //
  10. //===----------------------------------------------------------------------===//
  11. /// A sequence that represents the product of two sequences' elements.
  12. public struct Product2Sequence<Base1: Sequence, Base2: Collection> {
  13. /// The outer sequence in the product.
  14. @usableFromInline
  15. internal let base1: Base1
  16. /// The inner sequence in the product.
  17. @usableFromInline
  18. internal let base2: Base2
  19. @inlinable
  20. internal init(_ base1: Base1, _ base2: Base2) {
  21. self.base1 = base1
  22. self.base2 = base2
  23. }
  24. }
  25. extension Product2Sequence: Sequence {
  26. public typealias Element = (Base1.Element, Base2.Element)
  27. /// The iterator for a `Product2Sequence` sequence.
  28. public struct Iterator: IteratorProtocol {
  29. @usableFromInline
  30. internal var i1: Base1.Iterator
  31. @usableFromInline
  32. internal var i2: Base2.Iterator
  33. @usableFromInline
  34. internal var element1: Base1.Element?
  35. @usableFromInline
  36. internal let base2: Base2
  37. @inlinable
  38. internal init(_ c: Product2Sequence) {
  39. self.base2 = c.base2
  40. self.i1 = c.base1.makeIterator()
  41. self.i2 = c.base2.makeIterator()
  42. self.element1 = nil
  43. }
  44. @inlinable
  45. public mutating func next() -> (Base1.Element,
  46. Base2.Element)? {
  47. // This is the initial state, where i1.next() has never
  48. // been called, or the final state, where i1.next() has
  49. // already returned nil.
  50. if element1 == nil {
  51. element1 = i1.next()
  52. // once Base1 is exhausted, return `nil` forever
  53. if element1 == nil { return nil }
  54. }
  55. // Get the next element from the second sequence, if not
  56. // at end.
  57. if let element2 = i2.next() {
  58. return (element1!, element2)
  59. }
  60. // We've reached the end of the second sequence, so:
  61. // 1) Get the next element of the first sequence, if exists
  62. // 2) Restart iteration of the second sequence
  63. // 3) Get the first element of the second sequence, if exists
  64. element1 = i1.next()
  65. guard let element1 = element1
  66. else { return nil }
  67. i2 = base2.makeIterator()
  68. if let element2 = i2.next() {
  69. return (element1, element2)
  70. } else {
  71. return nil
  72. }
  73. }
  74. }
  75. @inlinable
  76. public func makeIterator() -> Iterator {
  77. Iterator(self)
  78. }
  79. }
  80. extension Product2Sequence: Collection where Base1: Collection {
  81. /// The index type for a `Product2Sequence` collection.
  82. public struct Index: Comparable {
  83. @usableFromInline
  84. internal var i1: Base1.Index
  85. @usableFromInline
  86. internal var i2: Base2.Index
  87. @inlinable
  88. internal init(i1: Base1.Index, i2: Base2.Index) {
  89. self.i1 = i1
  90. self.i2 = i2
  91. }
  92. @inlinable
  93. public static func < (lhs: Index, rhs: Index) -> Bool {
  94. (lhs.i1, lhs.i2) < (rhs.i1, rhs.i2)
  95. }
  96. }
  97. @inlinable
  98. public var count: Int {
  99. base1.count * base2.count
  100. }
  101. @inlinable
  102. public var startIndex: Index {
  103. Index(
  104. i1: base2.isEmpty ? base1.endIndex : base1.startIndex,
  105. i2: base2.startIndex)
  106. }
  107. @inlinable
  108. public var endIndex: Index {
  109. // `base2.startIndex` simplifies index calculations.
  110. Index(i1: base1.endIndex, i2: base2.startIndex)
  111. }
  112. @inlinable
  113. public subscript(position: Index) -> (Base1.Element,
  114. Base2.Element) {
  115. (base1[position.i1], base2[position.i2])
  116. }
  117. /// Forms an index from a pair of base indices, normalizing
  118. /// `(i, base2.endIndex)` to `(base1.index(after: i), base2.startIndex)` if
  119. /// necessary.
  120. @inlinable
  121. internal func normalizeIndex(_ i1: Base1.Index, _ i2: Base2.Index) -> Index {
  122. i2 == base2.endIndex
  123. ? Index(i1: base1.index(after: i1), i2: base2.startIndex)
  124. : Index(i1: i1, i2: i2)
  125. }
  126. @inlinable
  127. public func index(after i: Index) -> Index {
  128. precondition(i.i1 != base1.endIndex, "Can't advance past endIndex")
  129. return normalizeIndex(i.i1, base2.index(after: i.i2))
  130. }
  131. @inlinable
  132. public func distance(from start: Index, to end: Index) -> Int {
  133. guard start.i1 <= end.i1
  134. else { return -distance(from: end, to: start) }
  135. guard start.i1 != end.i1
  136. else { return base2.distance(from: start.i2, to: end.i2) }
  137. // The number of full cycles through `base2` between `start` and `end`,
  138. // excluding the cycles that `start` and `end` are on.
  139. let fullBase2Cycles = base1[start.i1..<end.i1].count - 1
  140. if start.i2 <= end.i2 {
  141. // start.i2
  142. // v
  143. // start.i1 > [l l l|c c c c c c r r r]
  144. // [l l l c c c c c c r r r] >
  145. // ... > `fullBase2Cycles` times
  146. // [l l l c c c c c c r r r] >
  147. // end.i1 > [l l l c c c c c c|r r r]
  148. // ^
  149. // end.i2
  150. let left = base2[..<start.i2].count
  151. let center = base2[start.i2..<end.i2].count
  152. let right = base2[end.i2...].count
  153. return center + right
  154. + fullBase2Cycles * (left + center + right)
  155. + left + center
  156. } else {
  157. // start.i2
  158. // v
  159. // start.i1 > [l l l c c c c c c|r r r]
  160. // [l l l c c c c c c r r r] >
  161. // ... > `fullBase2Cycles` times
  162. // [l l l c c c c c c r r r] >
  163. // end.i1 > [l l l|c c c c c c r r r]
  164. // ^
  165. // end.i2
  166. let left = base2[..<end.i2].count
  167. let right = base2[start.i2...].count
  168. // We can avoid traversing `base2[end.i2..<start.i2]` if `start` and `end`
  169. // are on consecutive cycles.
  170. guard fullBase2Cycles > 0 else { return right + left }
  171. let center = base2[end.i2..<start.i2].count
  172. return right
  173. + fullBase2Cycles * (left + center + right)
  174. + left
  175. }
  176. }
  177. @inlinable
  178. public func index(_ i: Index, offsetBy distance: Int) -> Index {
  179. guard distance != 0 else { return i }
  180. return distance > 0
  181. ? offsetForward(i, by: distance)
  182. : offsetBackward(i, by: -distance)
  183. }
  184. @inlinable
  185. public func index(
  186. _ i: Index,
  187. offsetBy distance: Int,
  188. limitedBy limit: Index
  189. ) -> Index? {
  190. if distance >= 0 {
  191. return limit >= i
  192. ? offsetForward(i, by: distance, limitedBy: limit)
  193. : offsetForward(i, by: distance)
  194. } else {
  195. return limit <= i
  196. ? offsetBackward(i, by: -distance, limitedBy: limit)
  197. : offsetBackward(i, by: -distance)
  198. }
  199. }
  200. @inlinable
  201. internal func offsetForward(_ i: Index, by distance: Int) -> Index {
  202. guard let index = offsetForward(i, by: distance, limitedBy: endIndex)
  203. else { fatalError("Index is out of bounds") }
  204. return index
  205. }
  206. @inlinable
  207. internal func offsetBackward(_ i: Index, by distance: Int) -> Index {
  208. guard let index = offsetBackward(i, by: distance, limitedBy: startIndex)
  209. else { fatalError("Index is out of bounds") }
  210. return index
  211. }
  212. @inlinable
  213. internal func offsetForward(
  214. _ i: Index, by distance: Int, limitedBy limit: Index
  215. ) -> Index? {
  216. assert(distance >= 0)
  217. assert(limit >= i)
  218. if limit.i1 == i.i1 {
  219. // Delegate to `base2` if the offset is limited to `i.i1`.
  220. //
  221. // i.i2 limit.i2
  222. // v v
  223. // i.i1 > [x x x|x x x x x x|x x x]
  224. return base2.index(i.i2, offsetBy: distance, limitedBy: limit.i2)
  225. .map { i2 in Index(i1: i.i1, i2: i2) }
  226. }
  227. if let i2 = base2.index(i.i2, offsetBy: distance, limitedBy: base2.endIndex) {
  228. // `distance` does not overflow `base2[i.i2...]`.
  229. //
  230. // i.i2 i2
  231. // v v
  232. // i.i1 > [x x x|x x x x x x|x x x]
  233. // [ |> > > > > >| ] (`distance`)
  234. return normalizeIndex(i.i1, i2)
  235. }
  236. let suffixCount = base2[i.i2...].count
  237. let remaining = distance - suffixCount
  238. let nextI1 = base1.index(after: i.i1)
  239. if limit.i1 == nextI1 {
  240. // Delegate to `base2` if the offset is limited to `nextI1`.
  241. //
  242. // i.i2
  243. // v
  244. // i.i1 > [x x x|x x x x x x x x x]
  245. // nextI1 > [x x x x x x x x x|x x x]
  246. // ^
  247. // limit.i2
  248. return base2.index(base2.startIndex, offsetBy: remaining, limitedBy: limit.i2)
  249. .map { i2 in Index(i1: nextI1, i2: i2) }
  250. }
  251. if let i2 = base2.index(base2.startIndex, offsetBy: remaining, limitedBy: i.i2) {
  252. // `remaining` does not overflow `base2[..<i.i2]`.
  253. //
  254. // i.i2
  255. // v
  256. // i.i1 > [x x x x x x x x x|x x x]
  257. // [ |> > >] (`suffixCount`)
  258. // [> > >| ] (`remaining`)
  259. // nextI1 > [x x x|x x x x x x x x x]
  260. // ^
  261. // i2
  262. return Index(i1: nextI1, i2: i2)
  263. }
  264. let prefixCount = base2[..<i.i2].count
  265. let base2Count = prefixCount + suffixCount
  266. let base1Distance = remaining / base2Count
  267. guard let i1 = base1.index(nextI1, offsetBy: base1Distance, limitedBy: limit.i1)
  268. else { return nil }
  269. // The distance from `base2.startIndex` to the target.
  270. let base2Distance = remaining % base2Count
  271. let base2Limit = limit.i1 == i1 ? limit.i2 : base2.endIndex
  272. return base2.index(base2.startIndex, offsetBy: base2Distance, limitedBy: base2Limit)
  273. .map { i2 in Index(i1: i1, i2: i2) }
  274. }
  275. @inlinable
  276. internal func offsetBackward(
  277. _ i: Index, by distance: Int, limitedBy limit: Index
  278. ) -> Index? {
  279. assert(distance >= 0)
  280. assert(limit <= i)
  281. if limit.i1 == i.i1 {
  282. // Delegate to `base2` if the offset is limited to `i.i1`.
  283. //
  284. // limit.i2 i.i2
  285. // v v
  286. // i.i1 > [x x x|x x x x x x|x x x]
  287. return base2.index(i.i2, offsetBy: -distance, limitedBy: limit.i2)
  288. .map { i2 in Index(i1: i.i1, i2: i2) }
  289. }
  290. if let i2 = base2.index(i.i2, offsetBy: -distance, limitedBy: base2.startIndex) {
  291. // `distance` does not underflow `base2[..<i.i2]`.
  292. //
  293. // i2 i.i2
  294. // v v
  295. // i.i1 > [x x x|x x x x x x|x x x]
  296. // [ |< < < < < <| ] (`distance`)
  297. return Index(i1: i.i1, i2: i2)
  298. }
  299. let prefixCount = base2[..<i.i2].count
  300. let remaining = distance - prefixCount
  301. let previousI1 = base1.index(i.i1, offsetBy: -1)
  302. if limit.i1 == previousI1 {
  303. // Delegate to `base2` if the offset is limited to `previousI1`.
  304. //
  305. // limit.i2
  306. // v
  307. // previousI1 > [x x x|x x x x x x x x x]
  308. // i.i1 > [x x x x x x x x x|x x x]
  309. // ^
  310. // i.i2
  311. return base2.index(base2.endIndex, offsetBy: -remaining, limitedBy: limit.i2)
  312. .map { i2 in Index(i1: previousI1, i2: i2) }
  313. }
  314. if let i2 = base2.index(base2.endIndex, offsetBy: -remaining, limitedBy: i.i2) {
  315. // `remaining` does not underflow `base2[i.i2...]`.
  316. //
  317. // i2
  318. // v
  319. // previousI1 > [x x x x x x x x x|x x x]
  320. // [ |< < <] (`remaining`)
  321. // [< < <| ] (`prefixCount`)
  322. // i.i1 > [x x x|x x x x x x x x x]
  323. // ^
  324. // i.i2
  325. return Index(i1: previousI1, i2: i2)
  326. }
  327. let suffixCount = base2[i.i2...].count
  328. let base2Count = prefixCount + suffixCount
  329. let base1Distance = remaining / base2Count
  330. // The distance from `base2.endIndex` to the target.
  331. let base2Distance = remaining % base2Count
  332. if base2Distance == 0 {
  333. // We end up exactly between two cycles, so `base1Distance` would
  334. // overshoot the target by 1.
  335. //
  336. // base2.startIndex
  337. // v
  338. // i1 > |x x x x x x x x x x x x] >
  339. // ... > `base1Distance` times
  340. // previousI1 > [x x x x x x x x x x x x] >
  341. // i.i1 > [x x x|x x x x x x x x x]
  342. // ^
  343. // i.i2
  344. if let i1 = base1.index(previousI1, offsetBy: -(base1Distance - 1), limitedBy: limit.i1) {
  345. let index = Index(i1: i1, i2: base2.startIndex)
  346. return index < limit ? nil : index
  347. } else {
  348. return nil
  349. }
  350. }
  351. guard let i1 = base1.index(previousI1, offsetBy: -base1Distance, limitedBy: limit.i1)
  352. else { return nil }
  353. let base2Limit = limit.i1 == i1 ? limit.i2 : base2.startIndex
  354. return base2.index(base2.endIndex, offsetBy: -base2Distance, limitedBy: base2Limit)
  355. .map { i2 in Index(i1: i1, i2: i2) }
  356. }
  357. }
  358. extension Product2Sequence: BidirectionalCollection
  359. where Base1: BidirectionalCollection, Base2: BidirectionalCollection
  360. {
  361. @inlinable
  362. public func index(before i: Index) -> Index {
  363. precondition(i != startIndex,
  364. "Can't move before startIndex")
  365. if i.i2 == base2.startIndex {
  366. return Index(
  367. i1: base1.index(before: i.i1),
  368. i2: base2.index(before: base2.endIndex))
  369. } else {
  370. return Index(i1: i.i1, i2: base2.index(before: i.i2))
  371. }
  372. }
  373. }
  374. extension Product2Sequence: RandomAccessCollection
  375. where Base1: RandomAccessCollection, Base2: RandomAccessCollection {}
  376. extension Product2Sequence.Index: Hashable
  377. where Base1.Index: Hashable, Base2.Index: Hashable {}
  378. //===----------------------------------------------------------------------===//
  379. // product(_:_:)
  380. //===----------------------------------------------------------------------===//
  381. /// Creates a sequence of each pair of elements of two underlying sequences.
  382. ///
  383. /// Use this function to iterate over every pair of elements in two different
  384. /// collections. The returned sequence yields 2-element tuples, where the first
  385. /// element of the tuple is from the first collection and the second element is
  386. /// from the second collection.
  387. ///
  388. ///
  389. /// let numbers = 1...3
  390. /// let colors = ["cerise", "puce", "heliotrope"]
  391. /// for (number, color) in product(numbers, colors) {
  392. /// print("\(number): \(color)")
  393. /// }
  394. /// // 1: cerise
  395. /// // 1: puce
  396. /// // 1: heliotrope
  397. /// // 2: cerise
  398. /// // 2: puce
  399. /// // 2: heliotrope
  400. /// // 3: cerise
  401. /// // 3: puce
  402. /// // 3: heliotrope
  403. ///
  404. /// The order of tuples in the returned sequence is consistent. The first
  405. /// element of the first collection is paired with each element of the second
  406. /// collection, then the second element of the first collection is paired with
  407. /// each element of the second collection, and so on.
  408. ///
  409. /// - Parameters:
  410. /// - s1: The first sequence to iterate over.
  411. /// - s2: The second sequence to iterate over.
  412. ///
  413. /// - Complexity: O(1)
  414. @inlinable
  415. public func product<Base1: Sequence, Base2: Collection>(
  416. _ s1: Base1, _ s2: Base2
  417. ) -> Product2Sequence<Base1, Base2> {
  418. Product2Sequence(s1, s2)
  419. }